Check importing crate/$crate/super after handling self

This commit is contained in:
mu001999
2026-02-23 09:48:22 +08:00
parent c78a29473a
commit 5cfaadaa50
3 changed files with 86 additions and 35 deletions
@@ -629,6 +629,35 @@ fn build_reduced_graph_for_use_tree(
// `true` for `...::{self [as target]}` imports, `false` otherwise.
let type_ns_only = nested && source.ident.name == kw::SelfLower;
if source.ident.name == kw::SelfLower
&& let Some(parent) = module_path.pop()
{
// Suggest `use prefix::{self};` for `use prefix::self;`
if !type_ns_only
&& (parent.ident.name != kw::PathRoot
|| self.r.path_root_is_crate_root(parent.ident))
{
let span_with_rename = match rename {
Some(rename) => source.ident.span.to(rename.span),
None => source.ident.span,
};
self.r.report_error(
parent.ident.span.shrink_to_hi().to(source.ident.span),
ResolutionError::SelfImportsOnlyAllowedWithin {
root: parent.ident.name == kw::PathRoot,
span_with_rename,
},
);
}
let self_span = source.ident.span;
source = parent;
if rename.is_none() {
ident = Ident::new(source.ident.name, self_span);
}
}
match source.ident.name {
kw::DollarCrate => {
if !module_path.is_empty() {
@@ -664,45 +693,14 @@ fn build_reduced_graph_for_use_tree(
return;
}
}
kw::SelfLower => {
if let Some(parent) = module_path.pop() {
// Suggest `use prefix::{self};` for `use prefix::self;`
if !type_ns_only
&& (parent.ident.name != kw::PathRoot
|| self.r.path_root_is_crate_root(parent.ident))
{
let span_with_rename = match rename {
Some(rename) => source.ident.span.to(rename.span),
None => source.ident.span,
};
self.r.report_error(
parent.ident.span.shrink_to_hi().to(source.ident.span),
ResolutionError::SelfImportsOnlyAllowedWithin {
root: parent.ident.name == kw::PathRoot,
span_with_rename,
},
);
}
let self_span = source.ident.span;
source = parent;
if rename.is_none() {
ident = Ident::new(source.ident.name, self_span);
}
}
// Deny `use ::{self};` after edition 2015
kw::PathRoot if !self.r.path_root_is_crate_root(source.ident) => {
self.r.dcx().span_err(use_tree.span, "extern prelude cannot be imported");
return;
}
_ => {}
}
// Deny `use ::{self};` after edition 2015
if source.ident.name == kw::PathRoot
&& !self.r.path_root_is_crate_root(source.ident)
{
self.r.dcx().span_err(use_tree.span, "extern prelude cannot be imported");
return;
}
// Deny importing path-kw without renaming
if rename.is_none() && ident.is_path_segment_keyword() {
let ident = use_tree.ident();
+14
View File
@@ -0,0 +1,14 @@
pub mod x {
pub use crate::x::super::{self as crate1}; //~ ERROR `super` in paths can only be used in start position
pub use crate::x::self::super::{self as crate2}; //~ ERROR `super` in paths can only be used in start position
pub fn foo() {}
}
fn main() {
x::crate1::x::foo(); //~ ERROR cannot find `crate1` in `x`
x::crate2::x::foo(); //~ ERROR cannot find `crate2` in `x`
crate::x::super::x::foo(); //~ ERROR `super` in paths can only be used in start position
crate::x::self::super::x::foo(); //~ ERROR `self` in paths can only be used in start position
}
+39
View File
@@ -0,0 +1,39 @@
error: `super` in paths can only be used in start position, after `self`, or after another `super`
--> $DIR/use-super-in-middle.rs:2:23
|
LL | pub use crate::x::super::{self as crate1};
| ^^^^^
error: `super` in paths can only be used in start position, after `self`, or after another `super`
--> $DIR/use-super-in-middle.rs:3:29
|
LL | pub use crate::x::self::super::{self as crate2};
| ^^^^^
error[E0433]: cannot find `crate1` in `x`
--> $DIR/use-super-in-middle.rs:9:8
|
LL | x::crate1::x::foo();
| ^^^^^^ could not find `crate1` in `x`
error[E0433]: cannot find `crate2` in `x`
--> $DIR/use-super-in-middle.rs:10:8
|
LL | x::crate2::x::foo();
| ^^^^^^ could not find `crate2` in `x`
error[E0433]: `super` in paths can only be used in start position
--> $DIR/use-super-in-middle.rs:12:15
|
LL | crate::x::super::x::foo();
| ^^^^^ can only be used in path start position
error[E0433]: `self` in paths can only be used in start position
--> $DIR/use-super-in-middle.rs:13:15
|
LL | crate::x::self::super::x::foo();
| ^^^^ can only be used in path start position
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0433`.