resolve: Tweak some naming around import ambiguities
This commit is contained in:
parent
d929a42a66
commit
b6074fffd1
4 changed files with 42 additions and 50 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue