@@ -386,11 +386,12 @@ enum StackList<'a, T: 'a + InterestingTrait> {
386
386
387
387
[ RFC 2102 ] : https://github.com/rust-lang/rfcs/pull/2102
388
388
389
- ## In relation to [ RFC 2102]
389
+ ## In relation to [ RFC 2102] and what ` Self ` refers to.
390
390
391
- It should be noted that ` Self ` always refers to the top level type and not the
392
- inner unnamed ` struct ` or ` union ` . In other words:
393
- * Self always applies to the top level inside type definitions* .
391
+ It should be noted that ` Self ` always refers to the top level type and not
392
+ the inner unnamed ` struct ` or ` union ` because those are unnamed. Specifically,
393
+ * Self always applies to the innermost nameable type* . In type definitions in
394
+ particular, this is equivalent: * Self always applies to the top level type* .
394
395
395
396
## Error messages
396
397
@@ -442,6 +443,111 @@ it removes exceptional cases especially in the users mental model.
442
443
The rationale for this particular design is straightforward as it would be
443
444
uneconomic, confusing, and inconsistent to use other keywords.
444
445
446
+ ## The consistency of what ` Self ` refers to
447
+
448
+ As explained in the [ reference-level explanation] , we said that:
449
+ > * Self always applies to the innermost nameable type* .
450
+
451
+ We arrive at this conclusion by examining a few different cases and what
452
+ they have in common.
453
+
454
+ ### Current Rust - Shadowing in ` impl ` s
455
+
456
+ First, let's take a look at shadowing in ` impl ` s.
457
+
458
+ ``` rust
459
+ fn main () { Foo {}. foo (); }
460
+
461
+ #[derive(Debug )]
462
+ struct Foo ;
463
+
464
+ impl Foo {
465
+ fn foo (& self ) {
466
+ // Prints "Foo", which is the innermost type.
467
+ println! (" {:?}" , Self {});
468
+
469
+ #[derive(Debug )]
470
+ struct Bar ;
471
+
472
+ impl Bar {
473
+ fn bar (& self ) {
474
+ // Prints "Bar", also the innermost type in this context.
475
+ println! (" {:?}" , Self {});
476
+ }
477
+ }
478
+ Bar {}. bar ();
479
+ }
480
+ }
481
+ ```
482
+
483
+ Let's also consider trait impls instead of inherent impls:
484
+
485
+ ``` rust
486
+ impl Trait for Foo {
487
+ fn foo (& self ) {
488
+ impl Trait for Bar {
489
+ // Self is shadowed here...
490
+ }
491
+ }
492
+ }
493
+ ```
494
+
495
+ We see that the conclusion holds for both examples.
496
+
497
+ ### In relation to [ RFC 2102]
498
+
499
+ Let's consider a modified example from [ RFC 2102] :
500
+
501
+ ``` rust
502
+ #[repr(C )]
503
+ struct S {
504
+ a : u32 ,
505
+ _ : union {
506
+ b : Box <Self >,
507
+ c : f32 ,
508
+ },
509
+ d : u64 ,
510
+ }
511
+ ```
512
+
513
+ In this example, the inner union is not nameable, and so ` Self ` refers to the
514
+ only nameable introduced type ` S ` . Therefore, the conclusion holds.
515
+
516
+ ### Type definitions inside ` impl ` s
517
+
518
+ If in the future we decide to permit type definitions inside ` impl ` s as in:
519
+
520
+ ``` rust
521
+ impl Trait for Foo {
522
+ struct Bar {
523
+ head : u8 ,
524
+ tail : Option <Box <Self >>,
525
+ }
526
+ }
527
+ ```
528
+
529
+ as sugar for:
530
+
531
+ ``` rust
532
+ enum _Bar {
533
+ head : u8 ,
534
+ tail : Option <Box <Self >>,
535
+ }
536
+ impl Trait for Foo {
537
+ type Bar = _Bar ;
538
+ }
539
+ ```
540
+
541
+ In the desugared example, we see that the only possible meaning of ` Self ` is
542
+ that it refers to ` _Bar ` and not ` Foo ` . To be consistent with the desugared
543
+ form, the sugared variant should have the same meaning and so ` Self ` refers
544
+ to ` Bar ` there.
545
+
546
+ ### Conclusion
547
+
548
+ We've now examined a few cases and seen that indeed, the meaning of ` Self ` is
549
+ consistent in all of them as well as with what the meaning in in today's Rust.
550
+
445
551
## Doing nothing
446
552
447
553
One alternative to the changes proposed in this RFC is to simply not implement
0 commit comments