Expand description
Giving a recursive type a size by boxing the field that closes the cycle.
A schema may refer to itself, directly or through other schemas. Lowered
as written, Node { child: Node } is a type that holds itself, and rustc
rejects it with E0072. The fix rustc itself suggests is a Box, so this
pass inserts one.
§What counts as holding a type
A field holds its type when the size of that type counts towards the size of
the struct. Vec<T>, HashMap<String, T> and Box<T> keep what they hold
on the heap, so they hold nothing and already break a cycle. Option<T>
stores its T inline, so Option<Node> inside Node is just as infinite as
Node. That last point is easy to get wrong: making a recursive property
optional does not fix anything.
§Which edge gets the box
Every edge on a cycle, and not one chosen edge. Boxing a single edge is
enough for rustc, but the choice would fall out of item order, so A and
B that refer to each other would get one box on whichever the walk met
first. Boxing both states the same fact about both types.
An alias holds its target and offers nothing to box, so a cycle made only of
aliases is Error::RecursiveAlias instead.
Functions§
- box_
recursive_ types - Box every field and variant of
modulethat closes a type cycle.