diff --git a/src/traits-associated-types.md b/src/traits-associated-types.md index 51972c41e..ec20985ff 100644 --- a/src/traits-associated-types.md +++ b/src/traits-associated-types.md @@ -53,12 +53,15 @@ we saw above would be lowered to a program clause like so: ```text forall { - Normalize( as IntoIterator>::Item -> T) + Normalize( as IntoIterator>::Item -> T) :- + Implemented(Option: IntoIterator) } ``` +where in this case, the one `Implemented` condition is always true. + (An aside: since we do not permit quantification over traits, this is -really more like a family of predicates, one for each associated +really more like a family of program clauses, one for each associated type.) We could apply that rule to normalize either of the examples that diff --git a/src/traits-lowering-rules.md b/src/traits-lowering-rules.md index 80884cbdd..06dc67401 100644 --- a/src/traits-lowering-rules.md +++ b/src/traits-lowering-rules.md @@ -132,8 +132,6 @@ to be **well-formed**: ```text // Rule WellFormed-TraitRef -// -// For each where clause WC: forall { WellFormed(Self: Trait) :- Implemented(Self: Trait) && WellFormed(WC) } @@ -198,38 +196,72 @@ in detail in the [section on associated types](./traits-associated-types.html), but reproduced here for reference: ```text - // Rule ProjectionEq-Normalize - // - // ProjectionEq can succeed by normalizing: - forall { - ProjectionEq(>::AssocType = U) :- - Normalize(>::AssocType -> U) - } +// Rule ProjectionEq-Normalize +// +// ProjectionEq can succeed by normalizing: +forall { + ProjectionEq(>::AssocType = U) :- + Normalize(>::AssocType -> U) +} +``` - // Rule ProjectionEq-Skolemize - // - // ProjectionEq can succeed by skolemizing, see "associated type" - // chapter for more: - forall { - ProjectionEq( - >::AssocType = - (Trait::AssocType) - ) :- - // But only if the trait is implemented, and the conditions from - // the associated type are met as well: - Implemented(Self: Trait) - && WC1 - } +```text +// Rule ProjectionEq-Skolemize +// +// ProjectionEq can succeed by skolemizing, see "associated type" +// chapter for more: +forall { + ProjectionEq( + >::AssocType = + (Trait::AssocType) + ) +} ``` The next rule covers implied bounds for the projection. In particular, -the `Bounds` declared on the associated type must be proven to hold to -show that the impl is well-formed, and hence we can rely on them +the `Bounds` declared on the associated type must have been proven to hold +to show that the impl is well-formed, and hence we can rely on them elsewhere. ```text -// XXX how exactly should we set this up? Have to be careful; -// presumably this has to be a kind of `FromEnv` setup. +// Rule Implied-Bound-From-AssocTy +// +// For each `Bound` in `Bounds`: +forall { + FromEnv(>::AssocType>: Bound) :- + FromEnv(Self: Trait) +} +``` + +Next, we define the requirements for an instantiation of our associated +type to be well-formed... + +```text +// Rule WellFormed-AssocTy +forall { + WellFormed((Trait::AssocType)) :- + WC1, Implemented(Self: Trait) +} +``` + +...along with the reverse implications, when we can assume that it is +well-formed. + +```text +// Rule Implied-WC-From-AssocTy +// +// For each where clause WC1: +forall { + FromEnv(WC1) :- FromEnv((Trait::AssocType)) +} +``` + +```text +// Rule Implied-Trait-From-AssocTy +forall { + FromEnv(Self: Trait) :- + FromEnv((Trait::AssocType)) +} ``` ### Lowering function and constant declarations @@ -269,27 +301,29 @@ In addition, we will lower all of the *impl items*. Given an impl that contains: ```rust,ignore -impl Trait for A0 -where WC +impl Trait for P0 +where WC_impl { - type AssocType where WC1 = T; + type AssocType = T; } ``` -We produce the following rule: +and our where clause `WC1` on the trait associated type from above, we +produce the following rule: ```text // Rule Normalize-From-Impl forall { forall { - Normalize(>::AssocType -> T) :- - WC && WC1 + Normalize(>::AssocType -> T) :- + Implemented(P0 as Trait) && WC1 } } ``` -Note that `WC` and `WC1` both encode where-clauses that the impl can -rely on. +Note that `WC_impl` and `WC1` both encode where-clauses that the impl can +rely on. (`WC_impl` is not used here, because it is implied by +`Implemented(P0 as Trait)`.) @@ -300,5 +334,3 @@ like to treat them exactly like normalization. This presumably involves adding a new kind of parameter (constant), and then having a `NormalizeValue` domain goal. This is *to be written* because the details are a bit up in the air. - -