Skip to content

Commit 312678d

Browse files
committed
Support trailing self in normal paths
1 parent 962ff47 commit 312678d

14 files changed

Lines changed: 299 additions & 260 deletions

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
614614
// `true` for `...::{self [as target]}` imports, `false` otherwise.
615615
let type_ns_only = source.ident.name == kw::SelfLower;
616616

617+
// If the identifier is `self` without a rename,
618+
// then it is replaced with the parent identifier.
617619
let ident = if source.ident.name == kw::SelfLower
618620
&& rename.is_none()
619621
&& let Some(parent) = module_path.last()
@@ -658,29 +660,31 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
658660
return;
659661
}
660662
}
661-
kw::SelfLower if let Some(parent) = module_path.last() => {
662-
// Deny `use ::{self};` after edition 2015
663-
if parent.ident.name == kw::PathRoot
664-
&& !self.r.path_root_is_crate_root(parent.ident)
665-
{
666-
self.r
667-
.dcx()
668-
.span_err(use_tree.span(), "extern prelude cannot be imported");
669-
return;
670-
}
671-
672-
// Deny `use ...::self::self [as name];` but allow `use self::self as name;`
673-
if parent.ident.name == kw::SelfLower && module_path.len() > 1 {
674-
self.r.dcx().span_err(
675-
parent.ident.span,
676-
"`self` in paths can only be used in start position or last position",
677-
);
678-
return;
679-
}
663+
// Deny `use ::{self};` after edition 2015
664+
kw::SelfLower
665+
if let Some(parent) = module_path.last()
666+
&& parent.ident.name == kw::PathRoot
667+
&& !self.r.path_root_is_crate_root(parent.ident) =>
668+
{
669+
self.r.dcx().span_err(use_tree.span(), "extern prelude cannot be imported");
670+
return;
680671
}
681672
_ => (),
682673
}
683674

675+
// Deny `use ...::self::source [as target];` or `use ...::self::self [as target];`,
676+
// but allow `use self::source [as target];` and `use self::self as target;`.
677+
if let Some(parent) = module_path.last()
678+
&& parent.ident.name == kw::SelfLower
679+
&& module_path.len() > 1
680+
{
681+
self.r.dcx().span_err(
682+
parent.ident.span,
683+
"`self` in paths can only be used in start position or last position",
684+
);
685+
return;
686+
}
687+
684688
// Deny importing path-kw without renaming
685689
if rename.is_none() && ident.is_path_segment_keyword() {
686690
let ident = use_tree.ident();

compiler/rustc_resolve/src/ident.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1836,8 +1836,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18361836
}
18371837
}
18381838

