diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 2438b3a38ed..08b73ebb694 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -9,12 +9,9 @@ use crate::def_collector::collect_definitions; use crate::imports::{Import, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; -use crate::{ - errors, Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot, -}; -use crate::{ - MacroData, NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError, -}; +use crate::{errors, BindingKey, MacroData}; +use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError}; use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; @@ -72,7 +69,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { T: ToNameBinding<'a>, { let binding = def.to_name_binding(self.arenas); - let key = self.new_key(ident, ns); + let key = self.new_disambiguated_key(ident, ns); if let Err(old_binding) = self.try_define(parent, key, binding) { self.report_conflict(parent, ident, ns, old_binding, &binding); } @@ -379,7 +376,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { ImportKind::Single { target, type_ns_only, .. } => { self.r.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { - let key = this.new_key(target, ns); + let key = BindingKey::new(target, ns); let mut resolution = this.resolution(current_module, key).borrow_mut(); resolution.add_single_import(import); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 59eda9db97f..3ed7580af05 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -28,10 +28,10 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::ThinVec; -use crate::errors as errs; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; +use crate::{errors as errs, BindingKey}; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize}; use crate::{HasGenericParams, MacroRulesScope, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{LexicalScopeBinding, NameBinding, NameBindingKind, PrivacyError, VisResolutionError}; @@ -2081,7 +2081,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let resolutions = self.resolutions(crate_module).borrow(); - let resolution = resolutions.get(&self.new_key(ident, MacroNS))?; + let binding_key = BindingKey::new(ident, MacroNS); + let resolution = resolutions.get(&binding_key)?; let binding = resolution.borrow().binding()?; if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { let module_name = crate_module.kind.name().unwrap(); diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f065c4ddd2e..945c7ce3a9b 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -18,6 +18,7 @@ use crate::late::{ ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind, }; use crate::macros::{sub_namespace_match, MacroRulesScope}; +use crate::BindingKey; use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize}; use crate::{Import, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res}; @@ -865,7 +866,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } }; - let key = self.new_key(ident, ns); + let key = BindingKey::new(ident, ns); let resolution = self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 9e4429507b1..0e90703faec 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -415,7 +415,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let dummy_binding = self.dummy_binding; let dummy_binding = self.import(dummy_binding, import); self.per_ns(|this, ns| { - let key = this.new_key(target, ns); + let key = BindingKey::new(target, ns); let _ = this.try_define(import.parent_scope.module, key, dummy_binding); }); self.record_use(target, dummy_binding, false); @@ -712,7 +712,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .span_label(import.span, "cannot be imported directly") .emit(); } - let key = this.new_key(target, ns); + let key = BindingKey::new(target, ns); this.update_resolution(parent, key, |_, resolution| { resolution.single_imports.remove(&Interned::new_unchecked(import)); }); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c053ea222a0..a1077615d95 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -6,6 +6,7 @@ //! If you wonder why there's no `early.rs`, that's because it's split into three files - //! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`. +use crate::BindingKey; use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding}; use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult}; use crate::{ResolutionError, Resolver, Segment, UseError}; @@ -2967,7 +2968,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // If there is a TraitRef in scope for an impl, then the method must be in the trait. let Some((module, _)) = &self.current_trait_ref else { return; }; ident.span.normalize_to_macros_2_0_and_adjust(module.expansion); - let key = self.r.new_key(ident, ns); + let key = BindingKey::new(ident, ns); let mut binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding); debug!(?binding); if binding.is_none() { @@ -2978,7 +2979,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { TypeNS => ValueNS, _ => ns, }; - let key = self.r.new_key(ident, ns); + let key = BindingKey::new(ident, ns); binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding); debug!(?binding); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 323b78fcd98..14a3671c01d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -469,6 +469,13 @@ struct BindingKey { disambiguator: u32, } +impl BindingKey { + fn new(ident: Ident, ns: Namespace) -> Self { + let ident = ident.normalize_to_macros_2_0(); + BindingKey { ident, ns, disambiguator: 0 } + } +} + type Resolutions<'a> = RefCell>>>; /// One node in the tree of modules. @@ -943,6 +950,7 @@ pub struct Resolver<'a, 'tcx> { empty_module: Module<'a>, module_map: FxHashMap>, binding_parent_modules: FxHashMap>, Module<'a>>, + underscore_disambiguator: u32, /// Maps glob imports to the names of items actually imported. @@ -1595,7 +1603,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { import_ids } - fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey { + fn new_disambiguated_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey { let ident = ident.normalize_to_macros_2_0(); let disambiguator = if ident.name == kw::Underscore { self.underscore_disambiguator += 1; diff --git a/tests/ui/underscore-imports/issue-110164.rs b/tests/ui/underscore-imports/issue-110164.rs new file mode 100644 index 00000000000..6fd13414500 --- /dev/null +++ b/tests/ui/underscore-imports/issue-110164.rs @@ -0,0 +1,19 @@ +use self::*; +//~^ ERROR unresolved import `self::*` +use crate::*; +//~^ ERROR unresolved import `crate::*` +use _::a; +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR unresolved import `_` +use _::*; +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR unresolved import `_` + +fn main() { + use _::a; + //~^ ERROR expected identifier, found reserved identifier `_` + //~| ERROR unresolved import `_` + use _::*; + //~^ ERROR expected identifier, found reserved identifier `_` + //~| ERROR unresolved import `_` +} diff --git a/tests/ui/underscore-imports/issue-110164.stderr b/tests/ui/underscore-imports/issue-110164.stderr new file mode 100644 index 00000000000..5016c41e8a5 --- /dev/null +++ b/tests/ui/underscore-imports/issue-110164.stderr @@ -0,0 +1,71 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-110164.rs:5:5 + | +LL | use _::a; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-110164.rs:8:5 + | +LL | use _::*; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-110164.rs:13:9 + | +LL | use _::a; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-110164.rs:16:9 + | +LL | use _::*; + | ^ expected identifier, found reserved identifier + +error[E0432]: unresolved import `self::*` + --> $DIR/issue-110164.rs:1:5 + | +LL | use self::*; + | ^^^^^^^ cannot glob-import a module into itself + +error[E0432]: unresolved import `crate::*` + --> $DIR/issue-110164.rs:3:5 + | +LL | use crate::*; + | ^^^^^^^^ cannot glob-import a module into itself + +error[E0432]: unresolved import `_` + --> $DIR/issue-110164.rs:8:5 + | +LL | use _::*; + | ^ maybe a missing crate `_`? + | + = help: consider adding `extern crate _` to use the `_` crate + +error[E0432]: unresolved import `_` + --> $DIR/issue-110164.rs:5:5 + | +LL | use _::a; + | ^ maybe a missing crate `_`? + | + = help: consider adding `extern crate _` to use the `_` crate + +error[E0432]: unresolved import `_` + --> $DIR/issue-110164.rs:13:9 + | +LL | use _::a; + | ^ maybe a missing crate `_`? + | + = help: consider adding `extern crate _` to use the `_` crate + +error[E0432]: unresolved import `_` + --> $DIR/issue-110164.rs:16:9 + | +LL | use _::*; + | ^ maybe a missing crate `_`? + | + = help: consider adding `extern crate _` to use the `_` crate + +error: aborting due to 10 previous errors + +For more information about this error, try `rustc --explain E0432`.