Rustc has different representations for constants: one for MIR
([rustc_middle::mir::Const]), one for the type system
([rustc_middle::ty::ConstKind]). For simplicity hax maps those
two constructs to the same ConstantExpr type.
A representation of exists<T: Trait1 + Trait2>(value): we create a fresh type id and the
appropriate trait clauses. The contained value may refer to the fresh ty and the in-scope trait
clauses. This is used to represent types related to dyn Trait.
Represents the “shape” of a function pointer, i.e. the most general signature we can obtain
from it without breaking the higher-kinded variables. E.g. for<'a> fn(&'a u32) -> Adt<'a, u32> is considered to be an instantiation of the shape for<'a> fn(&'a A) -> Adt<'a, B> with
A=B=u32.
Reflects [ty::OutlivesPredicate] as a named struct
instead of a tuple struct. This is because the script converting
JSONSchema types to OCaml doesn’t support tuple structs, and this
is the only tuple struct in the whole AST.
A TraitProof describes the full data of a trait implementation. Because of generics, this may
need to combine several concrete trait implementation items. For example, ((1u8, 2u8), "hello").clone() combines the generic implementation of Clone for (A, B) with the
concrete implementations for u8 and &str, represented as a tree.
We create some extra DefIds to represent things that rustc doesn’t have a DefId for. This
makes the pipeline much easier to have “real” def_ids for them, as we can then solve traits
for them etc, and works well with monomorphization.
The source of a particular trait implementation. Most often this is either Concrete for a
concrete impl Trait for Type {} item, or LocalBound for a context-bound where T: Trait.
Erase free regions from the given value. Largely copied from tcx.erase_and_anonymize_regions, but also
erases bound regions that are bound outside value, so we can call this function inside a
Binder.
The signature of a method impl may be a subtype of the one expected from the trait decl, as in
the example below. For correctness, we must be able to map from the method generics declared in
the trait to the actual method generics. Because this would require type inference, we instead
simply return the declared signature. This will cause issues if it is possible to use such a
more-specific implementation with its more-specific type, but we have a few other issues with
lifetime-generic function pointers anyway so this is unlikely to cause problems.
Closures and inline consts have special type params that are used as inference variables. After
analysis, they can be computed from the rest of the args (modulo some erased regions). This
computes the identity args for this def_id with the inference ars properly inferred.
Given a clause clause in the context of some impl block impl_did, susbts correctly Self
from clause and (1) derive a Clause and (2) resolve a TraitProof.
Convert a type annotation into data we can use, by fetching the types that rustc inferred and
gathering the predicates that still need to be checked at borrowck time.
Reflects [ty::TraitRef]
Contains the def_id and arguments passed to the trait. The first type argument is the Self
type. The trait proofs are the required predicate for this trait; currently they are always
empty because we consider all trait predicates as implied.
self.in_trait is always None because a trait can’t be associated to another one.
The data of a user annotation: for each used projection we get the type of the corresponding
place, and we record outlives predicates that must hold. The first vec matches the input list
of projections, the second is free-form.