Rollup merge of #128732 - bvanjoi:immutable-import-vis, r=petrochenkov

make `import.vis` is immutable

r? `@petrochenkov`
This commit is contained in:
Matthias Krüger 2024-08-07 20:28:18 +02:00 committed by GitHub
commit 8f5b50d4ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 129 additions and 63 deletions

View File

@ -283,6 +283,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
parent_scope,
finalize.then(|| Finalize::new(id, path.span)),
None,
None,
) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
let res = module.res().expect("visibility resolved to unnamed block");
@ -372,7 +373,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
has_attributes: !item.attrs.is_empty(),
root_span,
root_id,
vis: Cell::new(Some(vis)),
vis,
used: Default::default(),
});
@ -888,7 +889,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
root_span: item.span,
span: item.span,
module_path: Vec::new(),
vis: Cell::new(Some(vis)),
vis,
used: Cell::new(used.then_some(Used::Other)),
});
self.r.potentially_unused_imports.push(import);
@ -1089,7 +1090,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
root_span: span,
span,
module_path: Vec::new(),
vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID))),
vis: ty::Visibility::Restricted(CRATE_DEF_ID),
used: Default::default(),
})
};
@ -1125,6 +1126,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
ident,
MacroNS,
&self.parent_scope,
None,
);
if let Ok(binding) = result {
let import = macro_use_import(self, ident.span, false);
@ -1253,7 +1255,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
root_span: span,
span,
module_path: Vec::new(),
vis: Cell::new(Some(vis)),
vis,
used: Cell::new(Some(Used::Other)),
});
let import_binding = self.r.import(binding, import);

View File

