fn<T> wrap(x: T) { wrap(Box { val: x }); // ERROR: every call asks for a NEW, bigger} // instantiation of wrap -- this never endsTurf’s generics are monomorphized: calling a generic function or
constructing a generic struct with a new combination of concrete types
compiles a brand new specialized copy of it. That’s normally invisible –
List<int> and List<string> just work, each with its own compiled code.
But a generic that calls itself with a type that keeps growing (here,
wrap<T> always calls wrap<Box<T>>) would need an infinite number of
distinct compiled copies: wrap<int>, wrap<Box<int>>, wrap<Box<Box<int>>>,
forever. The compiler stops once a chain of instantiations requesting each
other is 64 deep rather than exhausting memory trying to finish, and prints
that chain (starting at the call in your own code) so you can see exactly
which call keeps growing the type. Independent calls never add up toward the
limit: calling one generic function on a hundred different types is a hundred
chains of length one. (A generic that keeps requesting more than one new
instantiation per level hits a separate, much larger cap on the total, and
says “too many generic instantiations” instead.)
This is almost never what you actually want. If you’re trying to write a
recursive data structure or algorithm, use a pointer/reference
(T*/&T) so the TYPE stays fixed across the recursion – only the VALUE
recurses, not the instantiation.
Run turf --explain E079 in a terminal to read this again.