@@ -21,7 +21,7 @@ With the placeholder syntax used in discussions so far,
21
21
abstract return types would be used roughly like this:
22
22
23
23
``` rust
24
- fn foo (n : u32 ) -> impl Iterator <Item = u32 > {
24
+ fn foo (n : u32 ) -> impl Iterator <Item = u32 > {
25
25
(0 .. n ). map (| x | x * 100 )
26
26
}
27
27
// ^ behaves as if it had return type Map<Range<u32>, Closure>
@@ -30,7 +30,6 @@ fn foo(n: u32) -> impl Iterator<Item=u32> {
30
30
for x in foo (10 ) {
31
31
// x = 0, 100, 200, ...
32
32
}
33
-
34
33
```
35
34
36
35
# Background
@@ -61,10 +60,10 @@ its motivation and some other parts of its text below.
61
60
62
61
In today's Rust, you can write a function signature like
63
62
64
- ```` rust
65
- fn consume_iter_static <I : Iterator <u8 >>(iter : I )
66
- fn consume_iter_dynamic (iter : Box <Iterator <u8 >>)
67
- ````
63
+ ``` rust
64
+ fn consume_iter_static <I : Iterator <Item = u8 >>(iter : I )
65
+ fn consume_iter_dynamic (iter : Box <Iterator <Item = u8 >>)
66
+ ```
68
67
69
68
In both cases , the function does not depend on the exact type of the argument .
70
69
The type is held " abstract" , and is assumed only to satisfy a trait bound .
@@ -78,15 +77,15 @@ The type is held "abstract", and is assumed only to satisfy a trait bound.
78
77
79
78
On the other hand , while you can write
80
79
81
- ```` rust
82
- fn produce_iter_dynamic () -> Box <Iterator <u8 >>
83
- ````
80
+ ```rust
81
+ fn produce_iter_dynamic () -> Box <Iterator <Item = u8 >>
82
+ ```
84
83
85
84
you _cannot_ write something like
86
85
87
- ```` rust
88
- fn produce_iter_static () -> Iterator <u8 >
89
- ````
86
+ ```rust
87
+ fn produce_iter_static () -> Iterator <Item = u8 >
88
+ ```
90
89
91
90
That is , in today 's Rust , abstract return types can only be written using trait
92
91
objects , which can be a significant performance penalty . This RFC proposes
@@ -98,22 +97,22 @@ Here are some problems that unboxed abstract types solve or mitigate:
98
97
99
98
* _Returning unboxed closures_ . Closure syntax generates an anonymous type
100
99
implementing a closure trait . Without unboxed abstract types , there is no way
101
- to use this syntax while returning the resulting closure unboxed , because there
100
+ to use this syntax while returning the resulting closure unboxed because there
102
101
is no way to write the name of the generated type .
103
102
104
103
* _Leaky APIs_ . Functions can easily leak implementation details in their return
105
104
type , when the API should really only promise a trait bound . For example , a
106
105
function returning `Rev <Splits <'a , u8 >>` is revealing exactly how the iterator
107
106
is constructed , when the function should only promise that it returns _some_
108
- type implementing `Iterator <u8 >`. Using newtypes / structs with private fields
107
+ type implementing `Iterator <Item = u8 >`. Using newtypes / structs with private fields
109
108
helps , but is extra work . Unboxed abstract types make it as easy to promise only
110
109
a trait bound as it is to return a concrete type .
111
110
112
111
* _Complex types_ . Use of iterators in particular can lead to huge types :
113
112
114
- ```` rust
115
- Chain <Map <'a , (int , u8 ), u16 , Enumerate <Filter <'a , u8 , vec :: MoveItems <u8 >>>>, SkipWhile <'a , u16 , Map <'a , & u16 , u16 , slice :: Items <u16 >>>>
116
- ````
113
+ ```rust
114
+ Chain <Map <'a , (i32 , u8 ), u16 , Enumerate <Filter <'a , u8 , vec :: MoveItems <u8 >>>>, SkipWhile <'a , u16 , Map <'a , & u16 , u16 , slice :: Items <u16 >>>>
115
+ ```
117
116
118
117
Even when using newtypes to hide the details , the type still has to be written
119
118
out , which can be very painful . Unboxed abstract types only require writing the
@@ -142,7 +141,7 @@ with other extensions.
142
141
## Syntax
143
142
144
143
Let 's start with the bikeshed : The proposed syntax is `impl Trait ` in return type
145
- position , composing like trait objects to forms like `impl Foo + Send + 'a `.
144
+ position , composing like trait objects to forms like `impl Foo + Send + 'a `.
146
145
147
146
It can be explained as " a type that implements `Trait`" ,
148
147
and has been used in that form in most earlier discussions and proposals .
@@ -163,7 +162,7 @@ The core semantics of the feature is described below.
163
162
164
163
Note that the sections after this one go into more detail on some of the design
165
164
decisions , and that * * it is likely for many of the mentioned limitations to be
166
- lifted at some point in the future ** . For clarity , we 'll separately categories the * core
165
+ lifted at some point in the future ** . For clarity , we 'll separately categorize the * core
167
166
semantics * of the feature (aspects that would stay unchanged with future extensions )
168
167
and the * initial limitations * (which are likely to be lifted later ).
169
168
@@ -182,7 +181,7 @@ and the *initial limitations* (which are likely to be lifted later).
182
181
- The type would not be known to implement any other trait , with
183
182
the exception of OIBITS (aka " auto traits" ) and default traits like `Sized `.
184
183
- The type would not be considered equal to the actual underlying type .
185
- - The type would not be allowed to appear as the Self type for an `impl ` block .
184
+ - The type would not be allowed to appear as the ` Self ` type for an `impl ` block .
186
185
187
186
- Because OIBITS like `Send ` and `Sync ` will leak through an abstract return
188
187
type , there will be some additional complexity in the compiler due to some
@@ -224,7 +223,7 @@ and the *initial limitations* (which are likely to be lifted later).
224
223
unless these are themselves part of a legal return type.
225
224
226
225
- Eventually, we will want to allow the feature to be used within traits, and
227
- like in argument position as well (as an ergonomic improvement over today 's generics ).
226
+ likely in argument position as well (as an ergonomic improvement over today's generics).
228
227
- Using ` impl Trait ` multiple times in the same return type would be valid,
229
228
like for example in ` -> (impl Foo, impl Bar) ` .
230
229
@@ -253,7 +252,7 @@ and the *initial limitations* (which are likely to be lifted later).
253
252
254
253
## Rationale
255
254
256
- ### Why this semantics for the return type ?
255
+ ### Why these semantics for the return type?
257
256
258
257
There has been a lot of discussion about what the semantics of the return type
259
258
should be, with the theoretical extremes being "full return type inference" and
@@ -411,11 +410,11 @@ so the syntax is forbidden there.
411
410
412
411
### Compatibility with conditional trait bounds
413
412
414
- On valid critique for the existing `impl Trait ` proposal is that it does not
415
- cover more complex scenarios , where the return type would implement
413
+ One valid critique for the existing ` impl Trait ` proposal is that it does not
414
+ cover more complex scenarios where the return type would implement
416
415
one or more traits depending on whether a type parameter does so with another.
417
416
418
- For example , a iterator adapter might want to implement `Iterator ` and
417
+ For example, an iterator adapter might want to implement ` Iterator ` and
419
418
` DoubleEndedIterator ` , depending on whether the adapted one does:
420
419
421
420
``` rust
@@ -427,7 +426,7 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for SkipOne<I> { ... }
427
426
428
427
Using just ` -> impl Iterator ` , this would not be possible to reproduce.
429
428
430
- Since there has been no proposals so far that would address this in a way
429
+ Since there have been no proposals so far that would address this in a way
431
430
that would conflict with the fixed-trait-set case, this RFC punts on that issue as well.
432
431
433
432
### Limitation to free/inherent functions
@@ -436,10 +435,10 @@ One important usecase of abstract return types is to use them in trait methods.
436
435
437
436
However, there is an issue with this, namely that in combinations with generic
438
437
trait methods, they are effectively equivalent to higher kinded types.
439
- Which is an issue because Rust HKT story is not yet figured out, so
438
+ Which is an issue because Rust's HKT story is not yet figured out, so
440
439
any "accidental implementation" might cause unintended fallout.
441
440
442
- HKT allows you to be generic over a type constructor, aka a
441
+ HKT allows you to be generic over a type constructor, a.k.a. a
443
442
"thing with type parameters", and then instantiate them at some later point to
444
443
get the actual type.
445
444
For example, given a HK type ` T ` that takes one type as parameter, you could
@@ -460,7 +459,7 @@ with a `u32` or `bool`,
460
459
just like `T <u32 >` and `T <bool >` might give us `Vec <u32 >` or `Box <bool >`
461
460
in the example above .
462
461
463
- The problem does not exists with trait method return types today because
462
+ The problem does not exist with trait method return types today because
464
463
they are concrete :
465
464
466
465
```rust
@@ -473,7 +472,7 @@ Given the above code, there is no way for `bar` to choose a return type `X`
473
472
that could fundamentally differ between instantiations of `Self `
474
473
while still being instantiable with an arbitrary `U `.
475
474
476
- At most you could return a associated type , but then you'd loose the generics
475
+ At most you could return a associated type , but then you 'd lose the generics
477
476
from `bar `
478
477
479
478
```rust
@@ -483,7 +482,7 @@ trait Foo {
483
482
}
484
483
```
485
484
486
- So , in conclusion , since Rusts HKT story is not yet fleshed out ,
485
+ So , in conclusion , since Rust ' s HKT story is not yet fleshed out ,
487
486
and the compatibility of the current compiler with it is unknown ,
488
487
it is not yet possible to reach a concrete solution here .
489
488
0 commit comments