@ -382,7 +382,7 @@ impl Resolver<'_, '_> {
for import in self.potentially_unused_imports.iter() {
match import.kind {
_ if import.used.get().is_some()
|| import.expect_vis().is_public()
|| import.vis.is_public()
|| import.span.is_dummy() =>
{
if let ImportKind::MacroUse { .. } = import.kind {

View File

@ -1052,6 +1052,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
false,
false,
None,
) {
suggestions.extend(
ext.helper_attrs
@ -1506,6 +1507,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None,
false,
None,
None,
) {
let desc = match binding.res() {
Res::Def(DefKind::Macro(MacroKind::Bang), _) => {
@ -1983,6 +1985,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope: &ParentScope<'a>,
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
module: Option<ModuleOrUniformRoot<'a>>,
failed_segment_idx: usize,
ident: Ident,
@ -2066,11 +2069,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
None,
ignore_binding,
ignore_import,
)
.ok()
} else if let Some(ribs) = ribs
&& let Some(TypeNS | ValueNS) = opt_ns
{
assert!(ignore_import.is_none());
match self.resolve_ident_in_lexical_scope(
ident,
ns_to_try,
@ -2091,6 +2096,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None,
false,
ignore_binding,
ignore_import,
)
.ok()
};
@ -2132,6 +2138,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} else if ident.name.as_str().chars().next().is_some_and(|c| c.is_ascii_uppercase()) {
// Check whether the name refers to an item in the value namespace.
let binding = if let Some(ribs) = ribs {
assert!(ignore_import.is_none());
self.resolve_ident_in_lexical_scope(
ident,
ValueNS,
@ -2206,6 +2213,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None,
false,
ignore_binding,
ignore_import,
) {
let descr = binding.res().descr();
(format!("{descr} `{ident}` is not a crate or module"), suggestion)
@ -2259,7 +2267,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `self` and check if that is valid.
path[0].ident.name = kw::SelfLower;
let result = self.maybe_resolve_path(&path, None, parent_scope);
let result = self.maybe_resolve_path(&path, None, parent_scope, None);
debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
if let PathResult::Module(..) = result { Some((path, None)) } else { None }
}
@ -2278,7 +2286,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `crate` and check if that is valid.
path[0].ident.name = kw::Crate;
let result = self.maybe_resolve_path(&path, None, parent_scope);
let result = self.maybe_resolve_path(&path, None, parent_scope, None);
debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result);
if let PathResult::Module(..) = result {
Some((
@ -2309,7 +2317,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `crate` and check if that is valid.
path[0].ident.name = kw::Super;
let result = self.maybe_resolve_path(&path, None, parent_scope);
let result = self.maybe_resolve_path(&path, None, parent_scope, None);
debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result);
if let PathResult::Module(..) = result { Some((path, None)) } else { None }
}
@ -2343,7 +2351,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for name in extern_crate_names.into_iter() {
// Replace first ident with a crate name and check if that is valid.
path[0].ident.name = name;
let result = self.maybe_resolve_path(&path, None, parent_scope);
let result = self.maybe_resolve_path(&path, None, parent_scope, None);
debug!(
"make_external_crate_suggestion: name={:?} path={:?} result={:?}",
name, path, result
@ -2509,12 +2517,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
/// Finds a cfg-ed out item inside `module` with the matching name.
pub(crate) fn find_cfg_stripped(
&mut self,
err: &mut Diag<'_>,
segment: &Symbol,
module: DefId,
) {
pub(crate) fn find_cfg_stripped(&self, err: &mut Diag<'_>, segment: &Symbol, module: DefId) {
let local_items;
let symbols = if module.is_local() {
local_items = self

View File

@ -14,6 +14,7 @@ use Determinacy::*;
use Namespace::*;
use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use crate::imports::Import;
use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
use crate::macros::{sub_namespace_match, MacroRulesScope};
use crate::{
@ -351,6 +352,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
ignore_binding,
None,
);
if let Ok(binding) = item {
// The ident resolves to an item.
@ -364,6 +366,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
finalize,
finalize.is_some(),
ignore_binding,
None,
)
.ok()
.map(LexicalScopeBinding::Item)
@ -383,6 +386,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
finalize: Option<Finalize>,
force: bool,
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
) -> Result<NameBinding<'a>, Determinacy> {
bitflags::bitflags! {
#[derive(Clone, Copy)]
@ -455,6 +459,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
true,
force,
ignore_import,
) {
Ok((Some(ext), _)) => {
if ext.helper_attrs.contains(&ident.name) {
@ -496,6 +501,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
finalize,
ignore_binding,
ignore_import,
);
match binding {
Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)),
@ -518,6 +524,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
!matches!(scope_set, ScopeSet::Late(..)),
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
ignore_binding,
ignore_import,
);
match binding {
Ok(binding) => {
@ -585,6 +592,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
None,
ignore_binding,
ignore_import,
) {
if matches!(use_prelude, UsePrelude::Yes)
|| this.is_builtin_macro(binding.res())
@ -738,8 +746,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ident: Ident,
ns: Namespace,
parent_scope: &ParentScope<'a>,
ignore_import: Option<Import<'a>>,
) -> Result<NameBinding<'a>, Determinacy> {
self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None)
self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None, ignore_import)
.map_err(|(determinacy, _)| determinacy)
}
@ -752,9 +761,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope: &ParentScope<'a>,
finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
) -> Result<NameBinding<'a>, Determinacy> {
self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, finalize, ignore_binding)
.map_err(|(determinacy, _)| determinacy)
self.resolve_ident_in_module_ext(
module,
ident,
ns,
parent_scope,
finalize,
ignore_binding,
ignore_import,
)
.map_err(|(determinacy, _)| determinacy)
}
#[instrument(level = "debug", skip(self))]
@ -766,6 +784,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope: &ParentScope<'a>,
finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
) -> Result<NameBinding<'a>, (Determinacy, Weak)> {
let tmp_parent_scope;
let mut adjusted_parent_scope = parent_scope;
@ -792,6 +811,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
false,
finalize,
ignore_binding,
ignore_import,
)
}
@ -804,6 +824,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope: &ParentScope<'a>,
finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
) -> Result<NameBinding<'a>, Determinacy> {
self.resolve_ident_in_module_unadjusted_ext(
module,
@ -813,6 +834,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
false,
finalize,
ignore_binding,
ignore_import,
)
.map_err(|(determinacy, _)| determinacy)
}
@ -831,6 +853,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// This binding should be ignored during in-module resolution, so that we don't get
// "self-confirming" import resolutions during import validation and checking.
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
) -> Result<NameBinding<'a>, (Determinacy, Weak)> {
let module = match module {
ModuleOrUniformRoot::Module(module) => module,
@ -843,6 +866,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
finalize,
finalize.is_some(),
ignore_binding,
ignore_import,
);
return binding.map_err(|determinacy| (determinacy, Weak::No));
}
@ -879,6 +903,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
finalize,
finalize.is_some(),
ignore_binding,
ignore_import,
);
return binding.map_err(|determinacy| (determinacy, Weak::No));
}
@ -962,25 +987,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Check if one of single imports can still define the name,
// if it can then our result is not determined and can be invalidated.
for single_import in &resolution.single_imports {
let Some(import_vis) = single_import.vis.get() else {
// This branch handles a cycle in single imports, which occurs
// when we've previously **steal** the `vis` value during an import
// process.
if ignore_import == Some(*single_import) {
// This branch handles a cycle in single imports.
//
// For example:
// ```
// use a::b;
// use b as a;
// ```
// 1. Steal the `vis` in `use a::b` and attempt to locate `a` in the
// 1. Record `use a::b` as the `ignore_import` and attempt to locate `a` in the
// current module.
// 2. Encounter the import `use b as a`, which is a `single_import` for `a`,
// and try to find `b` in the current module.
// 3. Re-encounter the `use a::b` import since it's a `single_import` of `b`.
// This leads to entering this branch.
continue;
};
if !self.is_accessible_from(import_vis, parent_scope.module) {
}
if !self.is_accessible_from(single_import.vis, parent_scope.module) {
continue;
}
if let Some(ignored) = ignore_binding
@ -1022,6 +1045,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&single_import.parent_scope,
None,
ignore_binding,
ignore_import,
) {
Err(Determined) => continue,
Ok(binding)
@ -1070,10 +1094,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Check if one of glob imports can still define the name,
// if it can then our "no resolution" result is not determined and can be invalidated.
for glob_import in module.globs.borrow().iter() {
let Some(import_vis) = glob_import.vis.get() else {
if ignore_import == Some(*glob_import) {
continue;
};
if !self.is_accessible_from(import_vis, parent_scope.module) {
}
if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
continue;
}
let module = match glob_import.imported_module.get() {
@ -1100,6 +1124,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
adjusted_parent_scope,
None,
ignore_binding,
ignore_import,
);
match result {
@ -1412,8 +1437,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>,
ignore_import: Option<Import<'a>>,
) -> PathResult<'a> {
self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None)
self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import)
}
#[instrument(level = "debug", skip(self))]
@ -1424,8 +1450,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope: &ParentScope<'a>,
finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
) -> PathResult<'a> {
self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None, ignore_binding)
self.resolve_path_with_ribs(
path,
opt_ns,
parent_scope,
finalize,
None,
ignore_binding,
ignore_import,
)
}
pub(crate) fn resolve_path_with_ribs(
@ -1436,6 +1471,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
finalize: Option<Finalize>,
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
ignore_binding: Option<NameBinding<'a>>,
ignore_import: Option<Import<'a>>,
) -> PathResult<'a> {
let mut module = None;
let mut allow_super = true;
@ -1538,10 +1574,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
finalize,
ignore_binding,
ignore_import,
)
} else if let Some(ribs) = ribs
&& let Some(TypeNS | ValueNS) = opt_ns
{
assert!(ignore_import.is_none());
match self.resolve_ident_in_lexical_scope(
ident,
ns,
@ -1570,6 +1608,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
finalize,
finalize.is_some(),
ignore_binding,
ignore_import,
)
};
@ -1644,6 +1683,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope,
ribs,
ignore_binding,
ignore_import,
module,
segment_idx,
ident,

