Skip to content

Commit 89507fe

Browse files
committed
Specify what uses of impl Trait are allowed in impls
1 parent 9476edc commit 89507fe

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

text/0000-return-position-impl-trait-in-traits.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,6 @@ where `T_0 + ... + T_m` are bounds, for any impl of that trait to be valid, the
251251

252252
[^refine]: `#[refine]` was added in [RFC 3245: Refined trait implementations](https://rust-lang.github.io/rfcs/3245-refined-impls.html). This feature is not yet stable. Examples in this RFC requiring the use of `#[refine]` will not work until that feature is stabilized.
253253

254-
Additionally, using `-> impl Trait` notation in an impl is only legal if the trait also uses that notation.
255-
256254
```rust
257255
trait NewIntoIterator {
258256
type Item;
@@ -294,6 +292,23 @@ impl NewIntoIterator for Vec<u32> {
294292
}
295293
```
296294

295+
Additionally, using `-> impl Trait` notation in an impl is only legal if the trait also uses that notation. Each occurrence of `impl Trait` in an impl must unify with an occurrence of `impl Trait` in the trait.
296+
297+
```rust
298+
trait Trait {
299+
fn foo() -> i32;
300+
fn bar() -> impl Sized;
301+
}
302+
303+
impl Trait for () {
304+
// Not OK
305+
fn foo() -> impl Sized { 0 }
306+
307+
// Not OK
308+
fn bar() -> Result<impl Sized, impl Sized> { Ok::<(), ()>(()) }
309+
}
310+
```
311+
297312
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:
298313

299314
```rust
@@ -680,3 +695,20 @@ trait NewIntoIterator {
680695
The only problem remaining is with `#[refine]`. If an existing implementation refined its return value of an RPITIT method, we would need the existing `#[refine]` attribute to stand in for an overriding of the associated type default.
681696

682697
Whatever rules we decide to make this work, they will interact with some ongoing discussions of proposals for `#[defines]` or `#[defined_by]` attributes on `type_alias_impl_trait`. We therefore leave the details of this to a future RFC.
698+
699+
### Adding new occurrences of `impl Trait` in refinements
700+
701+
We may want to allow the following pattern:
702+
703+
```rust
704+
trait Trait {
705+
fn test() -> impl Sized;
706+
}
707+
708+
impl Trait for () {
709+
#[refine]
710+
fn test() -> Result<impl Sized, impl Sized> { Ok::<(), ()>(()) }
711+
}
712+
```
713+
714+
Then uses of `impl Trait` in a trait impl would not necessarily correspond to a use of `impl Trait` in the trait.

0 commit comments

Comments
 (0)