@@ -10,9 +10,12 @@ The special `Self` identifier is now permitted in `struct`, `enum`, and `union`
1010type definitions. A simple example ` struct ` is:
1111
1212``` rust
13- enum List <T > {
13+ enum List <T >
14+ where
15+ Self : PartialOrd <Self > // <-- Notice the `Self` instead of `List<T>`
16+ {
1417 Nil ,
15- Cons (T , Box <Self >) // <-- Notice the `Self` instead of `List<T>`
18+ Cons (T , Box <Self >) // <-- And here.
1619}
1720```
1821
@@ -41,9 +44,9 @@ impl Foo<Self> for Quux {
4144}
4245```
4346
44- But this is not currently possible inside type definitions. This makes the
45- language less consistent with respect to what is allowed in type positions
46- than what it could be.
47+ But this is not currently possible inside both fields and where clauses of
48+ type definitions. This makes the language less consistent with respect to what
49+ is allowed in type positions than what it could be.
4750
4851## Principle of least surprise
4952
@@ -190,6 +193,69 @@ struct NonEmptyList<T> {
190193
191194This also extends to ` union ` s.
192195
196+ ## ` where ` -clauses
197+
198+ In today's Rust, it is possible to define a type such as:
199+
200+ ``` rust
201+ struct Foo <T >
202+ where
203+ Foo <T >: SomeTrait
204+ {
205+ // Some fields..
206+ }
207+ ```
208+
209+ and with some ` impl ` s:
210+
211+ ``` rust
212+ trait SomeTrait { ... }
213+
214+ impl SomeTrait for Foo <u32 > { ... }
215+ impl SomeTrait for Foo <String > { ... }
216+ ```
217+
218+ this idiom bounds the types that the type parameter ` T ` can be of but also
219+ avoids defining an ` Auxiliary ` trait which one bound ` T ` with as in:
220+
221+ ``` rust
222+ struct Foo <T : Auxiliary > {
223+ // Some fields..
224+ }
225+ ```
226+
227+ You could also have the type on the right hand side of the bound in the ` where `
228+ clause as in:
229+
230+ ``` rust
231+ struct Bar <T >
232+ where
233+ T : PartialEq <Bar <T >>
234+ {
235+ // Some fields..
236+ }
237+ ```
238+
239+ with this RFC, you can now redefine ` Foo<T> ` and ` Bar<T> ` as:
240+
241+ ``` rust
242+ struct Foo <T >
243+ where
244+ Self : SomeTrait // <-- Notice `Self`!
245+ {
246+ // Some fields..
247+ }
248+
249+ struct Bar <T >
250+ where
251+ T : PartialEq <Self > // <-- Notice `Self`!
252+ {
253+ // Some fields..
254+ }
255+ ```
256+
257+ This makes the bound involving ` Self ` slightly more clear.
258+
193259## When ` Self ` can ** not** be used
194260
195261Consider the following small expression language:
@@ -321,8 +387,10 @@ is the [*"Learning Rust With Entirely Too Many Linked Lists"* guide][LRWETMLL].
321387# Reference-level explanation
322388[ reference-level-explanation ] : #reference-level-explanation
323389
324- The identifier ` Self ` is (now) allowed in type contexts in
325- fields of ` struct ` s, ` union ` s, and the variants of ` enum ` s.
390+ The identifier ` Self ` is (now) allowed in type contexts in fields of ` struct ` s,
391+ ` union ` s, and the variants of ` enum ` s. The identifier ` Self ` is also allowed
392+ as the left hand side of a bound in a ` where ` clause and as a type argument
393+ to a trait bound on the right hand side of a ` where ` clause.
326394
327395## Desugaring
328396
@@ -357,6 +425,28 @@ enum StackList<'a, T: 'a + InterestingTrait> {
357425}
358426```
359427
428+ An example of ` Self ` in ` where ` bounds is:
429+
430+ ``` rust
431+ struct Foo <T >
432+ where
433+ Self : PartialEq <Self >
434+ {
435+ // Some fields..
436+ }
437+ ```
438+
439+ which desugars into:
440+
441+ ``` rust
442+ struct Foo <T >
443+ where
444+ Foo <T >: PartialEq <Foo <T >>
445+ {
446+ // Some fields..
447+ }
448+ ```
449+
360450[ RFC 2102 ] : https://github.com/rust-lang/rfcs/pull/2102
361451
362452## In relation to [ RFC 2102] and what ` Self ` refers to.
@@ -595,6 +685,9 @@ some users that `Self` already works, as discussed in the [motivation],
595685the expectation that this alternative already works has not been brought
596686forth by anyone as far as this RFC's author is aware.
597687
688+ It is also unclear how internal scoped type aliases would syntactically work
689+ with ` where ` bounds.
690+
598691Strictly speaking, this particular alternative is not in conflict with this
599692RFC in that both can be supported technically. The alternative should be
600693considered interesting future work, but for now, a more conservative approach
0 commit comments