From ee4faf9cd8bf45aaa699b57cc197e4e2cdd6c778 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Fri, 8 Aug 2025 17:47:25 +0200 Subject: [PATCH 1/8] Resolver: Batched import resolution. Collect side effects from the current set of undetermined imports and only apply them at the end. --- compiler/rustc_hir/src/def.rs | 18 ++ compiler/rustc_resolve/src/imports.rs | 198 +++++++++++++----- compiler/rustc_resolve/src/lib.rs | 6 - fail.rs | 30 +++ tests/ui/imports/ambiguous-9.rs | 8 +- tests/ui/imports/ambiguous-9.stderr | 52 ++--- .../ui/imports/glob-conflict-cross-crate-1.rs | 2 +- .../glob-conflict-cross-crate-1.stderr | 16 +- tests/ui/imports/reexports.stderr | 20 +- .../shadowed/shadowed-use-visibility.stderr | 32 +-- 10 files changed, 243 insertions(+), 139 deletions(-) create mode 100644 fail.rs diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 95abe5c40dd43..8b01ecec1a275 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -759,6 +759,24 @@ impl PerNS { pub fn iter(&self) -> IntoIter<&T, 3> { [&self.value_ns, &self.type_ns, &self.macro_ns].into_iter() } + + pub fn into_iter_with(self) -> IntoIter<(Namespace, T), 3> { + [ + (Namespace::TypeNS, self.type_ns), + (Namespace::ValueNS, self.value_ns), + (Namespace::MacroNS, self.macro_ns), + ] + .into_iter() + } + + pub fn iter_with(&self) -> IntoIter<(Namespace, &T), 3> { + [ + (Namespace::TypeNS, &self.type_ns), + (Namespace::ValueNS, &self.value_ns), + (Namespace::MacroNS, &self.macro_ns), + ] + .into_iter() + } } impl ::std::ops::Index for PerNS { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 04eb312a0f8ba..9fc711c240e9f 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1,6 +1,7 @@ //! A bunch of methods and structures more or less related to resolving imports. use std::mem; +use std::ops::Deref; use rustc_ast::NodeId; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; @@ -41,6 +42,96 @@ use crate::{ type Res = def::Res; +struct ImportResolver<'r, 'ra, 'tcx> { + r: CmResolver<'r, 'ra, 'tcx>, // always immutable + outputs: ImportResolutionOutputs<'ra>, +} + +enum SideEffect<'ra> { + None, + Single { import_bindings: PerNS> }, + Glob { import_bindings: Vec<(NameBinding<'ra>, BindingKey, bool /* warn_ambiguity */)> }, +} + +#[derive(Default)] +struct ImportResolutionOutputs<'ra> { + indeterminate_imports: Vec>, + determined_imports: Vec<(Import<'ra>, SideEffect<'ra>)>, +} + +impl<'ra> ImportResolutionOutputs<'ra> { + fn commit<'tcx>(self, r: &mut Resolver<'ra, 'tcx>) { + r.indeterminate_imports = self.indeterminate_imports; + r.determined_imports.reserve(self.determined_imports.len()); + + for (import, side_effect) in self.determined_imports { + r.determined_imports.push(import); + + let parent = import.parent_scope.module; + match (&import.kind, side_effect) { + ( + ImportKind::Single { target, bindings, .. }, + SideEffect::Single { import_bindings }, + ) => { + for (ns, pending_binding) in import_bindings.into_iter_with() { + match pending_binding { + PendingBinding::Ready(Some(binding)) => { + r.define_binding_local(parent, *target, ns, binding); + } + PendingBinding::Ready(None) => { + let key = BindingKey::new(*target, ns); + r.update_local_resolution(parent, key, false, |_, resolution| { + resolution.single_imports.swap_remove(&import); + }); + } + _ => {} + } + bindings[ns].set(pending_binding); + } + } + (ImportKind::Glob { id, .. }, SideEffect::Glob { import_bindings }) => { + let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() + else { + unreachable!(); + }; + + module.glob_importers.borrow_mut(r).push(import); + + for (binding, key, warn_ambiguity) in import_bindings { + let _ = r.try_define_local( + parent, + key.ident.0, + key.ns, + binding, + warn_ambiguity, + ); + } + + r.record_partial_res(*id, PartialRes::new(module.res().unwrap())); + } + + (_, SideEffect::None) => {} + // Something weird happened, which shouldn't have happened. + _ => unreachable!("Mismatched import kind and side effect"), + } + } + } +} + +impl<'r, 'ra, 'tcx> Deref for ImportResolver<'r, 'ra, 'tcx> { + type Target = Resolver<'ra, 'tcx>; + + fn deref(&self) -> &Self::Target { + self.r.deref() + } +} + +impl<'r, 'ra, 'tcx> AsRef> for ImportResolver<'r, 'ra, 'tcx> { + fn as_ref(&self) -> &Resolver<'ra, 'tcx> { + self.r.as_ref() + } +} + /// A [`NameBinding`] in the process of being resolved. #[derive(Clone, Copy, Default, PartialEq)] pub(crate) enum PendingBinding<'ra> { @@ -553,22 +644,34 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Resolves all imports for the crate. This method performs the fixed- /// point iteration. pub(crate) fn resolve_imports(&mut self) { - self.assert_speculative = true; let mut prev_indeterminate_count = usize::MAX; let mut indeterminate_count = self.indeterminate_imports.len() * 3; while indeterminate_count < prev_indeterminate_count { prev_indeterminate_count = indeterminate_count; - indeterminate_count = 0; - for import in mem::take(&mut self.indeterminate_imports) { - let import_indeterminate_count = self.cm().resolve_import(import); - indeterminate_count += import_indeterminate_count; - match import_indeterminate_count { - 0 => self.determined_imports.push(import), - _ => self.indeterminate_imports.push(import), - } + let batch = mem::take(&mut self.indeterminate_imports); + self.assert_speculative = true; + let (outputs, count) = + ImportResolver { r: self.cm(), outputs: Default::default() }.resolve_batch(batch); + self.assert_speculative = false; + indeterminate_count = count; + outputs.commit(self); + } + } + + fn resolve_batch<'r>( + mut self: ImportResolver<'r, 'ra, 'tcx>, + batch: Vec>, + ) -> (ImportResolutionOutputs<'ra>, usize) { + let mut indeterminate_count = 0; + for import in batch { + let (side_effect, import_indeterminate_count) = self.resolve_import(import); + indeterminate_count += import_indeterminate_count; + match import_indeterminate_count { + 0 => self.outputs.determined_imports.push((import, side_effect)), + _ => self.outputs.indeterminate_imports.push(import), } } - self.assert_speculative = false; + (self.outputs, indeterminate_count) } pub(crate) fn finalize_imports(&mut self) { @@ -837,7 +940,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// /// Meanwhile, if resolve successful, the resolved bindings are written /// into the module. - fn resolve_import<'r>(mut self: CmResolver<'r, 'ra, 'tcx>, import: Import<'ra>) -> usize { + fn resolve_import<'r>( + self: &mut ImportResolver<'r, 'ra, 'tcx>, + import: Import<'ra>, + ) -> (SideEffect<'ra>, usize) { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", Segment::names_to_string(&import.module_path), @@ -846,7 +952,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let module = if let Some(module) = import.imported_module.get() { module } else { - let path_res = self.reborrow().maybe_resolve_path( + let path_res = self.r.reborrow().maybe_resolve_path( &import.module_path, None, &import.parent_scope, @@ -855,8 +961,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match path_res { PathResult::Module(module) => module, - PathResult::Indeterminate => return 3, - PathResult::NonModule(..) | PathResult::Failed { .. } => return 0, + PathResult::Indeterminate => return (SideEffect::None, 3), + PathResult::NonModule(..) | PathResult::Failed { .. } => { + return (SideEffect::None, 0); + } } }; @@ -867,16 +975,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { (source, target, bindings, type_ns_only) } ImportKind::Glob { .. } => { - // FIXME: Use mutable resolver directly as a hack, this should be an output of - // speculative resolution. - self.get_mut_unchecked().resolve_glob_import(import); - return 0; + return (self.resolve_glob_import(import), 0); } _ => unreachable!(), }; + let mut import_bindings = PerNS::default(); let mut indeterminate_count = 0; - self.per_ns_cm(|this, ns| { + self.r.reborrow().per_ns_cm(|this, ns| { if !type_ns_only || ns == TypeNS { if bindings[ns].get() != PendingBinding::Pending { return; @@ -888,8 +994,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &import.parent_scope, Some(import), ); - let parent = import.parent_scope.module; - let binding = match binding_result { + let pending_binding = match binding_result { Ok(binding) => { if binding.is_assoc_item() && !this.tcx.features().import_trait_associated_functions() @@ -904,36 +1009,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // We need the `target`, `source` can be extracted. let imported_binding = this.import(binding, import); - // FIXME: Use mutable resolver directly as a hack, this should be an output of - // speculative resolution. - this.get_mut_unchecked().define_binding_local( - parent, - target, - ns, - imported_binding, - ); PendingBinding::Ready(Some(imported_binding)) } Err(Determinacy::Determined) => { // Don't remove underscores from `single_imports`, they were never added. - if target.name != kw::Underscore { - let key = BindingKey::new(target, ns); - // FIXME: Use mutable resolver directly as a hack, this should be an output of - // speculative resolution. - this.get_mut_unchecked().update_local_resolution( - parent, - key, - false, - |_, resolution| { - resolution.single_imports.swap_remove(&import); - }, - ); + if target.name == kw::Underscore { + return; } PendingBinding::Ready(None) } Err(Determinacy::Undetermined) => { indeterminate_count += 1; - PendingBinding::Pending + return; } }; // FIXME(batched): Will be fixed in batched import resolution. @@ -941,7 +1028,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } }); - indeterminate_count + (SideEffect::Single { import_bindings }, indeterminate_count) } /// Performs final import resolution, consistency checks and error reporting. @@ -1484,13 +1571,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { false } - fn resolve_glob_import(&mut self, import: Import<'ra>) { + fn resolve_glob_import<'r>( + self: &mut ImportResolver<'r, 'ra, 'tcx>, + import: Import<'ra>, + ) -> SideEffect<'ra> { // This function is only called for glob imports. - let ImportKind::Glob { id, .. } = import.kind else { unreachable!() }; + let ImportKind::Glob { .. } = import.kind else { unreachable!() }; let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); - return; + return SideEffect::None; }; if module.is_trait() && !self.tcx.features().import_trait_associated_functions() { @@ -1504,12 +1594,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } if module == import.parent_scope.module { - return; + return SideEffect::None; } - // Add to module's glob_importers - module.glob_importers.borrow_mut_unchecked().push(import); - // Ensure that `resolutions` isn't borrowed during `try_define`, // since it might get updated via a glob cycle. let bindings = self @@ -1520,6 +1607,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { resolution.borrow().binding().map(|binding| (*key, binding)) }) .collect::>(); + let mut import_bindings = Vec::with_capacity(bindings.len()); for (mut key, binding) in bindings { let scope = match key.ident.0.span.reverse_glob_adjust(module.expansion, import.span) { Some(Some(def)) => self.expn_def_scope(def), @@ -1532,18 +1620,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .resolution(import.parent_scope.module, key) .and_then(|r| r.binding()) .is_some_and(|binding| binding.warn_ambiguity_recursive()); - let _ = self.try_define_local( - import.parent_scope.module, - key.ident.0, - key.ns, - imported_binding, - warn_ambiguity, - ); + import_bindings.push((imported_binding, key, warn_ambiguity)); } } // Record the destination of this import - self.record_partial_res(id, PartialRes::new(module.res().unwrap())); + SideEffect::Glob { import_bindings } } // Miscellaneous post-processing, including recording re-exports, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b44b1c966a431..1c03f0adbe749 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2569,12 +2569,6 @@ mod ref_mut { true => self.p, } } - - /// Returns a mutable reference to the inner value without checking if - /// it's in a mutable state. - pub(crate) fn get_mut_unchecked(&mut self) -> &mut T { - self.p - } } /// A wrapper around a [`Cell`] that only allows mutation based on a condition in the resolver. diff --git a/fail.rs b/fail.rs new file mode 100644 index 0000000000000..114e05ed76072 --- /dev/null +++ b/fail.rs @@ -0,0 +1,30 @@ +#![no_core] +#![feature(no_core)] +#![allow(internal_features)] +#![feature(lang_items)] + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +mod core_simd { + mod vector { + pub struct Simd {} + } + pub mod simd { + pub use crate::core_simd::vector::*; + } +} + +pub mod simd { + pub use crate::core_simd::simd::*; +} + +mod fail { + use crate::simd::Simd; +} diff --git a/tests/ui/imports/ambiguous-9.rs b/tests/ui/imports/ambiguous-9.rs index c10b1268060ce..cb352668e7599 100644 --- a/tests/ui/imports/ambiguous-9.rs +++ b/tests/ui/imports/ambiguous-9.rs @@ -4,7 +4,7 @@ pub mod dsl { mod range { pub fn date_range() {} } - pub use self::range::*; //~ WARNING ambiguous glob re-exports + pub use self::range::*; use super::prelude::*; } @@ -12,8 +12,8 @@ pub mod prelude { mod t { pub fn date_range() {} } - pub use self::t::*; //~ WARNING ambiguous glob re-exports - pub use super::dsl::*; + pub use self::t::*; + pub use super::dsl::*; //~ WARNING ambiguous glob re-exports } use dsl::*; @@ -23,6 +23,4 @@ fn main() { date_range(); //~^ ERROR `date_range` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //~| ERROR `date_range` is ambiguous - //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-9.stderr b/tests/ui/imports/ambiguous-9.stderr index 800a2e10c9d78..9222f3f99c1e3 100644 --- a/tests/ui/imports/ambiguous-9.stderr +++ b/tests/ui/imports/ambiguous-9.stderr @@ -1,10 +1,10 @@ warning: ambiguous glob re-exports - --> $DIR/ambiguous-9.rs:7:13 + --> $DIR/ambiguous-9.rs:16:13 | -LL | pub use self::range::*; - | ^^^^^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here -LL | use super::prelude::*; - | ----------------- but the name `date_range` in the value namespace is also re-exported here +LL | pub use self::t::*; + | ---------- but the name `date_range` in the value namespace is also re-exported here +LL | pub use super::dsl::*; + | ^^^^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here | = note: `#[warn(ambiguous_glob_reexports)]` on by default @@ -18,10 +18,10 @@ LL | date_range(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `date_range` could refer to the function imported here - --> $DIR/ambiguous-9.rs:7:13 + --> $DIR/ambiguous-9.rs:16:13 | -LL | pub use self::range::*; - | ^^^^^^^^^^^^^^ +LL | pub use super::dsl::*; + | ^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate note: `date_range` could also refer to the function imported here --> $DIR/ambiguous-9.rs:8:9 @@ -35,33 +35,11 @@ warning: ambiguous glob re-exports --> $DIR/ambiguous-9.rs:15:13 | LL | pub use self::t::*; - | ^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here -LL | pub use super::dsl::*; - | ------------- but the name `date_range` in the value namespace is also re-exported here - -error: `date_range` is ambiguous - --> $DIR/ambiguous-9.rs:23:5 - | -LL | date_range(); - | ^^^^^^^^^^ ambiguous name - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: ambiguous because of multiple glob imports of a name in the same module -note: `date_range` could refer to the function imported here - --> $DIR/ambiguous-9.rs:19:5 - | -LL | use dsl::*; - | ^^^^^^ - = help: consider adding an explicit import of `date_range` to disambiguate -note: `date_range` could also refer to the function imported here - --> $DIR/ambiguous-9.rs:20:5 - | -LL | use prelude::*; - | ^^^^^^^^^^ + | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate + = note: `#[deny(ambiguous_glob_imports)]` on by default -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 1 previous error; 1 warning emitted Future incompatibility report: Future breakage diagnostic: error: `date_range` is ambiguous @@ -74,13 +52,13 @@ LL | date_range(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `date_range` could refer to the function imported here - --> $DIR/ambiguous-9.rs:7:13 + --> $DIR/ambiguous-9.rs:16:13 | -LL | pub use self::range::*; - | ^^^^^^^^^^^^^^ +LL | pub use super::dsl::*; + | ^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate note: `date_range` could also refer to the function imported here - --> $DIR/ambiguous-9.rs:8:9 + --> $DIR/ambiguous-9.rs:15:13 | LL | use super::prelude::*; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs index 5f0433d13fcfd..4ea6e131d2400 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -6,7 +6,7 @@ fn main() { glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` //^ FIXME: `glob_conflict::f` should raise an // ambiguity error instead of a not found error. - glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` + glob_conflict::glob::f(); //^ FIXME: `glob_conflict::glob::f` should raise an // ambiguity error instead of a not found error. } diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index 758087107f397..1f1217c25e626 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -3,13 +3,17 @@ error[E0425]: cannot find function `f` in crate `glob_conflict` | LL | glob_conflict::f(); | ^ not found in `glob_conflict` - -error[E0425]: cannot find function `f` in module `glob_conflict::glob` - --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | -LL | glob_conflict::glob::f(); - | ^ not found in `glob_conflict::glob` +help: consider importing this function + | +LL + use glob_conflict::glob::f; + | +help: if you import `f`, refer to it directly + | +LL - glob_conflict::f(); +LL + f(); + | -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr index 0ebcf8e58d627..dec8a60f93ca0 100644 --- a/tests/ui/imports/reexports.stderr +++ b/tests/ui/imports/reexports.stderr @@ -11,16 +11,16 @@ LL | pub use super::foo; | ^^^^^^^^^^ error[E0603]: module import `foo` is private - --> $DIR/reexports.rs:36:22 + --> $DIR/reexports.rs:37:22 | -LL | use crate::b::a::foo::S; +LL | use crate::b::b::foo::S as T; | ^^^ private module import | note: the module import `foo` is defined here... - --> $DIR/reexports.rs:24:17 + --> $DIR/reexports.rs:29:17 | -LL | pub use super::foo; // This is OK since the value `foo` is visible enough. - | ^^^^^^^^^^ +LL | pub use super::*; // This is also OK since the value `foo` is visible enough. + | ^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/reexports.rs:19:5 | @@ -28,16 +28,16 @@ LL | mod foo { | ^^^^^^^ error[E0603]: module import `foo` is private - --> $DIR/reexports.rs:37:22 + --> $DIR/reexports.rs:36:22 | -LL | use crate::b::b::foo::S as T; +LL | use crate::b::a::foo::S; | ^^^ private module import | note: the module import `foo` is defined here... - --> $DIR/reexports.rs:29:17 + --> $DIR/reexports.rs:24:17 | -LL | pub use super::*; // This is also OK since the value `foo` is visible enough. - | ^^^^^^^^ +LL | pub use super::foo; // This is OK since the value `foo` is visible enough. + | ^^^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/reexports.rs:19:5 | diff --git a/tests/ui/shadowed/shadowed-use-visibility.stderr b/tests/ui/shadowed/shadowed-use-visibility.stderr index b062341dc8be8..f3b81fcac99e0 100644 --- a/tests/ui/shadowed/shadowed-use-visibility.stderr +++ b/tests/ui/shadowed/shadowed-use-visibility.stderr @@ -1,31 +1,31 @@ -error[E0603]: module import `bar` is private - --> $DIR/shadowed-use-visibility.rs:9:21 +error[E0603]: module import `f` is private + --> $DIR/shadowed-use-visibility.rs:15:10 | -LL | use crate::foo::bar::f as g; - | ^^^ private module import +LL | use bar::f::f; + | ^ private module import | -note: the module import `bar` is defined here... - --> $DIR/shadowed-use-visibility.rs:4:9 +note: the module import `f` is defined here... + --> $DIR/shadowed-use-visibility.rs:11:9 | -LL | use crate::foo as bar; - | ^^^^^^^^^^^^^^^^^ +LL | use crate::foo as f; + | ^^^^^^^^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/shadowed-use-visibility.rs:1:1 | LL | mod foo { | ^^^^^^^ -error[E0603]: module import `f` is private - --> $DIR/shadowed-use-visibility.rs:15:10 +error[E0603]: module import `bar` is private + --> $DIR/shadowed-use-visibility.rs:9:21 | -LL | use bar::f::f; - | ^ private module import +LL | use crate::foo::bar::f as g; + | ^^^ private module import | -note: the module import `f` is defined here... - --> $DIR/shadowed-use-visibility.rs:11:9 +note: the module import `bar` is defined here... + --> $DIR/shadowed-use-visibility.rs:4:9 | -LL | use crate::foo as f; - | ^^^^^^^^^^^^^^^ +LL | use crate::foo as bar; + | ^^^^^^^^^^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/shadowed-use-visibility.rs:1:1 | From 08235d45648b054ab4a4918a3639aa17353088c2 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Tue, 19 Aug 2025 12:14:06 +0200 Subject: [PATCH 2/8] Several logical changes. --- compiler/rustc_hir/src/def.rs | 18 -- compiler/rustc_resolve/src/imports.rs | 370 +++++++++++++------------- fail.rs | 30 --- 3 files changed, 189 insertions(+), 229 deletions(-) delete mode 100644 fail.rs diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 8b01ecec1a275..95abe5c40dd43 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -759,24 +759,6 @@ impl PerNS { pub fn iter(&self) -> IntoIter<&T, 3> { [&self.value_ns, &self.type_ns, &self.macro_ns].into_iter() } - - pub fn into_iter_with(self) -> IntoIter<(Namespace, T), 3> { - [ - (Namespace::TypeNS, self.type_ns), - (Namespace::ValueNS, self.value_ns), - (Namespace::MacroNS, self.macro_ns), - ] - .into_iter() - } - - pub fn iter_with(&self) -> IntoIter<(Namespace, &T), 3> { - [ - (Namespace::TypeNS, &self.type_ns), - (Namespace::ValueNS, &self.value_ns), - (Namespace::MacroNS, &self.macro_ns), - ] - .into_iter() - } } impl ::std::ops::Index for PerNS { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 9fc711c240e9f..27714f12c444d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1,7 +1,6 @@ //! A bunch of methods and structures more or less related to resolving imports. use std::mem; -use std::ops::Deref; use rustc_ast::NodeId; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; @@ -42,98 +41,30 @@ use crate::{ type Res = def::Res; -struct ImportResolver<'r, 'ra, 'tcx> { - r: CmResolver<'r, 'ra, 'tcx>, // always immutable - outputs: ImportResolutionOutputs<'ra>, -} - -enum SideEffect<'ra> { +/// The the side effect made when resolving the bindings for an underterminate import. +enum SideEffectBindings<'ra> { None, - Single { import_bindings: PerNS> }, - Glob { import_bindings: Vec<(NameBinding<'ra>, BindingKey, bool /* warn_ambiguity */)> }, -} - -#[derive(Default)] -struct ImportResolutionOutputs<'ra> { - indeterminate_imports: Vec>, - determined_imports: Vec<(Import<'ra>, SideEffect<'ra>)>, -} - -impl<'ra> ImportResolutionOutputs<'ra> { - fn commit<'tcx>(self, r: &mut Resolver<'ra, 'tcx>) { - r.indeterminate_imports = self.indeterminate_imports; - r.determined_imports.reserve(self.determined_imports.len()); - - for (import, side_effect) in self.determined_imports { - r.determined_imports.push(import); - - let parent = import.parent_scope.module; - match (&import.kind, side_effect) { - ( - ImportKind::Single { target, bindings, .. }, - SideEffect::Single { import_bindings }, - ) => { - for (ns, pending_binding) in import_bindings.into_iter_with() { - match pending_binding { - PendingBinding::Ready(Some(binding)) => { - r.define_binding_local(parent, *target, ns, binding); - } - PendingBinding::Ready(None) => { - let key = BindingKey::new(*target, ns); - r.update_local_resolution(parent, key, false, |_, resolution| { - resolution.single_imports.swap_remove(&import); - }); - } - _ => {} - } - bindings[ns].set(pending_binding); - } - } - (ImportKind::Glob { id, .. }, SideEffect::Glob { import_bindings }) => { - let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() - else { - unreachable!(); - }; - - module.glob_importers.borrow_mut(r).push(import); - - for (binding, key, warn_ambiguity) in import_bindings { - let _ = r.try_define_local( - parent, - key.ident.0, - key.ns, - binding, - warn_ambiguity, - ); - } - - r.record_partial_res(*id, PartialRes::new(module.res().unwrap())); - } - - (_, SideEffect::None) => {} - // Something weird happened, which shouldn't have happened. - _ => unreachable!("Mismatched import kind and side effect"), - } - } - } -} - -impl<'r, 'ra, 'tcx> Deref for ImportResolver<'r, 'ra, 'tcx> { - type Target = Resolver<'ra, 'tcx>; - - fn deref(&self) -> &Self::Target { - self.r.deref() - } + /// Side effect that should be applied to the field `bindings` of `ImportKind::Single`. + /// + /// The inner `Option` is the actual side effect, it tells us whether we found a binding + /// when resolving the import in this particular namespace. + /// The outer `Option` tells us if this side effect is present. + Single { + import_bindings: PerNS>>>, + }, + Glob { + import_bindings: Vec<(NameBinding<'ra>, BindingKey, bool /* warn_ambiguity */)>, + }, } -impl<'r, 'ra, 'tcx> AsRef> for ImportResolver<'r, 'ra, 'tcx> { - fn as_ref(&self) -> &Resolver<'ra, 'tcx> { - self.r.as_ref() - } +/// The side effect made when resolving an undeterminate import. +struct SideEffect<'ra> { + imported_module: ModuleOrUniformRoot<'ra>, + bindings: SideEffectBindings<'ra>, } /// A [`NameBinding`] in the process of being resolved. -#[derive(Clone, Copy, Default, PartialEq)] +#[derive(Clone, Copy, Default, PartialEq, Debug)] pub(crate) enum PendingBinding<'ra> { Ready(Option>), #[default] @@ -635,11 +566,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Import resolution // - // This is a fixed-point algorithm. We resolve imports until our efforts - // are stymied by an unresolved import; then we bail out of the current - // module and continue. We terminate successfully once no more imports - // remain or unsuccessfully when no forward progress in resolving imports - // is made. + // This is a batched fixed-point algorithm. Each import is resolved in + // isolation, with any side effects collected for later. + // After a full pass over the current set of `indeterminate_imports`, + // the collected side effects are committed together. The process + // repeats until either no imports remain or no further progress can + // be made. /// Resolves all imports for the crate. This method performs the fixed- /// point iteration. @@ -648,30 +580,128 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut indeterminate_count = self.indeterminate_imports.len() * 3; while indeterminate_count < prev_indeterminate_count { prev_indeterminate_count = indeterminate_count; - let batch = mem::take(&mut self.indeterminate_imports); + indeterminate_count = 0; + let mut side_effects = Vec::new(); self.assert_speculative = true; - let (outputs, count) = - ImportResolver { r: self.cm(), outputs: Default::default() }.resolve_batch(batch); + for import in mem::take(&mut self.indeterminate_imports) { + let (side_effect, import_indeterminate_count) = self.cm().resolve_import(import); + indeterminate_count += import_indeterminate_count; + match import_indeterminate_count { + 0 => self.determined_imports.push(import), + _ => self.indeterminate_imports.push(import), + } + if let Some(side_effect) = side_effect { + side_effects.push((import, side_effect)); + } + } self.assert_speculative = false; - indeterminate_count = count; - outputs.commit(self); + self.commit_import_resolutions(side_effects); } } - fn resolve_batch<'r>( - mut self: ImportResolver<'r, 'ra, 'tcx>, - batch: Vec>, - ) -> (ImportResolutionOutputs<'ra>, usize) { - let mut indeterminate_count = 0; - for import in batch { - let (side_effect, import_indeterminate_count) = self.resolve_import(import); - indeterminate_count += import_indeterminate_count; - match import_indeterminate_count { - 0 => self.outputs.determined_imports.push((import, side_effect)), - _ => self.outputs.indeterminate_imports.push(import), + fn commit_import_resolutions( + &mut self, + import_resolutions: Vec<(Import<'ra>, SideEffect<'ra>)>, + ) { + assert!( + !self.assert_speculative, + "`commit_import_resolutions` should not be called during speculative resolution" + ); + self.determined_imports.reserve(self.determined_imports.len()); + for (import, side_effect) in import_resolutions.iter() { + self.determined_imports.push(*import); + let SideEffect { imported_module, .. } = side_effect; + import.imported_module.set_unchecked(Some(*imported_module)); + + if import.is_glob() + && let ModuleOrUniformRoot::Module(module) = imported_module + && import.parent_scope.module != *module + { + module.glob_importers.borrow_mut(self).push(*import); + } + } + + for (import, side_effect) in import_resolutions { + let SideEffect { imported_module, bindings: side_effect_bindings } = side_effect; + let parent = import.parent_scope.module; + + match (&import.kind, side_effect_bindings) { + ( + ImportKind::Single { target, bindings, .. }, + SideEffectBindings::Single { import_bindings }, + ) => { + self.per_ns(|this, ns| { + match import_bindings[ns] { + Some(Some(binding)) => { + if binding.is_assoc_item() + && !this.tcx.features().import_trait_associated_functions() + { + feature_err( + this.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } + this.define_binding_local(parent, *target, ns, binding); + bindings[ns].set_unchecked(PendingBinding::Ready(Some(binding))); + } + Some(None) => { + // Don't remove underscores from `single_imports`, they were never added. + if target.name != kw::Underscore { + let key = BindingKey::new(*target, ns); + this.update_local_resolution( + parent, + key, + false, + |_, resolution| { + resolution.single_imports.swap_remove(&import); + }, + ); + } + bindings[ns].set_unchecked(PendingBinding::Ready(None)); + } + None => {} + } + }); + } + (ImportKind::Glob { id, .. }, SideEffectBindings::Glob { import_bindings }) => { + let ModuleOrUniformRoot::Module(module) = imported_module else { + self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); + continue; + }; + + if module.is_trait() && !self.tcx.features().import_trait_associated_functions() + { + feature_err( + self.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } + + for (binding, key, warn_ambiguity) in import_bindings { + let _ = self.try_define_local( + parent, + key.ident.0, + key.ns, + binding, + warn_ambiguity, + ); + } + + self.record_partial_res(*id, PartialRes::new(module.res().unwrap())); + } + + (_, SideEffectBindings::None) => {} + + // Something weird happened, which shouldn't have happened. + _ => unreachable!("Mismatched import kind and side effect"), } } - (self.outputs, indeterminate_count) } pub(crate) fn finalize_imports(&mut self) { @@ -938,12 +968,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// - `0` means its resolution is determined. /// - Other values mean that indeterminate exists under certain namespaces. /// - /// Meanwhile, if resolve successful, the resolved bindings are written - /// into the module. + /// Meanwhile, if resolution is successful, the side effect of the resolution is returned. fn resolve_import<'r>( - self: &mut ImportResolver<'r, 'ra, 'tcx>, + self: &mut CmResolver<'r, 'ra, 'tcx>, import: Import<'ra>, - ) -> (SideEffect<'ra>, usize) { + ) -> (Option>, usize) { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", Segment::names_to_string(&import.module_path), @@ -952,7 +981,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let module = if let Some(module) = import.imported_module.get() { module } else { - let path_res = self.r.reborrow().maybe_resolve_path( + let path_res = self.reborrow().maybe_resolve_path( &import.module_path, None, &import.parent_scope, @@ -961,28 +990,32 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match path_res { PathResult::Module(module) => module, - PathResult::Indeterminate => return (SideEffect::None, 3), + PathResult::Indeterminate => return (None, 3), PathResult::NonModule(..) | PathResult::Failed { .. } => { - return (SideEffect::None, 0); + return (None, 0); } } }; - // FIXME(batched): Will be fixed in batched import resolution. - import.imported_module.set_unchecked(Some(module)); - let (source, target, bindings, type_ns_only) = match import.kind { + let (source, _, bindings, type_ns_only) = match import.kind { ImportKind::Single { source, target, ref bindings, type_ns_only, .. } => { (source, target, bindings, type_ns_only) } ImportKind::Glob { .. } => { - return (self.resolve_glob_import(import), 0); + return ( + Some(SideEffect { + imported_module: module, + bindings: self.resolve_glob_import(import, module), + }), + 0, + ); } _ => unreachable!(), }; let mut import_bindings = PerNS::default(); let mut indeterminate_count = 0; - self.r.reborrow().per_ns_cm(|this, ns| { + self.reborrow().per_ns_cm(|this, ns| { if !type_ns_only || ns == TypeNS { if bindings[ns].get() != PendingBinding::Pending { return; @@ -996,39 +1029,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ); let pending_binding = match binding_result { Ok(binding) => { - if binding.is_assoc_item() - && !this.tcx.features().import_trait_associated_functions() - { - feature_err( - this.tcx.sess, - sym::import_trait_associated_functions, - import.span, - "`use` associated items of traits is unstable", - ) - .emit(); - } // We need the `target`, `source` can be extracted. let imported_binding = this.import(binding, import); - PendingBinding::Ready(Some(imported_binding)) - } - Err(Determinacy::Determined) => { - // Don't remove underscores from `single_imports`, they were never added. - if target.name == kw::Underscore { - return; - } - PendingBinding::Ready(None) + Some(Some(imported_binding)) } + Err(Determinacy::Determined) => Some(None), Err(Determinacy::Undetermined) => { indeterminate_count += 1; - return; + None } }; // FIXME(batched): Will be fixed in batched import resolution. - bindings[ns].set_unchecked(binding); + import_bindings[ns] = pending_binding; } }); - (SideEffect::Single { import_bindings }, indeterminate_count) + ( + Some(SideEffect { + imported_module: module, + bindings: SideEffectBindings::Single { import_bindings }, + }), + indeterminate_count, + ) } /// Performs final import resolution, consistency checks and error reporting. @@ -1572,60 +1594,46 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn resolve_glob_import<'r>( - self: &mut ImportResolver<'r, 'ra, 'tcx>, + self: &mut CmResolver<'r, 'ra, 'tcx>, import: Import<'ra>, - ) -> SideEffect<'ra> { + imported_module: ModuleOrUniformRoot<'ra>, + ) -> SideEffectBindings<'ra> { // This function is only called for glob imports. let ImportKind::Glob { .. } = import.kind else { unreachable!() }; - let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { - self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); - return SideEffect::None; + let ModuleOrUniformRoot::Module(module) = imported_module else { + return SideEffectBindings::None; }; - if module.is_trait() && !self.tcx.features().import_trait_associated_functions() { - feature_err( - self.tcx.sess, - sym::import_trait_associated_functions, - import.span, - "`use` associated items of traits is unstable", - ) - .emit(); - } - if module == import.parent_scope.module { - return SideEffect::None; + return SideEffectBindings::None; } - // Ensure that `resolutions` isn't borrowed during `try_define`, - // since it might get updated via a glob cycle. - let bindings = self + let import_bindings = self .resolutions(module) .borrow() .iter() .filter_map(|(key, resolution)| { - resolution.borrow().binding().map(|binding| (*key, binding)) + let binding = resolution.borrow().binding()?; + let mut key = *key; + let scope = + match key.ident.0.span.reverse_glob_adjust(module.expansion, import.span) { + Some(Some(def)) => self.expn_def_scope(def), + Some(None) => import.parent_scope.module, + None => return None, + }; + self.is_accessible_from(binding.vis, scope).then(|| { + let imported_binding = self.import(binding, import); + let warn_ambiguity = self + .resolution(import.parent_scope.module, key) + .and_then(|r| r.binding()) + .is_some_and(|binding| binding.warn_ambiguity_recursive()); + (imported_binding, key, warn_ambiguity) + }) }) .collect::>(); - let mut import_bindings = Vec::with_capacity(bindings.len()); - for (mut key, binding) in bindings { - let scope = match key.ident.0.span.reverse_glob_adjust(module.expansion, import.span) { - Some(Some(def)) => self.expn_def_scope(def), - Some(None) => import.parent_scope.module, - None => continue, - }; - if self.is_accessible_from(binding.vis, scope) { - let imported_binding = self.import(binding, import); - let warn_ambiguity = self - .resolution(import.parent_scope.module, key) - .and_then(|r| r.binding()) - .is_some_and(|binding| binding.warn_ambiguity_recursive()); - import_bindings.push((imported_binding, key, warn_ambiguity)); - } - } - // Record the destination of this import - SideEffect::Glob { import_bindings } + SideEffectBindings::Glob { import_bindings } } // Miscellaneous post-processing, including recording re-exports, diff --git a/fail.rs b/fail.rs deleted file mode 100644 index 114e05ed76072..0000000000000 --- a/fail.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![no_core] -#![feature(no_core)] -#![allow(internal_features)] -#![feature(lang_items)] - -#[lang = "sized"] -pub trait Sized: MetaSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -mod core_simd { - mod vector { - pub struct Simd {} - } - pub mod simd { - pub use crate::core_simd::vector::*; - } -} - -pub mod simd { - pub use crate::core_simd::simd::*; -} - -mod fail { - use crate::simd::Simd; -} From 2043b9c2c3b60686818b3b837793cf88685f6e21 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Wed, 27 Aug 2025 13:50:31 +0200 Subject: [PATCH 3/8] Report glob errors in first phase of commit. --- compiler/rustc_resolve/src/imports.rs | 106 +++++++++++++------------- compiler/rustc_resolve/src/lib.rs | 9 --- tests/ui/imports/ambiguous-9.stderr | 38 +-------- tests/ui/imports/import-loop-2.rs | 4 +- tests/ui/imports/import-loop-2.stderr | 8 +- tests/ui/imports/import4.rs | 4 +- tests/ui/imports/import4.stderr | 8 +- tests/ui/imports/reexports.stderr | 20 ++--- tests/ui/privacy/privacy1.stderr | 24 +++--- 9 files changed, 90 insertions(+), 131 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 27714f12c444d..3a5b830c88a08 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -53,7 +53,7 @@ enum SideEffectBindings<'ra> { import_bindings: PerNS>>>, }, Glob { - import_bindings: Vec<(NameBinding<'ra>, BindingKey, bool /* warn_ambiguity */)>, + import_bindings: Vec<(NameBinding<'ra>, BindingKey)>, }, } @@ -607,17 +607,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { !self.assert_speculative, "`commit_import_resolutions` should not be called during speculative resolution" ); - self.determined_imports.reserve(self.determined_imports.len()); for (import, side_effect) in import_resolutions.iter() { - self.determined_imports.push(*import); let SideEffect { imported_module, .. } = side_effect; import.imported_module.set_unchecked(Some(*imported_module)); - if import.is_glob() - && let ModuleOrUniformRoot::Module(module) = imported_module - && import.parent_scope.module != *module - { - module.glob_importers.borrow_mut(self).push(*import); + if import.is_glob() { + let ModuleOrUniformRoot::Module(module) = imported_module else { + self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); + continue; + }; + if import.parent_scope.module != *module { + module.glob_importers.borrow_mut_unchecked().push(*import); + } } } @@ -668,7 +669,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } (ImportKind::Glob { id, .. }, SideEffectBindings::Glob { import_bindings }) => { let ModuleOrUniformRoot::Module(module) = imported_module else { - self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); continue; }; @@ -683,12 +683,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .emit(); } - for (binding, key, warn_ambiguity) in import_bindings { + for (binding, key) in import_bindings { + let imported_binding = self.import(binding, import); + let warn_ambiguity = self + .resolution(import.parent_scope.module, key) + .and_then(|r| r.binding()) + .is_some_and(|binding| binding.warn_ambiguity_recursive()); let _ = self.try_define_local( parent, key.ident.0, key.ns, - binding, + imported_binding, warn_ambiguity, ); } @@ -970,7 +975,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// /// Meanwhile, if resolution is successful, the side effect of the resolution is returned. fn resolve_import<'r>( - self: &mut CmResolver<'r, 'ra, 'tcx>, + mut self: CmResolver<'r, 'ra, 'tcx>, import: Import<'ra>, ) -> (Option>, usize) { debug!( @@ -1015,12 +1020,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut import_bindings = PerNS::default(); let mut indeterminate_count = 0; - self.reborrow().per_ns_cm(|this, ns| { + + // HACK: Use array of namespaces in the same order as `per_ns_mut`. + // We can't use `per_ns_cm` because of the invariance on CmResolver (RefOrMut). + for ns in [TypeNS, ValueNS, MacroNS] { if !type_ns_only || ns == TypeNS { if bindings[ns].get() != PendingBinding::Pending { - return; + continue; }; - let binding_result = this.reborrow().maybe_resolve_ident_in_module( + let binding_result = self.reborrow().maybe_resolve_ident_in_module( module, source, ns, @@ -1030,7 +1038,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let pending_binding = match binding_result { Ok(binding) => { // We need the `target`, `source` can be extracted. - let imported_binding = this.import(binding, import); + let imported_binding = self.import(binding, import); Some(Some(imported_binding)) } Err(Determinacy::Determined) => Some(None), @@ -1042,8 +1050,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // FIXME(batched): Will be fixed in batched import resolution. import_bindings[ns] = pending_binding; } - }); - + } ( Some(SideEffect { imported_module: module, @@ -1593,47 +1600,40 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { false } - fn resolve_glob_import<'r>( - self: &mut CmResolver<'r, 'ra, 'tcx>, + fn resolve_glob_import( + &self, import: Import<'ra>, imported_module: ModuleOrUniformRoot<'ra>, ) -> SideEffectBindings<'ra> { - // This function is only called for glob imports. - let ImportKind::Glob { .. } = import.kind else { unreachable!() }; + match imported_module { + ModuleOrUniformRoot::Module(module) if module != import.parent_scope.module => { + let import_bindings = self + .resolutions(module) + .borrow() + .iter() + .filter_map(|(key, resolution)| { + let binding = resolution.borrow().binding()?; + let mut key = *key; + let scope = match key + .ident + .0 + .span + .reverse_glob_adjust(module.expansion, import.span) + { + Some(Some(def)) => self.expn_def_scope(def), + Some(None) => import.parent_scope.module, + None => return None, + }; + self.is_accessible_from(binding.vis, scope).then(|| (binding, key)) + }) + .collect::>(); - let ModuleOrUniformRoot::Module(module) = imported_module else { - return SideEffectBindings::None; - }; + SideEffectBindings::Glob { import_bindings } + } - if module == import.parent_scope.module { - return SideEffectBindings::None; + // Errors are reported in `commit_imports_resolutions` + _ => SideEffectBindings::None, } - - let import_bindings = self - .resolutions(module) - .borrow() - .iter() - .filter_map(|(key, resolution)| { - let binding = resolution.borrow().binding()?; - let mut key = *key; - let scope = - match key.ident.0.span.reverse_glob_adjust(module.expansion, import.span) { - Some(Some(def)) => self.expn_def_scope(def), - Some(None) => import.parent_scope.module, - None => return None, - }; - self.is_accessible_from(binding.vis, scope).then(|| { - let imported_binding = self.import(binding, import); - let warn_ambiguity = self - .resolution(import.parent_scope.module, key) - .and_then(|r| r.binding()) - .is_some_and(|binding| binding.warn_ambiguity_recursive()); - (imported_binding, key, warn_ambiguity) - }) - }) - .collect::>(); - - SideEffectBindings::Glob { import_bindings } } // Miscellaneous post-processing, including recording re-exports, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 1c03f0adbe749..c8bdcac1cd2cb 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1841,15 +1841,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { f(self, MacroNS); } - fn per_ns_cm<'r, F: FnMut(&mut CmResolver<'r, 'ra, 'tcx>, Namespace)>( - mut self: CmResolver<'r, 'ra, 'tcx>, - mut f: F, - ) { - f(&mut self, TypeNS); - f(&mut self, ValueNS); - f(&mut self, MacroNS); - } - fn is_builtin_macro(&self, res: Res) -> bool { self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some()) } diff --git a/tests/ui/imports/ambiguous-9.stderr b/tests/ui/imports/ambiguous-9.stderr index 9222f3f99c1e3..6446f2129c60b 100644 --- a/tests/ui/imports/ambiguous-9.stderr +++ b/tests/ui/imports/ambiguous-9.stderr @@ -24,20 +24,12 @@ LL | pub use super::dsl::*; | ^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate note: `date_range` could also refer to the function imported here - --> $DIR/ambiguous-9.rs:8:9 - | -LL | use super::prelude::*; - | ^^^^^^^^^^^^^^^^^ - = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default - -warning: ambiguous glob re-exports --> $DIR/ambiguous-9.rs:15:13 | LL | pub use self::t::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` on by default + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default error: aborting due to 1 previous error; 1 warning emitted @@ -60,32 +52,8 @@ LL | pub use super::dsl::*; note: `date_range` could also refer to the function imported here --> $DIR/ambiguous-9.rs:15:13 | -LL | use super::prelude::*; - | ^^^^^^^^^^^^^^^^^ - = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: -error: `date_range` is ambiguous - --> $DIR/ambiguous-9.rs:23:5 - | -LL | date_range(); - | ^^^^^^^^^^ ambiguous name - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: ambiguous because of multiple glob imports of a name in the same module -note: `date_range` could refer to the function imported here - --> $DIR/ambiguous-9.rs:19:5 - | -LL | use dsl::*; - | ^^^^^^ - = help: consider adding an explicit import of `date_range` to disambiguate -note: `date_range` could also refer to the function imported here - --> $DIR/ambiguous-9.rs:20:5 - | -LL | use prelude::*; - | ^^^^^^^^^^ +LL | pub use self::t::*; + | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default diff --git a/tests/ui/imports/import-loop-2.rs b/tests/ui/imports/import-loop-2.rs index 42f9a07fff389..af5c6509d38b6 100644 --- a/tests/ui/imports/import-loop-2.rs +++ b/tests/ui/imports/import-loop-2.rs @@ -1,9 +1,9 @@ mod a { - pub use crate::b::x; + pub use crate::b::x; //~ ERROR unresolved import `crate::b::x` } mod b { - pub use crate::a::x; //~ ERROR unresolved import `crate::a::x` + pub use crate::a::x; fn main() { let y = x; } } diff --git a/tests/ui/imports/import-loop-2.stderr b/tests/ui/imports/import-loop-2.stderr index 2ef40c4e21829..dfa7cf35eaac2 100644 --- a/tests/ui/imports/import-loop-2.stderr +++ b/tests/ui/imports/import-loop-2.stderr @@ -1,8 +1,8 @@ -error[E0432]: unresolved import `crate::a::x` - --> $DIR/import-loop-2.rs:6:13 +error[E0432]: unresolved import `crate::b::x` + --> $DIR/import-loop-2.rs:2:13 | -LL | pub use crate::a::x; - | ^^^^^^^^^^^ no `x` in `a` +LL | pub use crate::b::x; + | ^^^^^^^^^^^ no `x` in `b` error: aborting due to 1 previous error diff --git a/tests/ui/imports/import4.rs b/tests/ui/imports/import4.rs index f670cc06201c0..76a9887534c34 100644 --- a/tests/ui/imports/import4.rs +++ b/tests/ui/imports/import4.rs @@ -1,4 +1,4 @@ -mod a { pub use crate::b::foo; } -mod b { pub use crate::a::foo; } //~ ERROR unresolved import `crate::a::foo` +mod a { pub use crate::b::foo; } //~ ERROR unresolved import `crate::b::foo` +mod b { pub use crate::a::foo; } fn main() { println!("loop"); } diff --git a/tests/ui/imports/import4.stderr b/tests/ui/imports/import4.stderr index 4faa5f0520a9d..07fdc6a3d0ced 100644 --- a/tests/ui/imports/import4.stderr +++ b/tests/ui/imports/import4.stderr @@ -1,8 +1,8 @@ -error[E0432]: unresolved import `crate::a::foo` - --> $DIR/import4.rs:2:17 +error[E0432]: unresolved import `crate::b::foo` + --> $DIR/import4.rs:1:17 | -LL | mod b { pub use crate::a::foo; } - | ^^^^^^^^^^^^^ no `foo` in `a` +LL | mod a { pub use crate::b::foo; } + | ^^^^^^^^^^^^^ no `foo` in `b` error: aborting due to 1 previous error diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr index dec8a60f93ca0..0ebcf8e58d627 100644 --- a/tests/ui/imports/reexports.stderr +++ b/tests/ui/imports/reexports.stderr @@ -11,16 +11,16 @@ LL | pub use super::foo; | ^^^^^^^^^^ error[E0603]: module import `foo` is private - --> $DIR/reexports.rs:37:22 + --> $DIR/reexports.rs:36:22 | -LL | use crate::b::b::foo::S as T; +LL | use crate::b::a::foo::S; | ^^^ private module import | note: the module import `foo` is defined here... - --> $DIR/reexports.rs:29:17 + --> $DIR/reexports.rs:24:17 | -LL | pub use super::*; // This is also OK since the value `foo` is visible enough. - | ^^^^^^^^ +LL | pub use super::foo; // This is OK since the value `foo` is visible enough. + | ^^^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/reexports.rs:19:5 | @@ -28,16 +28,16 @@ LL | mod foo { | ^^^^^^^ error[E0603]: module import `foo` is private - --> $DIR/reexports.rs:36:22 + --> $DIR/reexports.rs:37:22 | -LL | use crate::b::a::foo::S; +LL | use crate::b::b::foo::S as T; | ^^^ private module import | note: the module import `foo` is defined here... - --> $DIR/reexports.rs:24:17 + --> $DIR/reexports.rs:29:17 | -LL | pub use super::foo; // This is OK since the value `foo` is visible enough. - | ^^^^^^^^^^ +LL | pub use super::*; // This is also OK since the value `foo` is visible enough. + | ^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/reexports.rs:19:5 | diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index 98750cee610e4..3dd4d29f3da0e 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -23,18 +23,6 @@ LL | mod baz { | ^^^^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:147:18 - | -LL | use bar::baz; - | ^^^ private module - | -note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 - | -LL | mod baz { - | ^^^^^^^ - error[E0603]: module `i` is private --> $DIR/privacy1.rs:171:20 | @@ -47,6 +35,18 @@ note: the module `i` is defined here LL | mod i { | ^^^^^ +error[E0603]: module `baz` is private + --> $DIR/privacy1.rs:147:18 + | +LL | use bar::baz; + | ^^^ private module + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:56:5 + | +LL | mod baz { + | ^^^^^^^ + error[E0603]: module `baz` is private --> $DIR/privacy1.rs:110:21 | From 0a23ecc5bc61a5f5214b6039c1a33335f2a37d8b Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Thu, 28 Aug 2025 18:12:02 +0200 Subject: [PATCH 4/8] disallow ambiguous names imported from external crates --- compiler/rustc_resolve/src/imports.rs | 3 +-- tests/ui/imports/ambiguous-2.rs | 3 +-- tests/ui/imports/ambiguous-2.stderr | 19 +++++++++++++++++++ tests/ui/imports/ambiguous-4.rs | 3 +-- tests/ui/imports/ambiguous-4.stderr | 19 +++++++++++++++++++ .../ui/imports/glob-conflict-cross-crate-1.rs | 2 +- .../glob-conflict-cross-crate-1.stderr | 16 ++++++---------- 7 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 tests/ui/imports/ambiguous-2.stderr create mode 100644 tests/ui/imports/ambiguous-4.stderr diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 3a5b830c88a08..4f2f29bbeb83d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1648,8 +1648,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module.for_each_child(self, |this, ident, _, binding| { let res = binding.res().expect_non_local(); - let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity; - if res != def::Res::Err && !error_ambiguity { + if res != def::Res::Err && !binding.is_ambiguity_recursive() { let mut reexport_chain = SmallVec::new(); let mut next_binding = binding; while let NameBindingKind::Import { binding, import, .. } = next_binding.kind { diff --git a/tests/ui/imports/ambiguous-2.rs b/tests/ui/imports/ambiguous-2.rs index 087431485ad62..8615773b2e7d3 100644 --- a/tests/ui/imports/ambiguous-2.rs +++ b/tests/ui/imports/ambiguous-2.rs @@ -1,10 +1,9 @@ -//@ check-pass //@ aux-build: ../ambiguous-1.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1633574396 extern crate ambiguous_1; fn main() { - ambiguous_1::id(); + ambiguous_1::id(); //~ ERROR cannot find function `id` in crate `ambiguous_1` //^ FIXME: `id` should be identified as an ambiguous item. } diff --git a/tests/ui/imports/ambiguous-2.stderr b/tests/ui/imports/ambiguous-2.stderr new file mode 100644 index 0000000000000..f685913ae66e6 --- /dev/null +++ b/tests/ui/imports/ambiguous-2.stderr @@ -0,0 +1,19 @@ +error[E0425]: cannot find function `id` in crate `ambiguous_1` + --> $DIR/ambiguous-2.rs:7:18 + | +LL | ambiguous_1::id(); + | ^^ not found in `ambiguous_1` + | +help: consider importing this function + | +LL + use std::process::id; + | +help: if you import `id`, refer to it directly + | +LL - ambiguous_1::id(); +LL + id(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs index 3a9a14bfb524e..7a79fd8619714 100644 --- a/tests/ui/imports/ambiguous-4.rs +++ b/tests/ui/imports/ambiguous-4.rs @@ -1,9 +1,8 @@ -//@ check-pass //@ aux-build: ../ambiguous-4-extern.rs extern crate ambiguous_4_extern; fn main() { - ambiguous_4_extern::id(); + ambiguous_4_extern::id(); //~ ERROR cannot find function `id` in crate `ambiguous_4_extern` //^ FIXME: `id` should be identified as an ambiguous item. } diff --git a/tests/ui/imports/ambiguous-4.stderr b/tests/ui/imports/ambiguous-4.stderr new file mode 100644 index 0000000000000..08e4c3d01fb61 --- /dev/null +++ b/tests/ui/imports/ambiguous-4.stderr @@ -0,0 +1,19 @@ +error[E0425]: cannot find function `id` in crate `ambiguous_4_extern` + --> $DIR/ambiguous-4.rs:6:25 + | +LL | ambiguous_4_extern::id(); + | ^^ not found in `ambiguous_4_extern` + | +help: consider importing this function + | +LL + use std::process::id; + | +help: if you import `id`, refer to it directly + | +LL - ambiguous_4_extern::id(); +LL + id(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs index 4ea6e131d2400..5f0433d13fcfd 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -6,7 +6,7 @@ fn main() { glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` //^ FIXME: `glob_conflict::f` should raise an // ambiguity error instead of a not found error. - glob_conflict::glob::f(); + glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` //^ FIXME: `glob_conflict::glob::f` should raise an // ambiguity error instead of a not found error. } diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index 1f1217c25e626..758087107f397 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -3,17 +3,13 @@ error[E0425]: cannot find function `f` in crate `glob_conflict` | LL | glob_conflict::f(); | ^ not found in `glob_conflict` + +error[E0425]: cannot find function `f` in module `glob_conflict::glob` + --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | -help: consider importing this function - | -LL + use glob_conflict::glob::f; - | -help: if you import `f`, refer to it directly - | -LL - glob_conflict::f(); -LL + f(); - | +LL | glob_conflict::glob::f(); + | ^ not found in `glob_conflict::glob` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0425`. From c07c81e4bef7e101618cccb34a890b8bff1eb9c0 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Thu, 28 Aug 2025 22:50:17 +0200 Subject: [PATCH 5/8] bless test --- .../shadowed/shadowed-use-visibility.stderr | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/ui/shadowed/shadowed-use-visibility.stderr b/tests/ui/shadowed/shadowed-use-visibility.stderr index f3b81fcac99e0..b062341dc8be8 100644 --- a/tests/ui/shadowed/shadowed-use-visibility.stderr +++ b/tests/ui/shadowed/shadowed-use-visibility.stderr @@ -1,31 +1,31 @@ -error[E0603]: module import `f` is private - --> $DIR/shadowed-use-visibility.rs:15:10 +error[E0603]: module import `bar` is private + --> $DIR/shadowed-use-visibility.rs:9:21 | -LL | use bar::f::f; - | ^ private module import +LL | use crate::foo::bar::f as g; + | ^^^ private module import | -note: the module import `f` is defined here... - --> $DIR/shadowed-use-visibility.rs:11:9 +note: the module import `bar` is defined here... + --> $DIR/shadowed-use-visibility.rs:4:9 | -LL | use crate::foo as f; - | ^^^^^^^^^^^^^^^ +LL | use crate::foo as bar; + | ^^^^^^^^^^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/shadowed-use-visibility.rs:1:1 | LL | mod foo { | ^^^^^^^ -error[E0603]: module import `bar` is private - --> $DIR/shadowed-use-visibility.rs:9:21 +error[E0603]: module import `f` is private + --> $DIR/shadowed-use-visibility.rs:15:10 | -LL | use crate::foo::bar::f as g; - | ^^^ private module import +LL | use bar::f::f; + | ^ private module import | -note: the module import `bar` is defined here... - --> $DIR/shadowed-use-visibility.rs:4:9 +note: the module import `f` is defined here... + --> $DIR/shadowed-use-visibility.rs:11:9 | -LL | use crate::foo as bar; - | ^^^^^^^^^^^^^^^^^ +LL | use crate::foo as f; + | ^^^^^^^^^^^^^^^ note: ...and refers to the module `foo` which is defined here --> $DIR/shadowed-use-visibility.rs:1:1 | From 51f18e4b8a041d625bd879f8c1a612cb083dfd54 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Wed, 8 Oct 2025 16:07:42 +0200 Subject: [PATCH 6/8] revert change in `finalize_resolutions_in` + other small things --- compiler/rustc_resolve/src/imports.rs | 10 +++++----- compiler/rustc_resolve/src/lib.rs | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 4f2f29bbeb83d..84fc31615f2ab 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -342,8 +342,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && (vis == import_vis || max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx))) { - // FIXME(batched): Will be fixed in batched import resolution. - max_vis.set_unchecked(Some(vis.expect_local())) + max_vis.set(Some(vis.expect_local()), self) } self.arenas.alloc_name_binding(NameBindingData { @@ -979,8 +978,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { import: Import<'ra>, ) -> (Option>, usize) { debug!( - "(resolving import for module) resolving import `{}::...` in `{}`", + "(resolving import for module) resolving import `{}::{}` in `{}`", Segment::names_to_string(&import.module_path), + import_kind_to_string(&import.kind), module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()), ); let module = if let Some(module) = import.imported_module.get() { @@ -1047,7 +1047,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None } }; - // FIXME(batched): Will be fixed in batched import resolution. import_bindings[ns] = pending_binding; } } @@ -1648,7 +1647,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module.for_each_child(self, |this, ident, _, binding| { let res = binding.res().expect_non_local(); - if res != def::Res::Err && !binding.is_ambiguity_recursive() { + let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity; + if res != def::Res::Err && !error_ambiguity { let mut reexport_chain = SmallVec::new(); let mut next_binding = binding; while let NameBindingKind::Import { binding, import, .. } = next_binding.kind { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c8bdcac1cd2cb..f3a72540bed3f 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2598,6 +2598,13 @@ mod ref_mut { CmCell(Cell::new(value)) } + pub(crate) fn set<'ra, 'tcx>(&self, val: T, r: &Resolver<'ra, 'tcx>) { + if r.assert_speculative { + panic!() + } + self.0.set(val); + } + pub(crate) fn set_unchecked(&self, val: T) { self.0.set(val); } From 0bd2ce4db07a8eb9e39791dbaec30326b845721c Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Wed, 8 Oct 2025 16:11:41 +0200 Subject: [PATCH 7/8] bless test for green CI --- tests/ui/imports/ambiguous-2.rs | 3 ++- tests/ui/imports/ambiguous-2.stderr | 19 ------------------- tests/ui/imports/ambiguous-4.rs | 3 ++- tests/ui/imports/ambiguous-4.stderr | 19 ------------------- .../ui/imports/glob-conflict-cross-crate-1.rs | 2 +- .../glob-conflict-cross-crate-1.stderr | 16 ++++++++++------ 6 files changed, 15 insertions(+), 47 deletions(-) delete mode 100644 tests/ui/imports/ambiguous-2.stderr delete mode 100644 tests/ui/imports/ambiguous-4.stderr diff --git a/tests/ui/imports/ambiguous-2.rs b/tests/ui/imports/ambiguous-2.rs index 8615773b2e7d3..087431485ad62 100644 --- a/tests/ui/imports/ambiguous-2.rs +++ b/tests/ui/imports/ambiguous-2.rs @@ -1,9 +1,10 @@ +//@ check-pass //@ aux-build: ../ambiguous-1.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1633574396 extern crate ambiguous_1; fn main() { - ambiguous_1::id(); //~ ERROR cannot find function `id` in crate `ambiguous_1` + ambiguous_1::id(); //^ FIXME: `id` should be identified as an ambiguous item. } diff --git a/tests/ui/imports/ambiguous-2.stderr b/tests/ui/imports/ambiguous-2.stderr deleted file mode 100644 index f685913ae66e6..0000000000000 --- a/tests/ui/imports/ambiguous-2.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0425]: cannot find function `id` in crate `ambiguous_1` - --> $DIR/ambiguous-2.rs:7:18 - | -LL | ambiguous_1::id(); - | ^^ not found in `ambiguous_1` - | -help: consider importing this function - | -LL + use std::process::id; - | -help: if you import `id`, refer to it directly - | -LL - ambiguous_1::id(); -LL + id(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs index 7a79fd8619714..3a9a14bfb524e 100644 --- a/tests/ui/imports/ambiguous-4.rs +++ b/tests/ui/imports/ambiguous-4.rs @@ -1,8 +1,9 @@ +//@ check-pass //@ aux-build: ../ambiguous-4-extern.rs extern crate ambiguous_4_extern; fn main() { - ambiguous_4_extern::id(); //~ ERROR cannot find function `id` in crate `ambiguous_4_extern` + ambiguous_4_extern::id(); //^ FIXME: `id` should be identified as an ambiguous item. } diff --git a/tests/ui/imports/ambiguous-4.stderr b/tests/ui/imports/ambiguous-4.stderr deleted file mode 100644 index 08e4c3d01fb61..0000000000000 --- a/tests/ui/imports/ambiguous-4.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0425]: cannot find function `id` in crate `ambiguous_4_extern` - --> $DIR/ambiguous-4.rs:6:25 - | -LL | ambiguous_4_extern::id(); - | ^^ not found in `ambiguous_4_extern` - | -help: consider importing this function - | -LL + use std::process::id; - | -help: if you import `id`, refer to it directly - | -LL - ambiguous_4_extern::id(); -LL + id(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs index 5f0433d13fcfd..4ea6e131d2400 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -6,7 +6,7 @@ fn main() { glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` //^ FIXME: `glob_conflict::f` should raise an // ambiguity error instead of a not found error. - glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` + glob_conflict::glob::f(); //^ FIXME: `glob_conflict::glob::f` should raise an // ambiguity error instead of a not found error. } diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index 758087107f397..1f1217c25e626 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -3,13 +3,17 @@ error[E0425]: cannot find function `f` in crate `glob_conflict` | LL | glob_conflict::f(); | ^ not found in `glob_conflict` - -error[E0425]: cannot find function `f` in module `glob_conflict::glob` - --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | -LL | glob_conflict::glob::f(); - | ^ not found in `glob_conflict::glob` +help: consider importing this function + | +LL + use glob_conflict::glob::f; + | +help: if you import `f`, refer to it directly + | +LL - glob_conflict::f(); +LL + f(); + | -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0425`. From 8f39eee1dcf430d9cbb49e4c5855649964de91e4 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Wed, 8 Oct 2025 17:05:57 +0200 Subject: [PATCH 8/8] bless another test --- .../ui/imports/same-res-ambigious.fail.stderr | 2 +- .../ui/imports/same-res-ambigious.pass.stderr | 20 +++++++++++++++++++ tests/ui/imports/same-res-ambigious.rs | 3 +-- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 tests/ui/imports/same-res-ambigious.pass.stderr diff --git a/tests/ui/imports/same-res-ambigious.fail.stderr b/tests/ui/imports/same-res-ambigious.fail.stderr index dfd7c5a5f94e0..aeeff5f2e2ad8 100644 --- a/tests/ui/imports/same-res-ambigious.fail.stderr +++ b/tests/ui/imports/same-res-ambigious.fail.stderr @@ -1,5 +1,5 @@ error[E0603]: derive macro `Embed` is private - --> $DIR/same-res-ambigious.rs:8:28 + --> $DIR/same-res-ambigious.rs:7:28 | LL | #[derive(ambigious_extern::Embed)] | ^^^^^ private derive macro diff --git a/tests/ui/imports/same-res-ambigious.pass.stderr b/tests/ui/imports/same-res-ambigious.pass.stderr new file mode 100644 index 0000000000000..a1d75a4387f66 --- /dev/null +++ b/tests/ui/imports/same-res-ambigious.pass.stderr @@ -0,0 +1,20 @@ +error[E0603]: derive macro `Embed` is private + --> $DIR/same-res-ambigious.rs:7:28 + | +LL | #[derive(ambigious_extern::Embed)] + | ^^^^^ private derive macro + | +note: the derive macro `Embed` is defined here + --> $DIR/auxiliary/same-res-ambigious-extern.rs:11:9 + | +LL | pub use RustEmbed as Embed; + | ^^^^^^^^^ +help: import `Embed` directly + | +LL - #[derive(ambigious_extern::Embed)] +LL + #[derive(same_res_ambigious_extern_macro::RustEmbed)] + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/same-res-ambigious.rs b/tests/ui/imports/same-res-ambigious.rs index b5c13a15b7c9c..52a40450b942f 100644 --- a/tests/ui/imports/same-res-ambigious.rs +++ b/tests/ui/imports/same-res-ambigious.rs @@ -1,11 +1,10 @@ //@ edition: 2018 //@ revisions: fail pass -//@[pass] check-pass //@[pass] aux-crate: ambigious_extern=same-res-ambigious-extern.rs //@[fail] aux-crate: ambigious_extern=same-res-ambigious-extern-fail.rs // see https://github.com/rust-lang/rust/pull/147196 -#[derive(ambigious_extern::Embed)] //[fail]~ ERROR: derive macro `Embed` is private +#[derive(ambigious_extern::Embed)] //~ ERROR: derive macro `Embed` is private struct Foo{} fn main(){}