Skip to content

Commit d8d13a8

Browse files
committed
Update lowering rules for GATs
1 parent 37f5f85 commit d8d13a8

File tree

2 files changed

+68
-36
lines changed

2 files changed

+68
-36
lines changed

src/traits-associated-types.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,15 @@ we saw above would be lowered to a program clause like so:
5353

5454
```text
5555
forall<T> {
56-
Normalize(<Option<T> as IntoIterator>::Item -> T)
56+
Normalize(<Option<T> as IntoIterator>::Item -> T) :-
57+
Implemented(Option<T>: IntoIterator)
5758
}
5859
```
5960

61+
where in this case, the one `Implemented` condition is always true.
62+
6063
(An aside: since we do not permit quantification over traits, this is
61-
really more like a family of predicates, one for each associated
64+
really more like a family of program clauses, one for each associated
6265
type.)
6366

6467
We could apply that rule to normalize either of the examples that

src/traits-lowering-rules.md

+63-34
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ to be **well-formed**:
132132

133133
```text
134134
// Rule WellFormed-TraitRef
135-
//
136-
// For each where clause WC:
137135
forall<Self, P1..Pn> {
138136
WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)
139137
}
@@ -198,38 +196,70 @@ in detail in the [section on associated types](./traits-associated-types.html),
198196
but reproduced here for reference:
199197

200198
```text
201-
// Rule ProjectionEq-Normalize
202-
//
203-
// ProjectionEq can succeed by normalizing:
204-
forall<Self, P1..Pn, Pn+1..Pm, U> {
205-
ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U) :-
206-
Normalize(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> -> U)
207-
}
199+
// Rule ProjectionEq-Normalize
200+
//
201+
// ProjectionEq can succeed by normalizing:
202+
forall<Self, P1..Pn, Pn+1..Pm, U> {
203+
ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U) :-
204+
Normalize(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> -> U)
205+
}
206+
```
208207

209-
// Rule ProjectionEq-Skolemize
210-
//
211-
// ProjectionEq can succeed by skolemizing, see "associated type"
212-
// chapter for more:
213-
forall<Self, P1..Pn, Pn+1..Pm> {
214-
ProjectionEq(
215-
<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> =
216-
(Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>
217-
) :-
218-
// But only if the trait is implemented, and the conditions from
219-
// the associated type are met as well:
220-
Implemented(Self: Trait<P1..Pn>)
221-
&& WC1
222-
}
208+
```text
209+
// Rule ProjectionEq-Skolemize
210+
//
211+
// ProjectionEq can succeed by skolemizing, see "associated type"
212+
// chapter for more:
213+
forall<Self, P1..Pn, Pn+1..Pm> {
214+
ProjectionEq(
215+
<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> =
216+
(Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>
217+
)
218+
}
223219
```
224220

225221
The next rule covers implied bounds for the projection. In particular,
226-
the `Bounds` declared on the associated type must be proven to hold to
227-
show that the impl is well-formed, and hence we can rely on them
222+
the `Bounds` declared on the associated type must have been proven to hold
223+
to show that the impl is well-formed, and hence we can rely on them
228224
elsewhere.
229225

230226
```text
231-
// XXX how exactly should we set this up? Have to be careful;
232-
// presumably this has to be a kind of `FromEnv` setup.
227+
// Rule Implied-Bound-From-AssocTy
228+
forall<Self, P1..Pn, Pn+1..Pm> {
229+
FromEnv(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm>>: Bounds) :-
230+
FromEnv(Self: Trait<P1..Pn>)
231+
}
232+
```
233+
234+
Next, we define the requirements for an instantiation of our associated
235+
type to be well-formed...
236+
237+
```text
238+
// Rule WellFormed-AssocTy
239+
forall<Self, P1..Pn, Pn+1..Pm> {
240+
WellFormed((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>) :-
241+
WC1, Implemented(Self: Trait<P1..Pn>)
242+
}
243+
```
244+
245+
...along with the reverse implications, when we can assume that it is
246+
well-formed.
247+
248+
```text
249+
// Rule Implied-WC-From-AssocTy
250+
//
251+
// For each where clause WC1:
252+
forall<Self, P1..Pn, Pn+1..Pm> {
253+
FromEnv(WC1) :- FromEnv((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
254+
}
255+
```
256+
257+
```text
258+
// Rule Implied-Trait-From-AssocTy
259+
forall<Self, P1..Pn, Pn+1..Pm> {
260+
FromEnv(Self: Trait<P1..Pn>) :-
261+
FromEnv((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
262+
}
233263
```
234264

235265
### Lowering function and constant declarations
@@ -270,25 +300,26 @@ Given an impl that contains:
270300

271301
```rust,ignore
272302
impl<P0..Pn> Trait<A1..An> for A0
273-
where WC
303+
where WC_impl
274304
{
275-
type AssocType<Pn+1..Pm> where WC1 = T;
305+
type AssocType<Pn+1..Pm> = T;
276306
}
277307
```
278308

279-
We produce the following rule:
309+
and our where clause `WC1` on the trait associated type from above, we
310+
produce the following rule:
280311

281312
```text
282313
// Rule Normalize-From-Impl
283314
forall<P0..Pm> {
284315
forall<Pn+1..Pm> {
285316
Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T) :-
286-
WC && WC1
317+
WC_impl && WC1
287318
}
288319
}
289320
```
290321

291-
Note that `WC` and `WC1` both encode where-clauses that the impl can
322+
Note that `WC_impl` and `WC1` both encode where-clauses that the impl can
292323
rely on.
293324

294325
<a name="constant-vals"></a>
@@ -300,5 +331,3 @@ like to treat them exactly like normalization. This presumably
300331
involves adding a new kind of parameter (constant), and then having a
301332
`NormalizeValue` domain goal. This is *to be written* because the
302333
details are a bit up in the air.
303-
304-

0 commit comments

Comments
 (0)