Skip to content

Commit e91e24d

Browse files
committed
rfc, associated-type-bounds: initial text
1 parent bc430eb commit e91e24d

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

text/0000-associated-type-bounds.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
- Feature Name: associated_type_bounds
2+
- Start Date: 2018-01-13
3+
- RFC PR: (leave this empty)
4+
- Rust Issue: (leave this empty)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Introduce the bound form `MyTrait<AssociatedType: Bounds>`, permitted anywhere
10+
a bound of the form `MyTrait<AssociatedType = T>` would be allowed. This form
11+
desugars to `MyTrait<AssociatedType = impl Bounds>`.
12+
13+
# Motivation
14+
[motivation]: #motivation
15+
16+
Currently, when specifying a bound using a trait that has an associated
17+
type, the developer can specify the precise type via the syntax
18+
`MyTrait<AssociatedType = T>`. With the introduction of the `impl Trait`
19+
syntax for static-dispatch existential types, this syntax also permits
20+
`MyTrait<AssociatedType = impl Bounds>`, as a shorthand for introducing a
21+
new type variable and specifying those bounds.
22+
23+
However, this introduces an unnecessary level of indirection that does not
24+
match the developer's intuition and mental model as well as it could. In
25+
particular, given the ability to write bounds on a type variable as `T: Bounds`,
26+
it makes sense to permit writing bounds on an associated type directly.
27+
This results in the simpler syntax `MyTrait<AssociatedType: Bounds>`.
28+
29+
# Guide-level explanation
30+
[guide-level-explanation]: #guide-level-explanation
31+
32+
Instead of specifying a concrete type for an associated type, we can
33+
specify a bound on the associated type, to ensure that it implements
34+
specific traits, as seen in the example below:
35+
36+
```rust
37+
fn print_all<T: Iterator<Item: Display>>(printables: T) {
38+
for p in printables {
39+
println!("{}", p);
40+
}
41+
}
42+
```
43+
44+
## In anonymous existential types
45+
46+
```rust
47+
fn printables() -> impl Iterator<Item: Display> {
48+
// ..
49+
}
50+
```
51+
52+
## Further examples
53+
54+
Instead of writing:
55+
56+
```rust
57+
impl<I> Clone for Peekable<I>
58+
where
59+
I: Clone + Iterator,
60+
<I as Iterator>::Item: Clone,
61+
{
62+
// ..
63+
}
64+
```
65+
66+
you may write:
67+
68+
```rust
69+
impl<I> Clone for Peekable<I>
70+
where
71+
I: Clone + Iterator<Item: Clone>
72+
{
73+
// ..
74+
}
75+
```
76+
77+
or replace the `where` clause entirely:
78+
79+
```rust
80+
impl<I: Clone + Iterator<Item: Clone>> Clone for Peekable<I> {
81+
// ..
82+
}
83+
```
84+
85+
# Reference-level explanation
86+
[reference-level-explanation]: #reference-level-explanation
87+
88+
The surface syntax `Trait<AssociatedType: Bounds>` should desugar to
89+
`Trait<AssociatedType = impl Bounds>` anywhere it appears. This syntax
90+
does not introduce any new semantics that the availability of
91+
`impl Bounds` does not already introduce.
92+
93+
# Drawbacks
94+
[drawbacks]: #drawbacks
95+
96+
With the introduction of the `impl Trait` syntax, Rust code can already
97+
express this using the desugared form. This proposal just introduces a
98+
simpler surface syntax that parallels other uses of bounds. As always,
99+
when introducing new syntactic forms, an increased burden is put on
100+
developers to know about and understand those forms, and this proposal
101+
is no different. However, we believe that the parallel to the use of bounds
102+
elsewhere makes this new syntax immediately recognizable and understandable.
103+
104+
# Rationale and alternatives
105+
[alternatives]: #alternatives
106+
107+
As with any new surface syntax, one alternative is simply not introducing
108+
the syntax at all. That would still leave developers with the
109+
`MyTrait<AssociatedType = impl Bounds>` form. However, allowing the more
110+
direct bounds syntax provides a better parallel to the use of bounds elsewhere.
111+
The introduced form in this RFC is comparatively both shorter and clearer.
112+
113+
# Unresolved questions
114+
[unresolved]: #unresolved-questions
115+
116+
- Does this introduce any parsing ambiguities?
117+
- Does allowing this for `dyn` trait objects introduce any unforseen issues?

0 commit comments

Comments
 (0)