Lowers the AST to the HIR.
Since the AST and HIR are fairly similar, this is mostly a simple procedure, much like a fold. Where lowering involves a bit more work things get more interesting and there are some invariants you should know about. These mostly concern spans and IDs.
Spans are assigned to AST nodes during parsing and then are modified during expansion to indicate the origin of a node and the process it went through being expanded. IDs are assigned to AST nodes just before lowering.
For the simpler lowering steps, IDs and spans should be preserved. Unlike
expansion we do not preserve the process of lowering in the spans, so spans
should not be modified here. When creating a new node (as opposed to
“folding” an existing one), create a new ID using
You must ensure that IDs are unique. That means that you should only use the ID from an AST node in a single HIR node (you can assume that AST node-IDs are unique). Every new node must have a unique ID. Avoid cloning HIR nodes. If you do, you must then set the new node’s ID to a fresh one.
Spans are used for error messages and for tools to map semantics back to source code. It is therefore not as important with spans as IDs to be strict about use (you can’t break the compiler by screwing up a span). Obviously, a HIR node can only have a single span. But multiple nodes can have the same span and spans don’t need to be kept in order, etc. Where code is preserved by lowering, it should have the same span as in the AST. Where HIR nodes are new it is probably best to give a span for the whole AST node being lowered. All nodes should have real spans; don’t use dummy spans. Tools are likely to get confused if the spans from leaf AST nodes occur in multiple places in the HIR, especially for multiple identifiers.
What to do when we encounter an anonymous lifetime
reference. Anonymous lifetime references come in two flavors. You
have implicit, or fully elided, references to lifetimes, like the
Ref<T>, and you have
'_ lifetimes, like
Ref<'_, T>. These often behave the same, but not always:
impl Trait in code, which determines whether it is allowed in an HIR subtree,
and if so, what meaning it has.
Position in which
impl Trait is disallowed.