Skip to content

Commit c35b728

Browse files
committed
rarw
1 parent 62d1539 commit c35b728

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

src/items/generics.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
310310
}
311311
```
312312

313+
r[items.generics.instantiation]
314+
When using an item its generic parameters have to get instantiated. This replaces all occurances of the parameter with either the explicitly provided argument or a new unconstrained inference variable.
315+
316+
Instantiating the generic parameters of an item generally requires proving its where clauses.
317+
318+
313319
[array repeat expression]: ../expressions/array-expr.md
314320
[arrays]: ../types/array.md
315321
[slices]: ../types/slice.md

src/trait-bounds.md

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,11 @@ The bounds of an item must be satisfied when using that item.
5656

5757
r[bound.satisfaction.impl]
5858

59-
- a trait bound can be satisfied by using an implementation of that trait
60-
- an impl is applicable if, after instantiating its generic parameters with inference variables
61-
- TODO: how to talk about "instantiate with infer vars"...
62-
- the self type and trait arguments are equal to the trait bound,
63-
- the where-bounds of the impl can be recursively satisfied
59+
A trait bound can be satisfied by using an implementation of that trait. An implementation is applicable if,
60+
after instantiating its generic parameters with new inference variables, the self type and trait arguments are
61+
equal to the trait bound and the where-bounds of the impl can be recursively satisfied.
6462

65-
[bound.satisfaction.impl.builtin]
63+
r[bound.satisfaction.impl.builtin]
6664

6765
There exist impls which are automatically generated by the compiler.
6866

@@ -71,21 +69,51 @@ There exist impls which are automatically generated by the compiler.
7169

7270
- alternative: mention this in item-kind impl
7371

74-
[bound.satisfaction.impl.builtin.trait-object]
72+
r[bound.satisfaction.impl.builtin.trait-object]
7573

7674
Trait objects implement their trait if TODO: lookup conditions, something something project bounds make sense
7775

78-
[bound.satisfaction.bounds]
76+
r[bound.satisfaction.bounds]
7977

8078
While inside of a generic item, trait bounds can be satisfied by using the where-bounds of the current item as the item is able to assume that its bounds are satisfied. For this, higher-ranked where-bounds can be instantiated with inference variables. The where-bound is then equated with the trait bound that needs to be satisfied.
8179

82-
[bound.satisfaction.alias-bounds]
80+
r[bound.satisfaction.alias-bounds]
8381

84-
- if an alias cannot be normalized in the current environment, trait bounds using this alias as a self type can be proven by using its item bounds
85-
- TODO: alias bounds from nested self-types github.com/rust-lang/rust/pull/120752
82+
If an alias type is rigid in the current environment, trait bounds using this alias as a self type can be satisfied by using its item bounds.
83+
84+
```rust
85+
trait Trait {
86+
type Assoc: Clone;
87+
}
88+
89+
fn foo<T: Trait>(x: &T::Assoc) -> T::Assoc {
90+
// The where-bound `T::Assoc: Clone` is satisfied using the `Clone` item-bound.
91+
x.clone()
92+
}
93+
```
94+
95+
r[bound.satisfaction.alias-bounds.nested]
96+
97+
We also consider the item bounds of the self type of aliases to satisfy trait bounds.
98+
99+
```rust
100+
trait Trait {
101+
type Assoc: Iterator
102+
where
103+
<Self::Assoc as Iterator>::Item: Clone;
104+
// equivalent to
105+
// type Assoc: Iterator<Item: Clone>;
106+
}
107+
108+
fn item_is_clone<T: Trait>(iter: T::Assoc) {
109+
for item in iter {
110+
let _ = item.clone();
111+
}
112+
}
113+
```
86114

87115

88-
[bound.satisfaction.candidate-preference]
116+
r[bound.satisfaction.candidate-preference]
89117

90118
> This is purely descriptive. Candidate preference behavior may change in future releases and must not be relied upon for correctness or soundness.
91119
@@ -99,10 +127,6 @@ If there are multiple ways to satisfy a trait bound, some groups of candidate ar
99127

100128
> note: this candidate preference can result in incorrect errors and type mismatches, e.g. ...
101129
102-
[bound.satisfaction.cycles]
103-
104-
In case satisfying a bound requires recursively satisfying the same bound, we've encountered a *cycle*. TODO: terminology is iffy here .... can just drop this again
105-
106130
r[bound.trait-object]
107131
Trait and lifetime bounds are also used to name [trait objects].
108132

src/types.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,14 @@ let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil))));
153153

154154
r[types.equality]
155155

156-
Equality and subtyping of types is generally structural. If the outermost type constructors are the same,
157-
corresponding generic arguments are compared. The only exceptions from this rule are higher ranked types and alias types.
156+
Equality and subtyping of types is generally structural; if the outermost type constructors are the same,
157+
their corresponding generic arguments are pairwise compared. We say types with this equality behavior are *rigid*. The only exceptions from this rule are higher ranked types and alias types.
158+
159+
r[types.equality.rigid]
158160

159161
r[types.equality.aliases]
160162

161-
Aliases are compared by first normalizing them to a *rigid* type? and then equating their type constructors and recursing into their generic arguments.
163+
Aliases are compared by first normalizing them to a *rigid* type and then equating their type constructors and recursing into their generic arguments.
162164

163165
r[types.equality.higher-ranked]
164166

@@ -172,7 +174,6 @@ r[types.equality.higher-ranked.eq]
172174

173175
Equality is checked by both instantiating the `for` of the lhs with inference variables and the `for` of the rhs with placeholders before equating them, and also doing the opposite.
174176

175-
176177
[Array]: types/array.md
177178
[Boolean]: types/boolean.md
178179
[Closures]: types/closure.md

0 commit comments

Comments
 (0)