Skip to main content

Module recurse

Module recurse 

Source
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 module that closes a type cycle.