Module rustc_traits::chalk::lowering [−][src]
Expand description
Contains the logic to lower rustc types into Chalk types
In many cases there is a 1:1 relationship between a rustc type and a Chalk type.
For example, a SubstsRef maps almost directly to a Substitution. In some
other cases, such as Params, there is no Chalk type, so we have to handle
accordingly.
Ty lowering
Much of the Ty lowering is 1:1 with Chalk. (Or will be eventually). A
helpful table for what types lower to what can be found in the
Chalk book.
The most notable difference lies with Params. To convert from rustc to
Chalk, we eagerly and deeply convert Params to placeholders (in goals) or
bound variables (for clause generation through functions in db).
Region lowering
Regions are handled in rustc and Chalk is quite differently. In rustc, there
is a difference between “early bound” and “late bound” regions, where only
the late bound regions have a DebruijnIndex. Moreover, in Chalk all
regions (Lifetimes) have an associated index. In rustc, only BrAnons have
an index, whereas BrNamed don’t. In order to lower regions to Chalk, we
convert all regions into BrAnon late-bound regions.
Const lowering
Chalk doesn’t handle consts currently, so consts are currently lowered to an empty tuple.
Bound variable collection
Another difference between rustc and Chalk lies in the handling of binders.
Chalk requires that we store the bound parameter kinds, whereas rustc does
not. To lower anything wrapped in a Binder, we first deeply find any bound
variables from the current Binder.
Structs
This is used to replace BoundRegionKind::BrNamed with BoundRegionKind::BrAnon.
Note: we assume that we will always have room for more bound vars. (i.e. we
won’t ever hit the u32 limit in BrAnons).
Used to substitute Params with placeholders. We do this since Chalk
have a notion of Params.
Used to collect Placeholders.
Used to substitute specific Regionss with placeholders.
Traits
Essentially an Into with a &RustInterner parameter
Functions
To collect bound vars, we have to do two passes. In the first pass, we
collect all BoundRegionKinds and ty::Bounds. In the second pass, we then
replace BrNamed into BrAnon. The two separate passes are important,
since we can only replace BrNamed with BrAnons with indices after all
“real” BrAnons.