Skip to content

Commit b5dff2e

Browse files
committed
Add some examples for impls
1 parent 462b7c3 commit b5dff2e

File tree

1 file changed

+192
-21
lines changed

1 file changed

+192
-21
lines changed

src/traits/wf.md

Lines changed: 192 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ struct OnlyClone<T> where T: Clone {
7373
}
7474
// The only types appearing are type parameters: we have nothing to check,
7575
// the type definition is well-formed.
76+
```
7677

78+
```rust,ignore
7779
struct Foo<T> where T: Clone {
7880
foo: OnlyClone<T>,
7981
}
@@ -87,23 +89,28 @@ struct Foo<T> where T: Clone {
8789
// }
8890
// ```
8991
// which is provable.
92+
```
9093

91-
struct Bar<T> where OnlyClone<T>: Debug {
94+
```rust,ignore
95+
struct Bar<T> where <T as Iterator>::Item: Debug {
9296
bar: i32,
9397
}
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:
96100
// ```
97101
// 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)
100105
// }
101106
// }
102107
// ```
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+
//
105112
// 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.
107114
```
108115

109116
# Trait definitions
@@ -137,41 +144,47 @@ under the assumption that the different where clauses hold.
137144

138145
Some examples:
139146
```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 {
143148
...
144149
}
145150
// 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:
147152
// ```
148153
// 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)
151156
// }
152157
// }
153158
// ```
154-
// which is provable thanks to the `FromEnv(T: Clone)` assumption.
159+
// which is provable thanks to the `FromEnv(T: Iterator)` assumption.
160+
```
155161

162+
```rust,ignore
156163
trait Bar {
157-
type Assoc<T>: From<OnlyClone<T>>;
164+
type Assoc<T>: From<<T as Iterator>::Item>;
158165
}
159166
// 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+
// ```
161169
// forall<T> {
162-
// WellFormed(OnlyClone<T>)
170+
// WellFormed(<T as Iterator>::Item)
163171
// }
172+
// ```
164173
// which is not provable, hence the trait definition is considered illegal.
174+
```
165175

176+
```rust,ignore
166177
trait Baz {
167-
type Assoc<T>: From<OnlyClone<T>> where T: Clone;
178+
type Assoc<T>: From<<T as Iterator>::Item> where T: Iterator;
168179
}
169180
// The generated goal is now:
181+
// ```
170182
// forall<T> {
171-
// if (FromEnv(T: Clone)) {
172-
// WellFormed(OnlyClone<T>)
183+
// if (FromEnv(T: Iterator)) {
184+
// WellFormed(<T as Iterator>::Item)
173185
// }
174186
// }
187+
// ```
175188
// which is now provable.
176189
```
177190

@@ -267,3 +280,161 @@ we allow the use of implied bounds on associated types: if we have
267280
chapter indicates that we are able to deduce
268281
`FromEnv(<SomeType as Trait>::Assoc: Bounds_assoc)` without knowing what the
269282
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

Comments
 (0)