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
Copy file name to clipboardExpand all lines: text/0000-return-position-impl-trait-in-traits.md
+44-1Lines changed: 44 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -179,7 +179,6 @@ impl NewIntoIterator for Vec<u32> {
179
179
}
180
180
```
181
181
182
-
183
182
## Generic parameter capture and GATs
184
183
185
184
Given a trait method with a return type like `-> impl A + ... + Z` and an implementation of that trait, the hidden type for that implementation is allowed to reference:
@@ -239,6 +238,7 @@ trait Trait {
239
238
where `T_0 + ... + T_m` are bounds, for any impl of that trait to be valid, the following conditions must hold:
240
239
241
240
* The return type named in the corresponding impl method must implement all bounds `T_0 + ... + T_m` specified in the trait.
241
+
* This must be proven using only the information in the signature, with the exception that if the impl uses `impl Trait` syntax for the return type, the usual auto trait leakage rules apply.
242
242
* Either the impl method must have `#[refine]`,[^refine] OR
243
243
* The impl must use `impl Trait` syntax to name the corresponding type, and
244
244
* The return type in the trait must implement all bounds `I_0 + ... + I_n` specified in the impl return type. (Taken with the first outer bullet point, we can say that the bounds in the trait and the bounds in the impl imply each other.)
@@ -288,6 +288,49 @@ impl NewIntoIterator for Vec<u32> {
288
288
}
289
289
```
290
290
291
+
An interesting consequence of auto trait leakage is that a trait is allowed to specify an auto trait in its return type bounds, but the impl does not have to _repeat_ that auto trait in its signature, as long as its return type actually implements the required bound. For example:
292
+
293
+
```rust
294
+
/// Converts `self` into an iterator that is always `Send`.
// OK (auto traits leak, so adding `+ Send` here is NOT required):
309
+
implIntoSendIteratorforVec<u32> {
310
+
typeItem=u32;
311
+
fninto_iter(self) ->implIterator<Item=u32> {
312
+
self.into_iter()
313
+
}
314
+
}
315
+
316
+
// OK:
317
+
impl<T:Send> IntoSendIteratorforVec<T> {
318
+
// ^^^^ Required for our iterator to be Send!
319
+
typeItem=T;
320
+
fninto_iter(self) ->implIterator<Item=T> {
321
+
self.into_iter()
322
+
}
323
+
}
324
+
325
+
// Not OK (returned iterator is not known to be `Send`):
326
+
impl<T> IntoSendIteratorforVec<T> {
327
+
typeItem=T;
328
+
fninto_iter(self) ->implIterator<Item=T> {
329
+
self.into_iter()
330
+
}
331
+
}
332
+
```
333
+
291
334
### Interaction with `async fn` in trait
292
335
293
336
This RFC modifies the “Static async fn in traits” RFC so that async fn in traits may be satisfied by implementations that return `impl Future<Output = ...>` as long as the return-position impl trait type matches the async fn's desugared impl trait with the same rules as above.
0 commit comments