Lyricdev
GitHub

LYR-SEM0197

the monomorphization does not terminate

error · spec 03-types

The set of generic instances a program asks for is not finite: each instance asks for a further one — a function that calls itself with a type built from its own (grow(W<T> { v = x })), a method whose result type is built from its own element type (Wrap<T>.deeper(): Wrap<Wrap<T>> called on its own result). Refused at a chain 128 deep, or past 20 000 instances.

Explanation

Lyric compiles generic code by monomorphization: one copy per set of type arguments. That ends only when the program asks for finitely many instances. A function that calls itself with a type built from its own — grow<T> calling grow<W<T>> — asks for a new instance at every level, whatever the values decide at run time; so does a method of a generic type that returns an instance built from its own element type and is called on what it returns.

The compiler follows each chain of instances, a body asking for the next, to a depth of 128, and a program to 20 000 instances; past either it stops with this error, the chain's first and last links in the message. Give the recursion a type that stays the same — grow(x, n - 1), or a box of one type — or write the method as a free generic function, which is instantiated per use rather than per instance.

Example

$ lyric build
error[LYR-SEM0197]: the instantiation does not end: a chain of 128 instances, each body asking for the next — grow<int> → grow<W<int>> → grow<W<W<int>>> → … 126 more … → grow<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W…>>>>>>>>>>>>>>>>>>>>. A function that calls itself with a type built from its own asks for a new instance at every level; give the recursion a type that stays the same