You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Copy file name to clipboardExpand all lines: src/trait-bounds.md
+40-16Lines changed: 40 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,13 +56,11 @@ The bounds of an item must be satisfied when using that item.
56
56
57
57
r[bound.satisfaction.impl]
58
58
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.
64
62
65
-
[bound.satisfaction.impl.builtin]
63
+
r[bound.satisfaction.impl.builtin]
66
64
67
65
There exist impls which are automatically generated by the compiler.
68
66
@@ -71,21 +69,51 @@ There exist impls which are automatically generated by the compiler.
71
69
72
70
- alternative: mention this in item-kind impl
73
71
74
-
[bound.satisfaction.impl.builtin.trait-object]
72
+
r[bound.satisfaction.impl.builtin.trait-object]
75
73
76
74
Trait objects implement their trait if TODO: lookup conditions, something something project bounds make sense
77
75
78
-
[bound.satisfaction.bounds]
76
+
r[bound.satisfaction.bounds]
79
77
80
78
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.
81
79
82
-
[bound.satisfaction.alias-bounds]
80
+
r[bound.satisfaction.alias-bounds]
83
81
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
+
traitTrait {
86
+
typeAssoc:Clone;
87
+
}
88
+
89
+
fnfoo<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
+
traitTrait {
101
+
typeAssoc:Iterator
102
+
where
103
+
<Self::AssocasIterator>::Item:Clone;
104
+
// equivalent to
105
+
// type Assoc: Iterator<Item: Clone>;
106
+
}
107
+
108
+
fnitem_is_clone<T:Trait>(iter:T::Assoc) {
109
+
foriteminiter {
110
+
let_=item.clone();
111
+
}
112
+
}
113
+
```
86
114
87
115
88
-
[bound.satisfaction.candidate-preference]
116
+
r[bound.satisfaction.candidate-preference]
89
117
90
118
> This is purely descriptive. Candidate preference behavior may change in future releases and must not be relied upon for correctness or soundness.
91
119
@@ -99,10 +127,6 @@ If there are multiple ways to satisfy a trait bound, some groups of candidate ar
99
127
100
128
> note: this candidate preference can result in incorrect errors and type mismatches, e.g. ...
101
129
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
-
106
130
r[bound.trait-object]
107
131
Trait and lifetime bounds are also used to name [trait objects].
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]
158
160
159
161
r[types.equality.aliases]
160
162
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.
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.
0 commit comments