@@ -94,14 +94,20 @@ elided a single lifetime.
94
94
95
95
Lifetime positions can appear as either "input" or "output":
96
96
97
- * For ` fn ` definitions, input refers to argument types while output refers to
97
+ * For ` fn ` definitions, input refers to the types of the formal arguments
98
+ in the ` fn ` definition, while output refers to
98
99
result types. So ` fn foo(s: &str) -> (&str, &str) ` has elided one lifetime in
99
100
input position and two lifetimes in output position.
101
+ Note that the input positions of a ` fn ` method definition do not
102
+ include the lifetimes that occur in the method's ` impl ` header
103
+ (nor lifetimes that occur in the trait header, for a default method).
104
+
100
105
101
106
* For ` impl ` headers, input refers to the lifetimes appears in the type
102
107
receiving the ` impl ` , while output refers to the trait, if any. So `impl<'a>
103
- Foo<'a>` has ` 'a` in input position, while ` impl<'a> SomeTrait<'a> Foo<'a>`
104
- has ` 'a ` in both input and output positions.
108
+ Foo<'a>` has ` 'a` in input position, while ` impl<'a, 'b, 'c>
109
+ SomeTrait<'b, 'c> for Foo<'a, 'c>` has ` 'a` in input position, ` 'b`
110
+ in output position, and ` 'c ` in both input and output positions.
105
111
106
112
### The rules
107
113
@@ -152,6 +158,37 @@ impl<'a, 'b> Reader for (&'a str, &'b str) { ... } // expanded
152
158
153
159
impl StrSlice for & str { ... } // elided
154
160
impl <'a > StrSlice <'a > for & 'a str { ... } // expanded
161
+
162
+ trait Bar <'a > { fn bound (& 'a self ) -> & int { ... } fn fresh (& self ) -> & int { ... } } // elided
163
+ trait Bar <'a > { fn bound (& 'a self ) -> & 'a int { ... } fn fresh <'b >(& 'b self ) -> & 'b int { ... } } // expanded
164
+
165
+ impl <'a > Bar <'a > for & 'a str {
166
+ fn bound (& 'a self ) -> & 'a int { ... } fn fresh (& self ) -> & int { ... } // elided
167
+ }
168
+ impl <'a > Bar <'a > for & 'a str {
169
+ fn bound (& 'a self ) -> & 'a int { ... } fn fresh <'b >(& 'b self ) -> & 'b int { ... } // expanded
170
+ }
171
+
172
+ // Note that when the impl reuses the same signature (with the same elisions)
173
+ // from the trait definition, the expanded forms will also match, and thus
174
+ // the `impl` will be compatible with the `trait`.
175
+
176
+ impl Bar for & str { fn bound (& self ) -> & int { ... } } // elided
177
+ impl <'a > Bar <'a > for & 'a str { fn bound <'b >(& 'b self ) -> & 'b int { ... } } // expanded
178
+
179
+ // Note that the preceding example's expanded methods do not match the
180
+ // signatures from the above trait definition for `Bar`; in the general
181
+ // case, if the elided signatures between the `impl` and the `trait` do
182
+ // not match, an expanded `impl` may not be compatible with the given
183
+ // `trait` (and thus would not compile).
184
+
185
+ impl Bar for & str { fn fresh (& self ) -> & int { ... } } // elided
186
+ impl <'a > Bar <'a > for & 'a str { fn fresh <'b >(& 'b self ) -> & 'b int { ... } } // expanded
187
+
188
+ impl Bar for & str {
189
+ fn bound (& 'a self ) -> & 'a int { ... } fn fresh (& self ) -> & int { ... } // ILLEGAL: unbound 'a
190
+ }
191
+
155
192
```
156
193
157
194
## Error messages
0 commit comments