View File

@ -175,7 +175,7 @@ pub(crate) struct ImportData<'a> {
pub module_path: Vec<Segment>,
/// The resolution of `module_path`.
pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
pub vis: Cell<Option<ty::Visibility>>,
pub vis: ty::Visibility,
pub used: Cell<Option<Used>>,
}
@ -195,10 +195,6 @@ impl<'a> ImportData<'a> {
}
}
pub(crate) fn expect_vis(&self) -> ty::Visibility {
self.vis.get().expect("encountered cleared import visibility")
}
pub(crate) fn id(&self) -> Option<NodeId> {
match self.kind {
ImportKind::Single { id, .. }
@ -267,7 +263,7 @@ fn pub_use_of_private_extern_crate_hack(
match (&import.kind, &binding.kind) {
(ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. })
if let ImportKind::ExternCrate { id, .. } = binding_import.kind
&& import.expect_vis().is_public() =>
&& import.vis.is_public() =>
{
Some(id)
}
@ -279,7 +275,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Given a binding and an import that resolves to it,
/// return the corresponding binding defined by the import.
pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> {
let import_vis = import.expect_vis().to_def_id();
let import_vis = import.vis.to_def_id();
let vis = if binding.vis.is_at_least(import_vis, self.tcx)
|| pub_use_of_private_extern_crate_hack(import, binding).is_some()
{
@ -773,11 +769,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let module = if let Some(module) = import.imported_module.get() {
module
} else {
// For better failure detection, pretend that the import will
// not define any names while resolving its module path.
let orig_vis = import.vis.take();
let path_res = self.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
import.vis.set(orig_vis);
let path_res = self.maybe_resolve_path(
&import.module_path,
None,
&import.parent_scope,
Some(import),
);
match path_res {
PathResult::Module(module) => module,
@ -807,16 +804,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
self.per_ns(|this, ns| {
if !type_ns_only || ns == TypeNS {
if let Err(Undetermined) = source_bindings[ns].get() {
// For better failure detection, pretend that the import will
// not define any names while resolving its module path.
let orig_vis = import.vis.take();
let binding = this.maybe_resolve_ident_in_module(
module,
source,
ns,
&import.parent_scope,
Some(import),
);
import.vis.set(orig_vis);
source_bindings[ns].set(binding);
} else {
return;
@ -855,7 +849,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Optionally returns an unresolved import error. This error is buffered and used to
/// consolidate multiple unresolved import errors into a single diagnostic.
fn finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError> {
let orig_vis = import.vis.take();
let ignore_binding = match &import.kind {
ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
_ => None,
@ -874,11 +867,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&import.parent_scope,
Some(finalize),
ignore_binding,
Some(import),
);
let no_ambiguity =
ambiguity_errors_len(&self.ambiguity_errors) == prev_ambiguity_errors_len;
import.vis.set(orig_vis);
let module = match path_res {
PathResult::Module(module) => {
// Consistency checks, analogous to `finalize_macro_resolutions`.
@ -1013,8 +1007,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
if !is_prelude
&& let Some(max_vis) = max_vis.get()
&& let import_vis = import.expect_vis()
&& !max_vis.is_at_least(import_vis, self.tcx)
&& !max_vis.is_at_least(import.vis, self.tcx)
{
let def_id = self.local_def_id(id);
self.lint_buffer.buffer_lint(
@ -1023,7 +1016,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
import.span,
BuiltinLintDiag::RedundantImportVisibility {
max_vis: max_vis.to_string(def_id, self.tcx),
import_vis: import_vis.to_string(def_id, self.tcx),
import_vis: import.vis.to_string(def_id, self.tcx),
span: import.span,
},
);
@ -1038,9 +1031,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// importing it if available.
let mut path = import.module_path.clone();
path.push(Segment::from_ident(ident));
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
self.resolve_path(&path, None, &import.parent_scope, Some(finalize), ignore_binding)
{
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(
&path,
None,
&import.parent_scope,
Some(finalize),
ignore_binding,
None,
) {
let res = module.res().map(|r| (r, ident));
for error in &mut self.privacy_errors[privacy_errors_len..] {
error.outermost_res = res;
@ -1051,7 +1049,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut all_ns_err = true;
self.per_ns(|this, ns| {
if !type_ns_only || ns == TypeNS {
let orig_vis = import.vis.take();
let binding = this.resolve_ident_in_module(
module,
ident,
@ -1059,8 +1056,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&import.parent_scope,
Some(Finalize { report_private: false, ..finalize }),
target_bindings[ns].get(),
Some(import),
);
import.vis.set(orig_vis);
match binding {
Ok(binding) => {
@ -1123,6 +1120,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&import.parent_scope,
Some(finalize),
None,
None,
);
if binding.is_ok() {
all_ns_failed = false;
@ -1233,7 +1231,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut crate_private_reexport = false;
self.per_ns(|this, ns| {
if let Ok(binding) = source_bindings[ns].get() {
if !binding.vis.is_at_least(import.expect_vis(), this.tcx) {
if !binding.vis.is_at_least(import.vis, this.tcx) {
reexport_error = Some((ns, binding));
if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
if binding_def_id.is_top_level_module() {
@ -1370,6 +1368,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None,
false,
target_bindings[ns].get(),
None,
) {
Ok(other_binding) => {
is_redundant = binding.res() == other_binding.res()

View File

@ -1388,6 +1388,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
finalize,
Some(&self.ribs),
None,
None,
)
}
@ -4186,7 +4187,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
let path_seg = |seg: &Segment| PathSegment::from_ident(seg.ident);
let path = Path { segments: path.iter().map(path_seg).collect(), span, tokens: None };
if let Ok((_, res)) =
self.r.resolve_macro_path(&path, None, &self.parent_scope, false, false)
self.r.resolve_macro_path(&path, None, &self.parent_scope, false, false, None)
{
return Ok(Some(PartialRes::new(res)));
}

View File

@ -2058,6 +2058,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
ident,
ns,
&self.parent_scope,
None,
) {
let res = binding.res();
if filter_fn(res) {

View File

@ -2120,7 +2120,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
match self.maybe_resolve_path(&segments, Some(ns), &parent_scope) {
match self.maybe_resolve_path(&segments, Some(ns), &parent_scope, None) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
PathResult::NonModule(path_res) => path_res.full_res(),
PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => {
@ -2204,6 +2204,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ident,
ValueNS,
parent_scope,
None,
) else {
return;
};

View File

@ -39,6 +39,7 @@ use crate::errors::{
self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
MacroExpectedFound, RemoveSurroundingDerive,
};
use crate::imports::Import;
use crate::Namespace::*;
use crate::{
BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, MacroData, ModuleKind,
@ -399,6 +400,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
&parent_scope,
true,
force,
None,
) {
Ok((Some(ext), _)) => {
if !ext.helper_attrs.is_empty() {
@ -551,6 +553,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
force,
deleg_impl,
invoc_in_mod_inert_attr.map(|def_id| (def_id, node_id)),
None,
) {
Ok((Some(ext), res)) => (ext, res),
Ok((None, res)) => (self.dummy_ext(kind), res),
@ -704,8 +707,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent_scope: &ParentScope<'a>,
trace: bool,
force: bool,
ignore_import: Option<Import<'a>>,
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
self.resolve_macro_or_delegation_path(path, kind, parent_scope, trace, force, None, None)
self.resolve_macro_or_delegation_path(
path,
kind,
parent_scope,
trace,
force,
None,
None,
ignore_import,
)
}
fn resolve_macro_or_delegation_path(
@ -717,6 +730,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
force: bool,
deleg_impl: Option<LocalDefId>,
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
ignore_import: Option<Import<'a>>,
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
let path_span = ast_path.span;
let mut path = Segment::from_path(ast_path);
@ -733,7 +747,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let res = if deleg_impl.is_some() || path.len() > 1 {
let ns = if deleg_impl.is_some() { TypeNS } else { MacroNS };
let res = match self.maybe_resolve_path(&path, Some(ns), parent_scope) {
let res = match self.maybe_resolve_path(&path, Some(ns), parent_scope, ignore_import) {
PathResult::NonModule(path_res) if let Some(res) = path_res.full_res() => Ok(res),
PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
PathResult::NonModule(..)
@ -768,6 +782,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None,
force,
None,
None,
);
if let Err(Determinacy::Undetermined) = binding {
return Err(Determinacy::Undetermined);
@ -852,6 +867,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, path_span)),
None,
None,
) {
PathResult::NonModule(path_res) if let Some(res) = path_res.full_res() => {
check_consistency(self, &path, path_span, kind, initial_res, res)
@ -871,7 +887,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let PathResult::Failed { span, label, module, .. } = path_res {
// try to suggest if it's not a macro, maybe a function
if let PathResult::NonModule(partial_res) =
self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope)
self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope, None)
&& partial_res.unresolved_segments() == 0
{
let sm = self.tcx.sess.source_map();
@ -921,6 +937,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
true,
None,
None,
) {
Ok(binding) => {
let initial_res = initial_binding.map(|initial_binding| {
@ -966,6 +983,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
true,
None,
None,
);
}
}
@ -1070,6 +1088,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None,
false,
None,
None,
);
if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) {
self.tcx.sess.psess.buffer_lint(
@ -1143,7 +1162,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut indeterminate = false;
for ns in namespaces {
match self.maybe_resolve_path(path, Some(*ns), &parent_scope) {
match self.maybe_resolve_path(path, Some(*ns), &parent_scope, None) {
PathResult::Module(ModuleOrUniformRoot::Module(_)) => return Ok(true),
PathResult::NonModule(partial_res) if partial_res.unresolved_segments() == 0 => {
return Ok(true);