diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index b9c945a440f88..9399e2c2db9de 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -86,10 +86,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { let binding = self.arenas.alloc_name_binding(NameBindingData { kind: NameBindingKind::Res(res), - ambiguity, + ambiguity: CmCell::new(ambiguity), // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. - warn_ambiguity: true, - vis, + warn_ambiguity: CmCell::new(true), + vis: CmCell::new(vis), span, expansion, }); @@ -1159,18 +1159,18 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { self.r.potentially_unused_imports.push(import); module.for_each_child_mut(self, |this, ident, ns, binding| { if ns == MacroNS { - let import = if this.r.is_accessible_from(binding.vis, this.parent_scope.module) - { - import - } else { - // FIXME: This branch is used for reporting the `private_macro_use` lint - // and should eventually be removed. - if this.r.macro_use_prelude.contains_key(&ident.name) { - // Do not override already existing entries with compatibility entries. - return; - } - macro_use_import(this, span, true) - }; + let import = + if this.r.is_accessible_from(binding.vis(), this.parent_scope.module) { + import + } else { + // FIXME: This branch is used for reporting the `private_macro_use` lint + // and should eventually be removed. + if this.r.macro_use_prelude.contains_key(&ident.name) { + // Do not override already existing entries with compatibility entries. + return; + } + macro_use_import(this, span, true) + }; let import_binding = this.r.import(binding, import); this.add_macro_use_binding(ident.name, import_binding, span, allow_shadowing); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b0cdfe8ab87dc..e9eadc55a8982 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1338,7 +1338,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } let child_accessible = - accessible && this.is_accessible_from(name_binding.vis, parent_scope.module); + accessible && this.is_accessible_from(name_binding.vis(), parent_scope.module); // do not venture inside inaccessible items of other crates if in_module_is_extern && !child_accessible { @@ -1358,8 +1358,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // #90113: Do not count an inaccessible reexported item as a candidate. if let NameBindingKind::Import { binding, .. } = name_binding.kind - && this.is_accessible_from(binding.vis, parent_scope.module) - && !this.is_accessible_from(name_binding.vis, parent_scope.module) + && this.is_accessible_from(binding.vis(), parent_scope.module) + && !this.is_accessible_from(name_binding.vis(), parent_scope.module) { return; } @@ -2239,7 +2239,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let first = binding == first_binding; let def_span = self.tcx.sess.source_map().guess_head_span(binding.span); let mut note_span = MultiSpan::from_span(def_span); - if !first && binding.vis.is_public() { + if !first && binding.vis().is_public() { let desc = match binding.kind { NameBindingKind::Import { .. } => "re-export", _ => "directly", diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index fe6e5b8e6eb6a..0ab8d2bca1fc0 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -100,7 +100,9 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { if let Some(node_id) = import.id() { r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) } - } else if binding.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) { + } else if binding.ambiguity.get().is_some() + && eff_vis.is_public_at_level(Level::Reexported) + { exported_ambiguities.insert(*binding); } } @@ -126,9 +128,9 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // leading to it into the table. They are used by the `ambiguous_glob_reexports` // lint. For all bindings added to the table this way `is_ambiguity` returns true. let is_ambiguity = - |binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn; + |binding: NameBinding<'ra>, warn: bool| binding.ambiguity.get().is_some() && !warn; let mut parent_id = ParentId::Def(module_id); - let mut warn_ambiguity = binding.warn_ambiguity; + let mut warn_ambiguity = binding.warn_ambiguity.get(); while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind { self.update_import(binding, parent_id); @@ -141,12 +143,12 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { parent_id = ParentId::Import(binding); binding = nested_binding; - warn_ambiguity |= nested_binding.warn_ambiguity; + warn_ambiguity |= nested_binding.warn_ambiguity.get(); } if !is_ambiguity(binding, warn_ambiguity) && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { - self.update_def(def_id, binding.vis.expect_local(), parent_id); + self.update_def(def_id, binding.vis().expect_local(), parent_id); } } } @@ -189,7 +191,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { } fn update_import(&mut self, binding: NameBinding<'ra>, parent_id: ParentId<'ra>) { - let nominal_vis = binding.vis.expect_local(); + let nominal_vis = binding.vis().expect_local(); let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return }; let inherited_eff_vis = self.effective_vis_or_private(parent_id); let tcx = self.r.tcx; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f4a594a4731d2..e768c3d782d74 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1012,7 +1012,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Items and single imports are not shadowable, if we have one, then it's determined. if let Some(binding) = binding { - let accessible = self.is_accessible_from(binding.vis, parent_scope.module); + let accessible = self.is_accessible_from(binding.vis(), parent_scope.module); return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; } @@ -1099,7 +1099,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // shadowing is enabled, see `macro_expanded_macro_export_errors`). if let Some(binding) = binding { return if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted { - let accessible = self.is_accessible_from(binding.vis, parent_scope.module); + let accessible = self.is_accessible_from(binding.vis(), parent_scope.module); if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) } } else { Err(ControlFlow::Break(Undetermined)) @@ -1157,7 +1157,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match result { Err(ControlFlow::Break(Determined) | ControlFlow::Continue(Determined)) => continue, Ok(binding) - if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) => + if !self.is_accessible_from(binding.vis(), glob_import.parent_scope.module) => { continue; } @@ -1188,7 +1188,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return Err(ControlFlow::Continue(Determined)); }; - if !self.is_accessible_from(binding.vis, parent_scope.module) { + if !self.is_accessible_from(binding.vis(), parent_scope.module) { if report_private { self.privacy_errors.push(PrivacyError { ident, @@ -1315,7 +1315,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { Err(Determined) => continue, Ok(binding) - if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) => + if !self + .is_accessible_from(binding.vis(), single_import.parent_scope.module) => { continue; } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 4e0f3db59821f..4ba37475e8ffe 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -298,6 +298,27 @@ fn pub_use_of_private_extern_crate_hack( } } +/// Removes identical import layers from two bindings. +fn remove_same_import<'ra>( + b1: NameBinding<'ra>, + b2: NameBinding<'ra>, +) -> (NameBinding<'ra>, NameBinding<'ra>) { + if let NameBindingKind::Import { import: import1, binding: b1_next } = b1.kind + && let NameBindingKind::Import { import: import2, binding: b2_next } = b2.kind + && import1 == import2 + && b1.warn_ambiguity.get() == b2.warn_ambiguity.get() + { + assert_eq!(b1.ambiguity.get(), b2.ambiguity.get()); + assert!(!b1.warn_ambiguity.get()); + assert_eq!(b1.expansion, b2.expansion); + assert_eq!(b1.span, b2.span); + assert_eq!(b1.vis(), b2.vis()); + remove_same_import(b1_next, b2_next) + } else { + (b1, b2) + } +} + impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Given a binding and an import that resolves to it, /// return the corresponding binding defined by the import. @@ -307,12 +328,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { import: Import<'ra>, ) -> NameBinding<'ra> { let import_vis = import.vis.to_def_id(); - let vis = if binding.vis.is_at_least(import_vis, self.tcx) + let vis = if binding.vis().is_at_least(import_vis, self.tcx) || pub_use_of_private_extern_crate_hack(import, binding).is_some() { import_vis } else { - binding.vis + binding.vis() }; if let ImportKind::Glob { ref max_vis, .. } = import.kind @@ -324,14 +345,82 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.arenas.alloc_name_binding(NameBindingData { kind: NameBindingKind::Import { binding, import }, - ambiguity: None, - warn_ambiguity: false, + ambiguity: CmCell::new(None), + warn_ambiguity: CmCell::new(false), span: import.span, - vis, + vis: CmCell::new(vis), expansion: import.parent_scope.expansion, }) } + /// If `glob_binding` attempts to overwrite `old_glob_binding` in a module, + /// decide which one to keep. + fn select_glob_binding( + &self, + glob_binding: NameBinding<'ra>, + old_glob_binding: NameBinding<'ra>, + warn_ambiguity: bool, + ) -> NameBinding<'ra> { + assert!(glob_binding.is_glob_import()); + assert!(old_glob_binding.is_glob_import()); + assert_ne!(glob_binding, old_glob_binding); + // `best_binding` with a given key in a module may be overwritten in a + // number of cases (all of them can be seen below in the `match` in `try_define_local`), + // all these overwrites will be re-fetched by glob imports importing + // from that module without generating new ambiguities. + // - A glob binding is overwritten by a non-glob binding arriving later. + // - A glob binding is overwritten by its clone after setting ambiguity in it. + // FIXME: avoid this by removing `warn_ambiguity`, or by triggering glob re-fetch + // with the same binding in some way. + // - A glob binding is overwritten by a glob binding re-fetching an + // overwritten binding from other module (the recursive case). + // Here we are detecting all such re-fetches and overwrite old bindings + // with the re-fetched bindings. + // This is probably incorrect in corner cases, and the outdated bindings still get + // propagated to other places and get stuck there, but that's what we have at the moment. + let (deep_binding, old_deep_binding) = remove_same_import(glob_binding, old_glob_binding); + if deep_binding != glob_binding { + // Some import layers have been removed, need to overwrite. + assert_ne!(old_deep_binding, old_glob_binding); + // FIXME: reenable the asserts when `warn_ambiguity` is removed (#149195). + // assert_ne!(old_deep_binding, deep_binding); + // assert!(old_deep_binding.is_glob_import()); + assert!(!deep_binding.is_glob_import()); + if glob_binding.is_ambiguity_recursive() { + glob_binding.warn_ambiguity.set_unchecked(true); + } + glob_binding + } else if glob_binding.res() != old_glob_binding.res() { + old_glob_binding + .ambiguity + .set_unchecked(Some((glob_binding, AmbiguityKind::GlobVsGlob))); + old_glob_binding.warn_ambiguity.set_unchecked(warn_ambiguity); + if warn_ambiguity { + old_glob_binding + } else { + // Need a fresh binding so other glob imports importing it could re-fetch it + // and set their own `warn_ambiguity` to true. + // FIXME: remove this when `warn_ambiguity` is removed (#149195). + self.arenas.alloc_name_binding((*old_glob_binding).clone()) + } + } else if !old_glob_binding.vis().is_at_least(glob_binding.vis(), self.tcx) { + // We are glob-importing the same item but with greater visibility. + old_glob_binding.vis.set_unchecked(glob_binding.vis()); + old_glob_binding + } else if glob_binding.is_ambiguity_recursive() + && !old_glob_binding.is_ambiguity_recursive() + { + // Overwriting a non-ambiguous glob import with an ambiguous glob import. + old_glob_binding + .ambiguity + .set_unchecked(Some((glob_binding, AmbiguityKind::GlobVsGlob))); + old_glob_binding.warn_ambiguity.set_unchecked(true); + old_glob_binding + } else { + old_glob_binding + } + } + /// Define the name or return the existing binding if there is a collision. pub(crate) fn try_define_local( &mut self, @@ -353,38 +442,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }); self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| { if let Some(old_binding) = resolution.best_binding() { + assert_ne!(binding, old_binding); + assert!(!binding.warn_ambiguity.get()); if res == Res::Err && old_binding.res() != Res::Err { // Do not override real bindings with `Res::Err`s from error recovery. return Ok(()); } match (old_binding.is_glob_import(), binding.is_glob_import()) { (true, true) => { - let (glob_binding, old_glob_binding) = (binding, old_binding); - // FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity. - if !binding.is_ambiguity_recursive() - && let NameBindingKind::Import { import: old_import, .. } = - old_glob_binding.kind - && let NameBindingKind::Import { import, .. } = glob_binding.kind - && old_import == import - { - // When imported from the same glob-import statement, we should replace - // `old_glob_binding` with `glob_binding`, regardless of whether - // they have the same resolution or not. - resolution.glob_binding = Some(glob_binding); - } else if res != old_glob_binding.res() { - resolution.glob_binding = Some(this.new_ambiguity_binding( - AmbiguityKind::GlobVsGlob, - old_glob_binding, - glob_binding, - warn_ambiguity, - )); - } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { - // We are glob-importing the same item but with greater visibility. - resolution.glob_binding = Some(glob_binding); - } else if binding.is_ambiguity_recursive() { - resolution.glob_binding = - Some(this.new_warn_ambiguity_binding(glob_binding)); - } + resolution.glob_binding = + Some(this.select_glob_binding(binding, old_binding, warn_ambiguity)); } (old_glob @ true, false) | (old_glob @ false, true) => { let (glob_binding, non_glob_binding) = @@ -393,28 +460,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && non_glob_binding.expansion != LocalExpnId::ROOT && glob_binding.res() != non_glob_binding.res() { - resolution.non_glob_binding = Some(this.new_ambiguity_binding( - AmbiguityKind::GlobVsExpanded, - non_glob_binding, + non_glob_binding + .ambiguity + .set_unchecked(Some((glob_binding, AmbiguityKind::GlobVsExpanded))); + } + resolution.non_glob_binding = Some(non_glob_binding); + + if let Some(old_glob_binding) = resolution.glob_binding + && old_glob_binding != glob_binding + { + resolution.glob_binding = Some(this.select_glob_binding( glob_binding, + old_glob_binding, false, )); - } else { - resolution.non_glob_binding = Some(non_glob_binding); - } - - if let Some(old_glob_binding) = resolution.glob_binding { - assert!(old_glob_binding.is_glob_import()); - if glob_binding.res() != old_glob_binding.res() { - resolution.glob_binding = Some(this.new_ambiguity_binding( - AmbiguityKind::GlobVsGlob, - old_glob_binding, - glob_binding, - false, - )); - } else if !old_glob_binding.vis.is_at_least(binding.vis, this.tcx) { - resolution.glob_binding = Some(glob_binding); - } } else { resolution.glob_binding = Some(glob_binding); } @@ -435,23 +494,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } - fn new_ambiguity_binding( - &self, - ambiguity_kind: AmbiguityKind, - primary_binding: NameBinding<'ra>, - secondary_binding: NameBinding<'ra>, - warn_ambiguity: bool, - ) -> NameBinding<'ra> { - let ambiguity = Some((secondary_binding, ambiguity_kind)); - let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding }; - self.arenas.alloc_name_binding(data) - } - - fn new_warn_ambiguity_binding(&self, binding: NameBinding<'ra>) -> NameBinding<'ra> { - assert!(binding.is_ambiguity_recursive()); - self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding }) - } - // Use `f` to mutate the resolution of the name in the module. // If the resolution becomes a success, define it in the module's glob importers. fn update_local_resolution( @@ -493,7 +535,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(None) => import.parent_scope.module, None => continue, }; - if self.is_accessible_from(binding.vis, scope) { + if self.is_accessible_from(binding.vis(), scope) { let imported_binding = self.import(binding, *import); let _ = self.try_define_local( import.parent_scope.module, @@ -658,7 +700,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let Some(binding) = resolution.best_binding() else { continue }; if let NameBindingKind::Import { import, .. } = binding.kind - && let Some((amb_binding, _)) = binding.ambiguity + && let Some((amb_binding, _)) = binding.ambiguity.get() && binding.res() != Res::Err && exported_ambiguities.contains(&binding) { @@ -685,8 +727,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && let Some(glob_import_id) = glob_import.id() && let glob_import_def_id = self.local_def_id(glob_import_id) && self.effective_visibilities.is_exported(glob_import_def_id) - && glob_binding.vis.is_public() - && !binding.vis.is_public() + && glob_binding.vis().is_public() + && !binding.vis().is_public() { let binding_id = match binding.kind { NameBindingKind::Res(res) => { @@ -1316,9 +1358,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return; }; - if !binding.vis.is_at_least(import.vis, this.tcx) { + if !binding.vis().is_at_least(import.vis, this.tcx) { reexport_error = Some((ns, binding)); - if let Visibility::Restricted(binding_def_id) = binding.vis + if let Visibility::Restricted(binding_def_id) = binding.vis() && binding_def_id.is_top_level_module() { crate_private_reexport = true; @@ -1521,7 +1563,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(None) => import.parent_scope.module, None => continue, }; - if self.is_accessible_from(binding.vis, scope) { + 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) @@ -1563,7 +1605,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let child = |reexport_chain| ModChild { ident: ident.0, res, - vis: binding.vis, + vis: binding.vis(), reexport_chain, }; if let Some((ambig_binding1, ambig_binding2, ambig_kind)) = @@ -1573,7 +1615,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let second = ModChild { ident: ident.0, res: ambig_binding2.res().expect_non_local(), - vis: ambig_binding2.vis, + vis: ambig_binding2.vis(), reexport_chain: ambig_binding2.reexport_chain(this), }; let kind = match ambig_kind { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index f75ac400dc0ba..3e8b2d2288d88 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2799,7 +2799,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { in_module.for_each_child(self.r, |r, ident, _, name_binding| { // abort if the module is already found or if name_binding is private external - if result.is_some() || !name_binding.vis.is_visible_locally() { + if result.is_some() || !name_binding.vis().is_visible_locally() { return; } if let Some(module_def_id) = name_binding.res().module_like_def_id() { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ec030ecf8e13f..9b326b31b8ad4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -798,16 +798,16 @@ impl<'ra> fmt::Debug for Module<'ra> { } /// Records a possibly-private value, type, or module definition. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] struct NameBindingData<'ra> { kind: NameBindingKind<'ra>, - ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>, + ambiguity: CmCell, AmbiguityKind)>>, /// Produce a warning instead of an error when reporting ambiguities inside this binding. /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required. - warn_ambiguity: bool, + warn_ambiguity: CmCell, expansion: LocalExpnId, span: Span, - vis: Visibility, + vis: CmCell>, } /// All name bindings are unique and allocated on a same arena, @@ -923,6 +923,10 @@ struct AmbiguityError<'ra> { } impl<'ra> NameBindingData<'ra> { + fn vis(&self) -> Visibility { + self.vis.get() + } + fn res(&self) -> Res { match self.kind { NameBindingKind::Res(res) => res, @@ -940,7 +944,7 @@ impl<'ra> NameBindingData<'ra> { fn descent_to_ambiguity( self: NameBinding<'ra>, ) -> Option<(NameBinding<'ra>, NameBinding<'ra>, AmbiguityKind)> { - match self.ambiguity { + match self.ambiguity.get() { Some((ambig_binding, ambig_kind)) => Some((self, ambig_binding, ambig_kind)), None => match self.kind { NameBindingKind::Import { binding, .. } => binding.descent_to_ambiguity(), @@ -950,7 +954,7 @@ impl<'ra> NameBindingData<'ra> { } fn is_ambiguity_recursive(&self) -> bool { - self.ambiguity.is_some() + self.ambiguity.get().is_some() || match self.kind { NameBindingKind::Import { binding, .. } => binding.is_ambiguity_recursive(), _ => false, @@ -958,7 +962,7 @@ impl<'ra> NameBindingData<'ra> { } fn warn_ambiguity_recursive(&self) -> bool { - self.warn_ambiguity + self.warn_ambiguity.get() || match self.kind { NameBindingKind::Import { binding, .. } => binding.warn_ambiguity_recursive(), _ => false, @@ -1349,9 +1353,9 @@ impl<'ra> ResolverArenas<'ra> { ) -> NameBinding<'ra> { self.alloc_name_binding(NameBindingData { kind: NameBindingKind::Res(res), - ambiguity: None, - warn_ambiguity: false, - vis, + ambiguity: CmCell::new(None), + warn_ambiguity: CmCell::new(false), + vis: CmCell::new(vis), span, expansion, }) @@ -2055,7 +2059,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'ra>, used: Used) { - self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity); + self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity.get()); } fn record_use_inner( @@ -2065,7 +2069,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { used: Used, warn_ambiguity: bool, ) { - if let Some((b2, kind)) = used_binding.ambiguity { + if let Some((b2, kind)) = used_binding.ambiguity.get() { let ambiguity_error = AmbiguityError { kind, ident, @@ -2126,7 +2130,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, binding, Used::Other, - warn_ambiguity || binding.warn_ambiguity, + warn_ambiguity || binding.warn_ambiguity.get(), ); } } diff --git a/tests/ui/imports/ambiguous-14.stderr b/tests/ui/imports/ambiguous-14.stderr index 4efa31c61e328..2a3557c31f120 100644 --- a/tests/ui/imports/ambiguous-14.stderr +++ b/tests/ui/imports/ambiguous-14.stderr @@ -8,15 +8,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:13:13 + --> $DIR/ambiguous-14.rs:18:13 | LL | pub use a::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:14:13 + --> $DIR/ambiguous-14.rs:19:13 | -LL | pub use b::*; +LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default @@ -34,15 +34,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:13:13 + --> $DIR/ambiguous-14.rs:18:13 | LL | pub use a::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:14:13 + --> $DIR/ambiguous-14.rs:19:13 | -LL | pub use b::*; +LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default diff --git a/tests/ui/imports/duplicate.stderr b/tests/ui/imports/duplicate.stderr index 5cd3b0c2c8a55..74829fc21e22f 100644 --- a/tests/ui/imports/duplicate.stderr +++ b/tests/ui/imports/duplicate.stderr @@ -78,15 +78,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:24:13 + --> $DIR/duplicate.rs:29:13 | LL | pub use crate::a::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:25:13 + --> $DIR/duplicate.rs:30:13 | -LL | pub use crate::b::*; +LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default @@ -106,15 +106,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:24:13 + --> $DIR/duplicate.rs:29:13 | LL | pub use crate::a::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:25:13 + --> $DIR/duplicate.rs:30:13 | -LL | pub use crate::b::*; +LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default diff --git a/tests/ui/imports/issue-55884-1.rs b/tests/ui/imports/issue-55884-1.rs index 21744aa5d7bfa..3c9c033c158e1 100644 --- a/tests/ui/imports/issue-55884-1.rs +++ b/tests/ui/imports/issue-55884-1.rs @@ -17,5 +17,5 @@ mod m { fn main() { use m::S; //~ ERROR `S` is ambiguous - let s = S {}; + let s = S {}; //~ ERROR `S` is ambiguous } diff --git a/tests/ui/imports/issue-55884-1.stderr b/tests/ui/imports/issue-55884-1.stderr index ae8edb0495647..a0b63ddc91081 100644 --- a/tests/ui/imports/issue-55884-1.stderr +++ b/tests/ui/imports/issue-55884-1.stderr @@ -18,6 +18,26 @@ LL | pub use self::m2::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `S` to disambiguate -error: aborting due to 1 previous error +error[E0659]: `S` is ambiguous + --> $DIR/issue-55884-1.rs:20:13 + | +LL | let s = S {}; + | ^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `S` could refer to the struct imported here + --> $DIR/issue-55884-1.rs:14:13 + | +LL | pub use self::m1::*; + | ^^^^^^^^^^^ + = help: consider adding an explicit import of `S` to disambiguate +note: `S` could also refer to the struct imported here + --> $DIR/issue-55884-1.rs:15:13 + | +LL | pub use self::m2::*; + | ^^^^^^^^^^^ + = help: consider adding an explicit import of `S` to disambiguate + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`.