my best guess is that you can't do recursive enums without explicit boxing [edit: or other forms of indirection,
like &T]¹. so you can't do this:
enum List<T> {
Nil,
Cons(T, List<T>)
}
instead, you have to box/reference-ify the recursive occurrence:
enum List<T> {
Nil,
Cons(T, Box<List<T>>)
}
so in certain circumstances it doesn't let you "coproduct" two types together, you might need to modify one a bit, which makes it a technically-not-exactly-a-coproduct (i think). a bit of a stretch but it sort of makes sense next to a by-reference-only ML langs where you can (co)product anything as you please
You don't have to box, but you do need some sort of type to make things sized. This is usually a pointer of some kind, but any kind of pointer works. Take references, for example:
enum List<'a, T> {
Nil,
Cons(T, &'a List<'a, T>)
}
fn main() {
let list = List::Cons("hello", &List::Nil);
}
Box is usually chosen because it's a good default choice.
(btw, it's the same for recursive products)
---
1 - https://users.rust-lang.org/t/recursive-enum-types/2938/2