1
Fork 0

resolve: Tweak some naming around import ambiguities

This commit is contained in:
Vadim Petrochenkov 2024-06-25 19:03:39 +03:00
parent d929a42a66
commit b6074fffd1
4 changed files with 42 additions and 50 deletions

View file

@ -99,7 +99,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
// is the maximum value among visibilities of bindings corresponding to that def id. // is the maximum value among visibilities of bindings corresponding to that def id.
for (binding, eff_vis) in visitor.import_effective_visibilities.iter() { for (binding, eff_vis) in visitor.import_effective_visibilities.iter() {
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() }; let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
if !binding.is_ambiguity() { if !binding.is_ambiguity_recursive() {
if let Some(node_id) = import.id() { if let Some(node_id) = import.id() {
r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx)
} }

View file

@ -325,8 +325,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
match (old_binding.is_glob_import(), binding.is_glob_import()) { match (old_binding.is_glob_import(), binding.is_glob_import()) {
(true, true) => { (true, true) => {
// FIXME: remove `!binding.is_ambiguity()` after delete the warning ambiguity. // FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity.
if !binding.is_ambiguity() if !binding.is_ambiguity_recursive()
&& let NameBindingKind::Import { import: old_import, .. } = && let NameBindingKind::Import { import: old_import, .. } =
old_binding.kind old_binding.kind
&& let NameBindingKind::Import { import, .. } = binding.kind && let NameBindingKind::Import { import, .. } = binding.kind
@ -337,21 +337,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// imported from the same glob-import statement. // imported from the same glob-import statement.
resolution.binding = Some(binding); resolution.binding = Some(binding);
} else if res != old_binding.res() { } else if res != old_binding.res() {
let binding = if warn_ambiguity { resolution.binding = Some(this.new_ambiguity_binding(
this.warn_ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) AmbiguityKind::GlobVsGlob,
} else { old_binding,
this.ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) binding,
}; warn_ambiguity,
resolution.binding = Some(binding); ));
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
// We are glob-importing the same item but with greater visibility. // We are glob-importing the same item but with greater visibility.
resolution.binding = Some(binding); resolution.binding = Some(binding);
} else if binding.is_ambiguity() { } else if binding.is_ambiguity_recursive() {
resolution.binding = resolution.binding = Some(this.new_warn_ambiguity_binding(binding));
Some(self.arenas.alloc_name_binding(NameBindingData {
warn_ambiguity: true,
..(*binding).clone()
}));
} }
} }
(old_glob @ true, false) | (old_glob @ false, true) => { (old_glob @ true, false) | (old_glob @ false, true) => {
@ -361,24 +357,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&& nonglob_binding.expansion != LocalExpnId::ROOT && nonglob_binding.expansion != LocalExpnId::ROOT
&& glob_binding.res() != nonglob_binding.res() && glob_binding.res() != nonglob_binding.res()
{ {
resolution.binding = Some(this.ambiguity( resolution.binding = Some(this.new_ambiguity_binding(
AmbiguityKind::GlobVsExpanded, AmbiguityKind::GlobVsExpanded,
nonglob_binding, nonglob_binding,
glob_binding, glob_binding,
false,
)); ));
} else { } else {
resolution.binding = Some(nonglob_binding); resolution.binding = Some(nonglob_binding);
} }
if let Some(old_binding) = resolution.shadowed_glob { if let Some(old_shadowed_glob) = resolution.shadowed_glob {
assert!(old_binding.is_glob_import()); assert!(old_shadowed_glob.is_glob_import());
if glob_binding.res() != old_binding.res() { if glob_binding.res() != old_shadowed_glob.res() {
resolution.shadowed_glob = Some(this.ambiguity( resolution.shadowed_glob = Some(this.new_ambiguity_binding(
AmbiguityKind::GlobVsGlob, AmbiguityKind::GlobVsGlob,
old_binding, old_shadowed_glob,
glob_binding, glob_binding,
false,
)); ));
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { } else if !old_shadowed_glob.vis.is_at_least(binding.vis, this.tcx) {
resolution.shadowed_glob = Some(glob_binding); resolution.shadowed_glob = Some(glob_binding);
} }
} else { } else {
@ -397,29 +395,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}) })
} }
fn ambiguity( fn new_ambiguity_binding(
&self, &self,
kind: AmbiguityKind, ambiguity_kind: AmbiguityKind,
primary_binding: NameBinding<'a>, primary_binding: NameBinding<'a>,
secondary_binding: NameBinding<'a>, secondary_binding: NameBinding<'a>,
warn_ambiguity: bool,
) -> NameBinding<'a> { ) -> NameBinding<'a> {
self.arenas.alloc_name_binding(NameBindingData { let ambiguity = Some((secondary_binding, ambiguity_kind));
ambiguity: Some((secondary_binding, kind)), let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding };
..(*primary_binding).clone() self.arenas.alloc_name_binding(data)
})
} }
fn warn_ambiguity( fn new_warn_ambiguity_binding(&self, binding: NameBinding<'a>) -> NameBinding<'a> {
&self, assert!(binding.is_ambiguity_recursive());
kind: AmbiguityKind, self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding })
primary_binding: NameBinding<'a>,
secondary_binding: NameBinding<'a>,
) -> NameBinding<'a> {
self.arenas.alloc_name_binding(NameBindingData {
ambiguity: Some((secondary_binding, kind)),
warn_ambiguity: true,
..(*primary_binding).clone()
})
} }
// Use `f` to mutate the resolution of the name in the module. // Use `f` to mutate the resolution of the name in the module.
@ -1381,8 +1371,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
target_bindings[ns].get(), target_bindings[ns].get(),
) { ) {
Ok(other_binding) => { Ok(other_binding) => {
is_redundant = is_redundant = binding.res() == other_binding.res()
binding.res() == other_binding.res() && !other_binding.is_ambiguity(); && !other_binding.is_ambiguity_recursive();
if is_redundant { if is_redundant {
redundant_span[ns] = redundant_span[ns] =
Some((other_binding.span, other_binding.is_import())); Some((other_binding.span, other_binding.is_import()));
@ -1455,7 +1445,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.resolution(import.parent_scope.module, key) .resolution(import.parent_scope.module, key)
.borrow() .borrow()
.binding() .binding()
.is_some_and(|binding| binding.is_warn_ambiguity()); .is_some_and(|binding| binding.warn_ambiguity_recursive());
let _ = self.try_define( let _ = self.try_define(
import.parent_scope.module, import.parent_scope.module,
key, key,
@ -1480,7 +1470,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
module.for_each_child(self, |this, ident, _, binding| { module.for_each_child(self, |this, ident, _, binding| {
let res = binding.res().expect_non_local(); let res = binding.res().expect_non_local();
let error_ambiguity = binding.is_ambiguity() && !binding.warn_ambiguity; let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity;
if res != def::Res::Err && !error_ambiguity { if res != def::Res::Err && !error_ambiguity {
let mut reexport_chain = SmallVec::new(); let mut reexport_chain = SmallVec::new();
let mut next_binding = binding; let mut next_binding = binding;

View file

@ -3730,7 +3730,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?; let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
let (res, binding) = match ls_binding { let (res, binding) = match ls_binding {
LexicalScopeBinding::Item(binding) LexicalScopeBinding::Item(binding)
if is_syntactic_ambiguity && binding.is_ambiguity() => if is_syntactic_ambiguity && binding.is_ambiguity_recursive() =>
{ {
// For ambiguous bindings we don't know all their definitions and cannot check // For ambiguous bindings we don't know all their definitions and cannot check
// whether they can be shadowed by fresh bindings or not, so force an error. // whether they can be shadowed by fresh bindings or not, so force an error.

View file

@ -694,10 +694,12 @@ impl<'a> fmt::Debug for Module<'a> {
} }
/// Records a possibly-private value, type, or module definition. /// Records a possibly-private value, type, or module definition.
#[derive(Clone, Debug)] #[derive(Clone, Copy, Debug)]
struct NameBindingData<'a> { struct NameBindingData<'a> {
kind: NameBindingKind<'a>, kind: NameBindingKind<'a>,
ambiguity: Option<(NameBinding<'a>, AmbiguityKind)>, ambiguity: Option<(NameBinding<'a>, 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: bool,
expansion: LocalExpnId, expansion: LocalExpnId,
span: Span, span: Span,
@ -718,7 +720,7 @@ impl<'a> ToNameBinding<'a> for NameBinding<'a> {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Copy, Debug)]
enum NameBindingKind<'a> { enum NameBindingKind<'a> {
Res(Res), Res(Res),
Module(Module<'a>), Module(Module<'a>),
@ -830,18 +832,18 @@ impl<'a> NameBindingData<'a> {
} }
} }
fn is_ambiguity(&self) -> bool { fn is_ambiguity_recursive(&self) -> bool {
self.ambiguity.is_some() self.ambiguity.is_some()
|| match self.kind { || match self.kind {
NameBindingKind::Import { binding, .. } => binding.is_ambiguity(), NameBindingKind::Import { binding, .. } => binding.is_ambiguity_recursive(),
_ => false, _ => false,
} }
} }
fn is_warn_ambiguity(&self) -> bool { fn warn_ambiguity_recursive(&self) -> bool {
self.warn_ambiguity self.warn_ambiguity
|| match self.kind { || match self.kind {
NameBindingKind::Import { binding, .. } => binding.is_warn_ambiguity(), NameBindingKind::Import { binding, .. } => binding.warn_ambiguity_recursive(),
_ => false, _ => false,
} }
} }