Skip to content

Commit f1ac4a0

Browse files
committed
Support trailing self in normal paths
1 parent d5a26d8 commit f1ac4a0

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
@@ -615,6 +615,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
615615
// `true` for `...::{self [as target]}` imports, `false` otherwise.
616616
let type_ns_only = source.ident.name == kw::SelfLower;
617617

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

676+
// Deny `use ...::self::source [as target];` or `use ...::self::self [as target];`,
677+
// but allow `use self::source [as target];` and `use self::self as target;`.
678+
if let Some(parent) = module_path.last()
679+
&& parent.ident.name == kw::SelfLower
680+
&& module_path.len() > 1
681+
{
682+
self.r.dcx().span_err(
683+
parent.ident.span,
684+
"`self` in paths can only be used in start position or last position",
685+
);
686+
return;
687+
}
688+
685689
// Deny importing path-kw without renaming
686690
if rename.is_none() && ident.is_path_segment_keyword() {
687691
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
@@ -1837,8 +1837,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18371837
}
18381838
}
18391839

1840+
// Support `...::self`, but deny `::self` after edition 2018
1841+
let allow_trailing_self = is_last
1842+
&& name == kw::SelfLower
1843+
&& segment_idx > 0
1844+
&& (path[segment_idx - 1].ident.name != kw::PathRoot
1845+
|| self.path_root_is_crate_root(path[segment_idx - 1].ident));
1846+
18401847
// Report special messages for path segment keywords in wrong positions.
1841-
if ident.is_path_segment_keyword() && segment_idx != 0 {
1848+
if ident.is_path_segment_keyword() && segment_idx != 0 && !allow_trailing_self {
18421849
return PathResult::failed(
18431850
ident,
18441851
false,
@@ -1858,6 +1865,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18581865
format!("global paths cannot start with {name_str}"),
18591866
"cannot start with this".to_string(),
18601867
)
1868+
} else if name == kw::SelfLower {
1869+
(
1870+
format!(
1871+
"`self` in paths can only be used in start position or last position"
1872+
),
1873+
"can only be used in path start position or last position"
1874+
.to_string(),
1875+
)
18611876
} else {
18621877
(
18631878
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
@@ -41,5 +41,6 @@ impl Trait for S {
4141
mod prefix {}
4242
reuse unresolved_prefix::{a, b, c}; //~ ERROR cannot find module or crate `unresolved_prefix`
4343
reuse prefix::{self, super, crate}; //~ ERROR `crate` in paths can only be used in start position
44+
//~^ ERROR expected function, found module `prefix::self`
4445

4546
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:21: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)