Chalk: Lowering Rules and Implied Bounds
To cover the basic trait lowering, we define a few domain goals:

DomainGoal := Implemented(TraitRef)
           |  Declared(TraitRef)
           |  FromEnv(TraitRef)
           |  ... // other kinds of domain goals exist, but they are not relevant here

// A "TraitRef" is a trait plus its input parameters        
TraitRef := P0: Trait<P1..Pn>

// A parameter "P" is either a type or a lifetime
P := <type> | <lifetime>

You might be surprised to see all of the options. The reasons we have them is to accommodate implied bounds. Let’s walk through the goals one by one:

  • Implemented(TraitRef) — this means that the trait-ref is considered fully implemented. This implies both that there is an impl for the trait-reference but also that all where clauses declared on the trait are satisfied.
  • Declared(TraitRef) — this means that an impl of TraitRef exists
  • FromEnv(TraitRef) — this means that TraitRef appears in the environment (e.g., when checking a function with where-clause).

// from the trait:
trait Trait<V..> where WC { }
// forall<Self, V..> { Implemented(Self: Trait<V..>) :- FromEnv(Self: Trait<V..>) }
// forall<Self, V..> { FromEnv(WC) :- FromEnv(Self: Trait<V..>) }
// forall<Self, V..> {
//   Implemented(Self: Trait<V..>) :- 
//     Declared(Self: Trait<V..>), 
//     Implemented(WC)
// }

// User gives:
impl<V..> Trait<P1..> for P0 { .. }
// forall<V..> { Declared(P0: Trait<P1..>) }