Skip to content

Commit ff20938

Browse files
authored
Unrolled build for #152999
Rollup merge of #152999 - mu001999-contrib:fix/152997, r=petrochenkov Check importing `crate`/`$crate`/`super` after handling `self` Fixes #152997 r? petrochenkov
2 parents b3869b9 + 5cfaada commit ff20938

3 files changed

Lines changed: 86 additions & 35 deletions

File tree

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,35 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
629629
// `true` for `...::{self [as target]}` imports, `false` otherwise.
630630
let type_ns_only = nested && source.ident.name == kw::SelfLower;
631631

632+
if source.ident.name == kw::SelfLower
633+
&& let Some(parent) = module_path.pop()
634+
{
635+
// Suggest `use prefix::{self};` for `use prefix::self;`
636+
if !type_ns_only
637+
&& (parent.ident.name != kw::PathRoot
638+
|| self.r.path_root_is_crate_root(parent.ident))
639+
{
640+
let span_with_rename = match rename {
641+
Some(rename) => source.ident.span.to(rename.span),
642+
None => source.ident.span,
643+
};
644+
645+
self.r.report_error(
646+
parent.ident.span.shrink_to_hi().to(source.ident.span),
647+
ResolutionError::SelfImportsOnlyAllowedWithin {
648+
root: parent.ident.name == kw::PathRoot,
649+
span_with_rename,
650+
},
651+
);
652+
}
653+
654+
let self_span = source.ident.span;
655+
source = parent;
656+
if rename.is_none() {
657+
ident = Ident::new(source.ident.name, self_span);
658+
}
659+
}
660+
632661
match source.ident.name {
633662
kw::DollarCrate => {
634663
if !module_path.is_empty() {
@@ -664,45 +693,14 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
664693
return;
665694
}
666695
}
667-
kw::SelfLower => {
668-
if let Some(parent) = module_path.pop() {
669-
// Suggest `use prefix::{self};` for `use prefix::self;`
670-
if !type_ns_only
671-
&& (parent.ident.name != kw::PathRoot
672-
|| self.r.path_root_is_crate_root(parent.ident))
673-
{
674-
let span_with_rename = match rename {
675-
Some(rename) => source.ident.span.to(rename.span),
676-
None => source.ident.span,
677-
};
678-
679-
self.r.report_error(
680-
parent.ident.span.shrink_to_hi().to(source.ident.span),
681-
ResolutionError::SelfImportsOnlyAllowedWithin {
682-
root: parent.ident.name == kw::PathRoot,
683-
span_with_rename,
684-
},
685-
);
686-
}
687-
688-
let self_span = source.ident.span;
689-
source = parent;
690-
if rename.is_none() {
691-
ident = Ident::new(source.ident.name, self_span);
692-
}
693-
}
696+
// Deny `use ::{self};` after edition 2015
697+
kw::PathRoot if !self.r.path_root_is_crate_root(source.ident) => {
698+
self.r.dcx().span_err(use_tree.span, "extern prelude cannot be imported");
699+
return;
694700
}
695701
_ => {}
696702
}
697703

698-
// Deny `use ::{self};` after edition 2015
699-
if source.ident.name == kw::PathRoot
700-
&& !self.r.path_root_is_crate_root(source.ident)
701-
{
702-
self.r.dcx().span_err(use_tree.span, "extern prelude cannot be imported");
703-
return;
704-
}
705-
706704
// Deny importing path-kw without renaming
707705
if rename.is_none() && ident.is_path_segment_keyword() {
708706
let ident = use_tree.ident();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
pub mod x {
2+
pub use crate::x::super::{self as crate1}; //~ ERROR `super` in paths can only be used in start position
3+
pub use crate::x::self::super::{self as crate2}; //~ ERROR `super` in paths can only be used in start position
4+
5+
pub fn foo() {}
6+
}
7+
8+
fn main() {
9+
x::crate1::x::foo(); //~ ERROR cannot find `crate1` in `x`
10+
x::crate2::x::foo(); //~ ERROR cannot find `crate2` in `x`
11+
12+
crate::x::super::x::foo(); //~ ERROR `super` in paths can only be used in start position
13+
crate::x::self::super::x::foo(); //~ ERROR `self` in paths can only be used in start position
14+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error: `super` in paths can only be used in start position, after `self`, or after another `super`
2+
--> $DIR/use-super-in-middle.rs:2:23
3+
|
4+
LL | pub use crate::x::super::{self as crate1};
5+
| ^^^^^
6+
7+
error: `super` in paths can only be used in start position, after `self`, or after another `super`
8+
--> $DIR/use-super-in-middle.rs:3:29
9+
|
10+
LL | pub use crate::x::self::super::{self as crate2};
11+
| ^^^^^
12+
13+
error[E0433]: cannot find `crate1` in `x`
14+
--> $DIR/use-super-in-middle.rs:9:8
15+
|
16+
LL | x::crate1::x::foo();
17+
| ^^^^^^ could not find `crate1` in `x`
18+
19+
error[E0433]: cannot find `crate2` in `x`
20+
--> $DIR/use-super-in-middle.rs:10:8
21+
|
22+
LL | x::crate2::x::foo();
23+
| ^^^^^^ could not find `crate2` in `x`
24+
25+
error[E0433]: `super` in paths can only be used in start position
26+
--> $DIR/use-super-in-middle.rs:12:15
27+
|
28+
LL | crate::x::super::x::foo();
29+
| ^^^^^ can only be used in path start position
30+
31+
error[E0433]: `self` in paths can only be used in start position
32+
--> $DIR/use-super-in-middle.rs:13:15
33+
|
34+
LL | crate::x::self::super::x::foo();
35+
| ^^^^ can only be used in path start position
36+
37+
error: aborting due to 6 previous errors
38+
39+
For more information about this error, try `rustc --explain E0433`.

0 commit comments

Comments
 (0)