1839+
// Support `...::self`, but deny `::self` after edition 2018
1840+
let allow_trailing_self = is_last
1841+
&& name == kw::SelfLower
1842+
&& segment_idx > 0
1843+
&& (path[segment_idx - 1].ident.name != kw::PathRoot
1844+
|| self.path_root_is_crate_root(path[segment_idx - 1].ident));
1845+
18391846
// Report special messages for path segment keywords in wrong positions.
1840-
if ident.is_path_segment_keyword() && segment_idx != 0 {
1847+
if ident.is_path_segment_keyword() && segment_idx != 0 && !allow_trailing_self {
18411848
return PathResult::failed(
18421849
ident,
18431850
false,
@@ -1857,6 +1864,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18571864
format!("global paths cannot start with {name_str}"),
18581865
"cannot start with this".to_string(),
18591866
)
1867+
} else if name == kw::SelfLower {
1868+
(
1869+
format!(
1870+
"`self` in paths can only be used in start position or last position"
1871+
),
1872+
"can only be used in path start position or last position"
1873+
.to_string(),
1874+
)
18601875
} else {
18611876
(
18621877
format!("{name_str} in paths can only be used in start position"),

tests/ui/delegation/bad-resolve.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@ impl Trait for S {
4242
mod prefix {}
4343
reuse unresolved_prefix::{a, b, c}; //~ ERROR cannot find module or crate `unresolved_prefix`
4444
reuse prefix::{self, super, crate}; //~ ERROR `crate` in paths can only be used in start position
45+
//~^ ERROR expected function, found module `prefix::self`
4546

4647
fn main() {}

tests/ui/delegation/bad-resolve.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ LL - reuse Trait::foo2 { self.0 }
8282
LL + reuse Trait::foo { self.0 }
8383
|
8484

85+
error[E0423]: expected function, found module `prefix::self`
86+
--> $DIR/bad-resolve.rs:44:7
87+
|
88+
LL | reuse prefix::{self, super, crate};
89+
| ^^^^^^ not a function
90+
8591
error[E0046]: not all trait items implemented, missing: `Type`
8692
--> $DIR/bad-resolve.rs:22:1
8793
|
@@ -105,7 +111,7 @@ error[E0433]: `crate` in paths can only be used in start position
105111
LL | reuse prefix::{self, super, crate};
106112
| ^^^^^ can only be used in path start position
107113

108-
error: aborting due to 12 previous errors
114+
error: aborting due to 13 previous errors
109115

110116
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0433, E0575, E0576.
111117
For more information about an error, try `rustc --explain E0046`.

tests/ui/imports/absolute-paths-in-nested-use-groups.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use foo::{
88
super::bar,
99
//~^ ERROR: `super` in paths can only be used in start position
1010
self::bar,
11-
//~^ ERROR: `self` in paths can only be used in start position
11+
//~^ ERROR: `self` in paths can only be used in start position or last position
1212
};
1313

1414
fn main() {}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error: `self` in paths can only be used in start position or last position
2+
--> $DIR/absolute-paths-in-nested-use-groups.rs:10:5
3+
|
4+
LL | self::bar,
5+
| ^^^^
6+
17
error[E0433]: the crate root in paths can only be used in start position
28
--> $DIR/absolute-paths-in-nested-use-groups.rs:6:5
39
|
@@ -10,12 +16,6 @@ error[E0433]: `super` in paths can only be used in start position
1016
LL | super::bar,
1117
| ^^^^^ can only be used in path start position
1218

13-
error[E0433]: `self` in paths can only be used in start position
14-
--> $DIR/absolute-paths-in-nested-use-groups.rs:10:5
15-
|
16-
LL | self::bar,
17-
| ^^^^ can only be used in path start position
18-
1919
error: aborting due to 3 previous errors
2020

2121
For more information about this error, try `rustc --explain E0433`.

tests/ui/use/use-mod/use-mod-3.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0603]: module `bar` is private
33
|
44
LL | use foo::bar::{
55
| ^^^ private module
6+
LL | self
7+
| ---- module `self` is not publicly re-exported
68
|
79
note: the module `bar` is defined here
810
--> $DIR/use-mod-3.rs:9:5

tests/ui/use/use-path-segment-kw.e2015.stderr

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ LL | use self as name;
268268
| +++++++
269269

270270
error: imports need to be explicitly named
271-
--> $DIR/use-path-segment-kw.rs:176:15
271+
--> $DIR/use-path-segment-kw.rs:178:15
272272
|
273273
LL | use ::self;
274274
| ^^^^
@@ -279,7 +279,7 @@ LL | use ::self as name;
279279
| +++++++
280280

281281
error: imports need to be explicitly named
282-
--> $DIR/use-path-segment-kw.rs:179:16
282+
--> $DIR/use-path-segment-kw.rs:181:16
283283
|
284284
LL | use ::{self};
285285
| ^^^^
@@ -290,7 +290,7 @@ LL | use ::{self as name};
290290
| +++++++
291291

292292
error: imports need to be explicitly named
293-
--> $DIR/use-path-segment-kw.rs:192:20
293+
--> $DIR/use-path-segment-kw.rs:194:20
294294
|
295295
LL | use crate::self;
296296
| ^^^^
@@ -301,7 +301,7 @@ LL | use crate::self as name;
301301
| +++++++
302302

303303
error: imports need to be explicitly named
304-
--> $DIR/use-path-segment-kw.rs:194:21
304+
--> $DIR/use-path-segment-kw.rs:196:21
305305
|
306306
LL | use crate::{self};
307307
| ^^^^
@@ -312,7 +312,7 @@ LL | use crate::{self as name};
312312
| +++++++
313313

314314
error: imports need to be explicitly named
315-
--> $DIR/use-path-segment-kw.rs:198:20
315+
--> $DIR/use-path-segment-kw.rs:200:20
316316
|
317317
LL | use super::self;
318318
| ^^^^
@@ -323,7 +323,7 @@ LL | use super::self as name;
323323
| +++++++
324324

325325
error: imports need to be explicitly named
326-
--> $DIR/use-path-segment-kw.rs:200:21
326+
--> $DIR/use-path-segment-kw.rs:202:21
327327
|
328328
LL | use super::{self};
329329
| ^^^^
@@ -334,7 +334,7 @@ LL | use super::{self as name};
334334
| +++++++
335335

336336
error: imports need to be explicitly named
337-
--> $DIR/use-path-segment-kw.rs:204:19
337+
--> $DIR/use-path-segment-kw.rs:206:19
338338
|
339339
LL | use self::self;
340340
| ^^^^
@@ -345,7 +345,7 @@ LL | use self::self as name;
345345
| +++++++
346346

347347
error: imports need to be explicitly named
348-
--> $DIR/use-path-segment-kw.rs:206:20
348+
--> $DIR/use-path-segment-kw.rs:208:20
349349
|
350350
LL | use self::{self};
351351
| ^^^^
@@ -753,7 +753,7 @@ LL | use $crate::{self as name};
753753
| +++++++
754754

755755
error[E0433]: cannot find module or crate `foobar` in the crate root
756-
--> $DIR/use-path-segment-kw.rs:184:17
756+
--> $DIR/use-path-segment-kw.rs:186:17
757757
|
758758
LL | pub use foobar::qux::self;
759759
| ^^^^^^ use of unresolved module or unlinked crate `foobar`
@@ -764,7 +764,7 @@ LL + extern crate foobar;
764764
|
765765

766766
error[E0433]: cannot find module or crate `foobar` in the crate root
767-
--> $DIR/use-path-segment-kw.rs:188:17
767+
--> $DIR/use-path-segment-kw.rs:190:17
768768
|
769769
LL | pub use foobar::baz::{self};
770770
| ^^^^^^ use of unresolved module or unlinked crate `foobar`
@@ -775,7 +775,7 @@ LL + extern crate foobar;
775775
|
776776

777777
error[E0432]: unresolved import `foobar`
778-
--> $DIR/use-path-segment-kw.rs:186:17
778+
--> $DIR/use-path-segment-kw.rs:188:17
779779
|
780780
LL | pub use foobar::self as _self3;
781781
| ^^^^^^
@@ -786,7 +786,7 @@ LL | pub use self::foobar::self as _self3;
786786
| ++++++
787787

788788
error[E0432]: unresolved import `foobar`
789-
--> $DIR/use-path-segment-kw.rs:189:17
789+
--> $DIR/use-path-segment-kw.rs:191:17
790790
|
791791
LL | pub use foobar::{self as _nested_self3};
792792
| ^^^^^^
@@ -796,12 +796,6 @@ help: a similar path exists
796796
LL | pub use self::foobar::{self as _nested_self3};
797797
| ++++++
798798

799-
error[E0433]: `self` in paths can only be used in start position
800-
--> $DIR/use-path-segment-kw.rs:209:36
801-
|
802-
LL | type D7 = crate::foo::bar::self;
803-
| ^^^^ can only be used in path start position
804-
805799
error[E0573]: expected type, found module `$crate`
806800
--> $DIR/use-path-segment-kw.rs:10:19
807801
|
@@ -813,6 +807,17 @@ LL | macro_dollar_crate!();
813807
|
814808
= note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
815809

810+
error[E0573]: expected type, found module `$crate::self`
811+
--> $DIR/use-path-segment-kw.rs:62:20
812+
|
813+
LL | type A10 = $crate::self;
814+
| ^^^^^^^^^^^^ not a type
815+
...
816+
LL | macro_dollar_crate!();
817+
| --------------------- in this macro invocation
818+
|
819+
= note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
820+
816821
error[E0573]: expected type, found module `crate`
817822
--> $DIR/use-path-segment-kw.rs:95:19
818823
|
@@ -843,6 +848,42 @@ error[E0573]: expected type, found module `self`
843848
LL | type D1 = self;
844849
| ^^^^ not a type
845850

851+
error[E0573]: expected type, found module `::self`
852+
--> $DIR/use-path-segment-kw.rs:175:19
853+
|
854+
LL | type D2 = ::self;
855+
| ^^^^^^ not a type
856+
857+
error[E0573]: expected type, found module `foobar::self`
858+
--> $DIR/use-path-segment-kw.rs:185:19
859+
|
860+
LL | type D3 = foobar::self;
861+
| ^^^^^^^^^^^^ not a type
862+
863+
error[E0573]: expected type, found module `crate::self`
864+
--> $DIR/use-path-segment-kw.rs:193:19
865+
|
866+
LL | type D4 = crate::self;
867+
| ^^^^^^^^^^^ not a type
868+
869+
error[E0573]: expected type, found module `super::self`
870+
--> $DIR/use-path-segment-kw.rs:199:19
871+
|
872+
LL | type D5 = super::self;
873+
| ^^^^^^^^^^^ not a type
874+
875+
error[E0573]: expected type, found module `self::self`
876+
--> $DIR/use-path-segment-kw.rs:205:19
877+
|
878+
LL | type D6 = self::self;
879+
| ^^^^^^^^^^ not a type
880+
881+
error[E0573]: expected type, found module `crate::foo::bar::self`
882+
--> $DIR/use-path-segment-kw.rs:211:19
883+
|
884+
LL | type D7 = crate::foo::bar::self;
885+
| ^^^^^^^^^^^^^^^^^^^^^ not a type
886+
846887
error[E0433]: global paths cannot start with `$crate`
847888
--> $DIR/use-path-segment-kw.rs:14:21
848889
|
@@ -931,17 +972,6 @@ LL | macro_dollar_crate!();
931972
|
932973
= note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
933974

934-
error[E0433]: `self` in paths can only be used in start position
935-
--> $DIR/use-path-segment-kw.rs:62:28
936-
|
937-
LL | type A10 = $crate::self;
938-
| ^^^^ can only be used in path start position
939-
...
940-
LL | macro_dollar_crate!();
941-
| --------------------- in this macro invocation
942-
|
943-
= note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
944-
945975
error[E0433]: global paths cannot start with `crate`
946976
--> $DIR/use-path-segment-kw.rs:99:21
947977
|
@@ -990,36 +1020,6 @@ error[E0433]: `super` in paths can only be used in start position
9901020
LL | type C4 = crate::super;
9911021
| ^^^^^ can only be used in path start position
9921022

993-
error[E0433]: global paths cannot start with `self`
994-
--> $DIR/use-path-segment-kw.rs:175:21
995-
|
996-
LL | type D2 = ::self;
997-
| ^^^^ cannot start with this
998-
999-
error[E0433]: `self` in paths can only be used in start position
1000-
--> $DIR/use-path-segment-kw.rs:183:27
1001-
|
1002-
LL | type D3 = foobar::self;
1003-
| ^^^^ can only be used in path start position
1004-
1005-
error[E0433]: `self` in paths can only be used in start position
1006-
--> $DIR/use-path-segment-kw.rs:191:26
1007-
|
1008-
LL | type D4 = crate::self;
1009-
| ^^^^ can only be used in path start position
1010-
1011-
error[E0433]: `self` in paths can only be used in start position
1012-
--> $DIR/use-path-segment-kw.rs:197:26
1013-
|
1014-
LL | type D5 = super::self;
1015-
| ^^^^ can only be used in path start position
1016-
1017-
error[E0433]: `self` in paths can only be used in start position
1018-
--> $DIR/use-path-segment-kw.rs:203:25
1019-
|
1020-
LL | type D6 = self::self;
1021-
| ^^^^ can only be used in path start position
1022-
10231023
error: aborting due to 115 previous errors
10241024

10251025
Some errors have detailed explanations: E0432, E0433, E0573.

0 commit comments

Comments
 (0)