@@ -73,7 +73,9 @@ struct OnlyClone<T> where T: Clone {
73
73
}
74
74
// The only types appearing are type parameters: we have nothing to check,
75
75
// the type definition is well-formed.
76
+ ```
76
77
78
+ ``` rust,ignore
77
79
struct Foo<T> where T: Clone {
78
80
foo: OnlyClone<T>,
79
81
}
@@ -87,23 +89,28 @@ struct Foo<T> where T: Clone {
87
89
// }
88
90
// ```
89
91
// which is provable.
92
+ ```
90
93
91
- struct Bar<T> where OnlyClone<T>: Debug {
94
+ ``` rust,ignore
95
+ struct Bar<T> where <T as Iterator>::Item: Debug {
92
96
bar: i32,
93
97
}
94
- // The only non-parameter type which appears in this definition is
95
- // `OnlyClone<T> `. The generated goal is the following:
98
+ // The only non-parameter types which appear in this definition are
99
+ // `<T as Iterator>::Item` and `i32 `. The generated goal is the following:
96
100
// ```
97
101
// forall<T> {
98
- // if (FromEnv(OnlyClone<T>: Debug)) {
99
- // WellFormed(OnlyClone<T>)
102
+ // if (FromEnv(<T as Iterator>::Item: Debug)) {
103
+ // WellFormed(<T as Iterator>::Item) &&
104
+ // WellFormed(i32)
100
105
// }
101
106
// }
102
107
// ```
103
- // which is not provable since `WellFormed(OnlyClone<T>)` requires proving
104
- // `Implemented(T: Clone)`, and we are unable to prove that for an unknown `T`.
108
+ // which is not provable since `WellFormed(<T as Iterator>::Item)` requires
109
+ // proving `Implemented(T: Iterator)`, and we are unable to prove that for an
110
+ // unknown `T`.
111
+ //
105
112
// Hence, this type definition is considered illegal. An additional
106
- // `where T: Clone ` would make it legal.
113
+ // `where T: Iterator ` would make it legal.
107
114
```
108
115
109
116
# Trait definitions
@@ -137,41 +144,47 @@ under the assumption that the different where clauses hold.
137
144
138
145
Some examples:
139
146
``` rust,ignore
140
- struct OnlyClone<T: Clone> { ... }
141
-
142
- trait Foo<T> where T: Clone, OnlyClone<T>: Debug {
147
+ trait Foo<T> where T: Iterator, <T as Iterator>::Item: Debug {
143
148
...
144
149
}
145
150
// The only non-parameter type which appears in this definition is
146
- // `OnlyClone<T> `. The generated goal is the following:
151
+ // `<T as Iterator>::Item `. The generated goal is the following:
147
152
// ```
148
153
// forall<T> {
149
- // if (FromEnv(T: Clone ), FromEnv(OnlyClone<T> : Debug)) {
150
- // WellFormed(OnlyClone<T> )
154
+ // if (FromEnv(T: Iterator ), FromEnv(<T as Iterator>::Item : Debug)) {
155
+ // WellFormed(<T as Iterator>::Item )
151
156
// }
152
157
// }
153
158
// ```
154
- // which is provable thanks to the `FromEnv(T: Clone)` assumption.
159
+ // which is provable thanks to the `FromEnv(T: Iterator)` assumption.
160
+ ```
155
161
162
+ ``` rust,ignore
156
163
trait Bar {
157
- type Assoc<T>: From<OnlyClone<T> >;
164
+ type Assoc<T>: From<<T as Iterator>::Item >;
158
165
}
159
166
// The only non-parameter type which appears in this definition is
160
- // `OnlyClone<T>`. The generated goal is the following:
167
+ // `<T as Iterator>::Item`. The generated goal is the following:
168
+ // ```
161
169
// forall<T> {
162
- // WellFormed(OnlyClone<T> )
170
+ // WellFormed(<T as Iterator>::Item )
163
171
// }
172
+ // ```
164
173
// which is not provable, hence the trait definition is considered illegal.
174
+ ```
165
175
176
+ ``` rust,ignore
166
177
trait Baz {
167
- type Assoc<T>: From<OnlyClone<T> > where T: Clone ;
178
+ type Assoc<T>: From<<T as Iterator>::Item > where T: Iterator ;
168
179
}
169
180
// The generated goal is now:
181
+ // ```
170
182
// forall<T> {
171
- // if (FromEnv(T: Clone )) {
172
- // WellFormed(OnlyClone<T> )
183
+ // if (FromEnv(T: Iterator )) {
184
+ // WellFormed(<T as Iterator>::Item )
173
185
// }
174
186
// }
187
+ // ```
175
188
// which is now provable.
176
189
```
177
190
@@ -267,3 +280,161 @@ we allow the use of implied bounds on associated types: if we have
267
280
chapter indicates that we are able to deduce
268
281
` FromEnv(<SomeType as Trait>::Assoc: Bounds_assoc) ` without knowing what the
269
282
precise value of ` <SomeType as Trait>::Assoc ` is.
283
+
284
+ Some examples for the generated goal:
285
+ ``` rust,ignore
286
+ trait Copy { }
287
+ // `WellFormed(Self: Copy) :- Implemented(Self: Copy).`
288
+
289
+ trait Partial where Self: Copy { }
290
+ // ```
291
+ // WellFormed(Self: Partial) :-
292
+ // Implemented(Self: Partial) &&
293
+ // WellFormed(Self: Copy).
294
+ // ```
295
+
296
+ trait Complete where Self: Partial { }
297
+ // ```
298
+ // WellFormed(Self: Complete) :-
299
+ // Implemented(Self: Complete) &&
300
+ // WellFormed(Self: Partial).
301
+ // ```
302
+
303
+ impl<T> Partial for T where T: Complete { }
304
+ // The generated goal is:
305
+ // ```
306
+ // forall<T> {
307
+ // if (FromEnv(T: Complete)) {
308
+ // WellFormed(T: Partial)
309
+ // }
310
+ // }
311
+ // ```
312
+ // Then proving `WellFormed(T: Partial)` amounts to proving
313
+ // `Implemented(T: Partial)` and `Implemented(T: Copy)`.
314
+ // Both those facts can be deduced from the `FromEnv(T: Complete)` in our
315
+ // environment: this impl is legal.
316
+
317
+ impl<T> Complete for T { }
318
+ // The generated goal is:
319
+ // ```
320
+ // forall<T> {
321
+ // WellFormed(T: Complete)
322
+ // }
323
+ // ```
324
+ // Then proving `WellFormed(T: Complete)` amounts to proving
325
+ // `Implemented(T: Complete)`, `Implemented(T: Partial)` and
326
+ // `Implemented(T: Copy)`.
327
+ //
328
+ // `Implemented(T: Complete)` can be proved thanks to the
329
+ // `impl<T> Complete for T` blanket impl.
330
+ //
331
+ // `Implemented(T: Partial)` can be proved thanks to the
332
+ // `impl<T> Partial for T where T: Complete` impl and because we know
333
+ // `T: Complete` holds.
334
+
335
+ // However, `Implemented(T: Copy)` cannot be proved: the impl is illegal.
336
+ // An additional `where T: Copy` bound would be sufficient to make that impl
337
+ // legal.
338
+ ```
339
+
340
+ ``` rust,ignore
341
+ trait Bar { }
342
+
343
+ impl<T> Bar for T where <T as Iterator>::Item: Bar { }
344
+ // We have a non-parameter type appearing in the where clauses:
345
+ // `<T as Iterator>::Item`. The generated goal is:
346
+ // ```
347
+ // forall<T> {
348
+ // if (FromEnv(<T as Iterator>::Item: Bar)) {
349
+ // WellFormed(T: Bar) &&
350
+ // WellFormed(<T as Iterator>::Item: Bar)
351
+ // }
352
+ // }
353
+ // ```
354
+ // And `WellFormed(<T as Iterator>::Item: Bar)` is not provable: we'd need
355
+ // an additional `where T: Iterator` for example.
356
+ ```
357
+
358
+ ``` rust,ignore
359
+ trait Foo { }
360
+
361
+ trait Bar {
362
+ type Item: Foo;
363
+ }
364
+
365
+ struct Stuff<T> { }
366
+
367
+ impl<T> Bar for Stuff<T> where T: Foo {
368
+ type Item = T;
369
+ }
370
+ // The generated goal is:
371
+ // ```
372
+ // forall<T> {
373
+ // if (FromEnv(T: Foo)) {
374
+ // WellFormed(T: Foo).
375
+ // }
376
+ // }
377
+ // ```
378
+ // which is provable.
379
+ ```
380
+
381
+ ``` rust,ignore
382
+ trait Debug { ... }
383
+ // `WellFormed(Self: Debug) :- Implemented(Self: Debug).`
384
+
385
+ struct Box<T> { ... }
386
+ impl<T> Debug for Box<T> where T: Debug { ... }
387
+
388
+ trait PointerFamily {
389
+ type Pointer<T>: Debug where T: Debug;
390
+ }
391
+ // `WellFormed(Self: PointerFamily) :- Implemented(Self: PointerFamily).`
392
+
393
+ struct BoxFamily;
394
+
395
+ impl PointerFamily for CowFamily {
396
+ type Pointer<T> = Box<T> where T: Debug;
397
+ }
398
+ // The generated goal is:
399
+ // ```
400
+ // forall<T> {
401
+ // WellFormed(CowFamily: PointerFamily) &&
402
+ //
403
+ // if (FromEnv(T: Debug)) {
404
+ // WellFormed(Box<T>: Debug) &&
405
+ // WellFormed(Box<T>)
406
+ // }
407
+ // }
408
+ // ```
409
+ // `WellFormed(CowFamily: PointerFamily)` amounts to proving
410
+ // `Implemented(CowFamily: PointerFamily)`, which is ok thanks to our impl.
411
+ //
412
+ // `WellFormed(Box<T>)` is always true (there are no where clauses on the
413
+ // `Box` type definition).
414
+ //
415
+ // Moreover, we have an `impl<T: Debug> Debug for Box<T>`, hence
416
+ // we can prove `WellFormed(Box<T>: Debug)` and the impl is indeed legal.
417
+ ```
418
+
419
+ ``` rust,ignore
420
+ trait Foo {
421
+ type Assoc<T>;
422
+ }
423
+
424
+ struct OnlyClone<T: Clone> { ... }
425
+
426
+ impl Foo for i32 {
427
+ type Assoc<T> = OnlyClone<T>;
428
+ }
429
+ // The generated goal is:
430
+ // ```
431
+ // forall<T> {
432
+ // WellFormed(i32: Foo) &&
433
+ // WellFormed(OnlyClone<T>)
434
+ // }
435
+ // ```
436
+ // however `WellFormed(OnlyClone<T>)` is not provable because it requires
437
+ // `Implemented(T: Clone)`. It would be tempting to just add a `where T: Clone`
438
+ // bound inside the `impl Foo for i32` block, however we saw that it was
439
+ // illegal to add where clauses that didn't come from the trait definition.
440
+ ```
0 commit comments