Skip to content

Commit 7ff3697

Browse files
committed
Allow Self to appear in the where clause of trait impls (rust-lang#1647)
Merges rust-lang#1647
2 parents 83a3d96 + 8e737ce commit 7ff3697

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
- Feature Name: `allow_self_in_where_clauses`
2+
- Start Date: 2016-06-13
3+
- RFC PR: [#1647](https://github.com/rust-lang/rfcs/pull/1647)
4+
- Rust Issue: [#38864](https://github.com/rust-lang/rust/issues/38864)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
This RFC proposes allowing the `Self` type to be used in every position in trait
10+
implementations, including where clauses and other parameters to the trait being
11+
implemented.
12+
13+
# Motivation
14+
[motivation]: #motivation
15+
16+
`Self` is a useful tool to have to reduce churn when the type changes for
17+
various reasons. One would expect to be able to write
18+
19+
```rust
20+
impl SomeTrait for MySuperLongType<T, U, V, W, X> where
21+
Self: SomeOtherTrait,
22+
```
23+
24+
but this will fail to compile today, forcing you to repeat the type, and adding
25+
one more place that has to change if the type ever changes.
26+
27+
By this same logic, we would also like to be able to reference associated types
28+
from the traits being implemented. When dealing with generic code, patterns like
29+
this often emerge:
30+
31+
```rust
32+
trait MyTrait {
33+
type MyType: SomeBound;
34+
}
35+
36+
impl<T, U, V> MyTrait for SomeStruct<T, U, V> where
37+
SomeOtherStruct<T, U, V>: SomeBound,
38+
{
39+
type MyType = SomeOtherStruct<T, U, V>;
40+
}
41+
```
42+
43+
the only reason the associated type is repeated at all is to restate the bound
44+
on the associated type. It would be nice to reduce some of that duplication.
45+
46+
# Detailed design
47+
[design]: #detailed-design
48+
49+
Instead of blocking `Self` from being used in the "header" of a trait impl,
50+
it will be understood to be a reference to the implementation type. For example,
51+
all of these would be valid:
52+
53+
```rust
54+
impl SomeTrait for SomeType where Self: SomeOtherTrait { }
55+
56+
impl SomeTrait<Self> for SomeType { }
57+
58+
impl SomeTrait for SomeType where SomeOtherType<Self>: SomeTrait { }
59+
60+
impl SomeTrait for SomeType where Self::AssocType: SomeOtherTrait {
61+
AssocType = SomeOtherType;
62+
}
63+
```
64+
65+
If the `Self` type is parameterized by `Self`, an error that the type definition
66+
is recursive is thrown, rather than not recognizing self.
67+
68+
```rust
69+
// The error here is because this would be Vec<Vec<Self>>, Vec<Vec<Vec<Self>>>, ...
70+
impl SomeTrait for Vec<Self> { }
71+
```
72+
73+
# Drawbacks
74+
[drawbacks]: #drawbacks
75+
76+
`Self` is always less explicit than the alternative.
77+
78+
# Alternatives
79+
[alternatives]: #alternatives
80+
81+
Not implementing this is an alternative, as is accepting Self only in where clauses
82+
and not other positions in the impl header.
83+
84+
# Unresolved questions
85+
[unresolved]: #unresolved-questions
86+
87+
None

0 commit comments

Comments
 (0)