@@ -10,9 +10,12 @@ The special `Self` identifier is now permitted in `struct`, `enum`, and `union`
10
10
type definitions. A simple example ` struct ` is:
11
11
12
12
``` rust
13
- enum List <T > {
13
+ enum List <T >
14
+ where
15
+ Self : PartialOrd <Self > // <-- Notice the `Self` instead of `List<T>`
16
+ {
14
17
Nil ,
15
- Cons (T , Box <Self >) // <-- Notice the `Self` instead of `List<T>`
18
+ Cons (T , Box <Self >) // <-- And here.
16
19
}
17
20
```
18
21
@@ -41,9 +44,9 @@ impl Foo<Self> for Quux {
41
44
}
42
45
```
43
46
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.
47
50
48
51
## Principle of least surprise
49
52
@@ -190,6 +193,69 @@ struct NonEmptyList<T> {
190
193
191
194
This also extends to ` union ` s.
192
195
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
+
193
259
## When ` Self ` can ** not** be used
194
260
195
261
Consider the following small expression language:
@@ -321,8 +387,10 @@ is the [*"Learning Rust With Entirely Too Many Linked Lists"* guide][LRWETMLL].
321
387
# Reference-level explanation
322
388
[ reference-level-explanation ] : #reference-level-explanation
323
389
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.
326
394
327
395
## Desugaring
328
396
@@ -357,6 +425,28 @@ enum StackList<'a, T: 'a + InterestingTrait> {
357
425
}
358
426
```
359
427
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
+
360
450
[ RFC 2102 ] : https://github.com/rust-lang/rfcs/pull/2102
361
451
362
452
## 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],
595
685
the expectation that this alternative already works has not been brought
596
686
forth by anyone as far as this RFC's author is aware.
597
687
688
+ It is also unclear how internal scoped type aliases would syntactically work
689
+ with ` where ` bounds.
690
+
598
691
Strictly speaking, this particular alternative is not in conflict with this
599
692
RFC in that both can be supported technically. The alternative should be
600
693
considered interesting future work, but for now, a more conservative approach
0 commit comments