resolve: Update NameBindingData::warn_ambiguity in place

instead of creating fresh bindings.
This commit is contained in:
Vadim Petrochenkov 2025-12-29 22:12:56 +03:00
parent e454835eef
commit 32cf3a96d7
4 changed files with 16 additions and 23 deletions

View file

@ -91,7 +91,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
kind: DeclKind::Def(res),
ambiguity,
// External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment.
warn_ambiguity: true,
warn_ambiguity: CmCell::new(true),
vis,
span,
expansion,

View file

@ -127,7 +127,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
// lint. For all bindings added to the table this way `is_ambiguity` returns true.
let is_ambiguity = |decl: Decl<'ra>, warn: bool| decl.ambiguity.is_some() && !warn;
let mut parent_id = ParentId::Def(module_id);
let mut warn_ambiguity = decl.warn_ambiguity;
let mut warn_ambiguity = decl.warn_ambiguity.get();
while let DeclKind::Import { source_decl, .. } = decl.kind {
self.update_import(decl, parent_id);
@ -140,7 +140,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
parent_id = ParentId::Import(decl);
decl = source_decl;
warn_ambiguity |= source_decl.warn_ambiguity;
warn_ambiguity |= source_decl.warn_ambiguity.get();
}
if !is_ambiguity(decl, warn_ambiguity)
&& let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local())

View file

@ -303,7 +303,7 @@ fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra
&& d1.ambiguity == d2.ambiguity
{
assert!(d1.ambiguity.is_none());
assert_eq!(d1.warn_ambiguity, d2.warn_ambiguity);
assert_eq!(d1.warn_ambiguity.get(), d2.warn_ambiguity.get());
assert_eq!(d1.expansion, d2.expansion);
assert_eq!(d1.span, d2.span);
assert_eq!(d1.vis, d2.vis);
@ -336,7 +336,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.arenas.alloc_decl(DeclData {
kind: DeclKind::Import { source_decl: decl, import },
ambiguity: None,
warn_ambiguity: false,
warn_ambiguity: CmCell::new(false),
span: import.span,
vis,
expansion: import.parent_scope.expansion,
@ -362,9 +362,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// - A glob decl is overwritten by an ambiguous glob decl.
// FIXME: avoid this by putting `DeclData::ambiguity` under a
// cell and updating it in place.
// - A glob decl is overwritten by the same decl with `warn_ambiguity == true`.
// FIXME: avoid this by putting `DeclData::warn_ambiguity` under a
// cell and updating it in place.
// - A glob decl is overwritten by a glob decl with larger visibility.
// FIXME: avoid this by putting `DeclData::vis` under a cell
// and updating it in place.
@ -381,10 +378,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
assert_ne!(old_deep_decl, deep_decl);
assert!(old_deep_decl.is_glob_import());
if glob_decl.is_ambiguity_recursive() {
self.new_decl_with_warn_ambiguity(glob_decl)
} else {
glob_decl
glob_decl.warn_ambiguity.set_unchecked(true);
}
glob_decl
} else if glob_decl.res() != old_glob_decl.res() {
self.new_decl_with_ambiguity(old_glob_decl, glob_decl, warn_ambiguity)
} else if !old_glob_decl.vis.is_at_least(glob_decl.vis, self.tcx) {
@ -392,7 +388,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
glob_decl
} else if glob_decl.is_ambiguity_recursive() {
// Overwriting with an ambiguous glob import.
self.new_decl_with_warn_ambiguity(glob_decl)
glob_decl.warn_ambiguity.set_unchecked(true);
glob_decl
} else {
old_glob_decl
}
@ -466,15 +463,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
warn_ambiguity: bool,
) -> Decl<'ra> {
let ambiguity = Some(secondary_decl);
let warn_ambiguity = CmCell::new(warn_ambiguity);
let data = DeclData { ambiguity, warn_ambiguity, ..*primary_decl };
self.arenas.alloc_decl(data)
}
fn new_decl_with_warn_ambiguity(&self, decl: Decl<'ra>) -> Decl<'ra> {
assert!(decl.is_ambiguity_recursive());
self.arenas.alloc_decl(DeclData { warn_ambiguity: true, ..*decl })
}
// 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<T, F>(

View file

@ -802,13 +802,13 @@ impl<'ra> fmt::Debug for Module<'ra> {
}
/// Data associated with any name declaration.
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct DeclData<'ra> {
kind: DeclKind<'ra>,
ambiguity: Option<Decl<'ra>>,
/// 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<bool>,
expansion: LocalExpnId,
span: Span,
vis: Visibility<DefId>,
@ -956,7 +956,7 @@ impl<'ra> DeclData<'ra> {
}
fn warn_ambiguity_recursive(&self) -> bool {
self.warn_ambiguity
self.warn_ambiguity.get()
|| match self.kind {
DeclKind::Import { source_decl, .. } => source_decl.warn_ambiguity_recursive(),
_ => false,
@ -1343,7 +1343,7 @@ impl<'ra> ResolverArenas<'ra> {
self.alloc_decl(DeclData {
kind: DeclKind::Def(res),
ambiguity: None,
warn_ambiguity: false,
warn_ambiguity: CmCell::new(false),
vis,
span,
expansion,
@ -2041,7 +2041,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
fn record_use(&mut self, ident: Ident, used_decl: Decl<'ra>, used: Used) {
self.record_use_inner(ident, used_decl, used, used_decl.warn_ambiguity);
self.record_use_inner(ident, used_decl, used, used_decl.warn_ambiguity.get());
}
fn record_use_inner(
@ -2112,7 +2112,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ident,
source_decl,
Used::Other,
warn_ambiguity || source_decl.warn_ambiguity,
warn_ambiguity || source_decl.warn_ambiguity.get(),
);
}
}