about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2022-04-08 22:50:56 +0200
committerCamille GILLOT <gillot.camille@gmail.com>2022-04-12 19:51:46 +0200
commit24b37a737467ccb4ef93a95f822b9933f3aa56b0 (patch)
treef6101d2f7774fde1e7f83e55efb15909731c8396 /compiler/rustc_resolve/src
parenteb7f5673d9992b1dccc1bc97460267e630fc4ca0 (diff)
downloadrust-24b37a737467ccb4ef93a95f822b9933f3aa56b0.tar.gz
rust-24b37a737467ccb4ef93a95f822b9933f3aa56b0.zip
Pass last_import_segment and unusable_binding as parameters.
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs4
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs12
-rw-r--r--compiler/rustc_resolve/src/ident.rs111
-rw-r--r--compiler/rustc_resolve/src/imports.rs38
-rw-r--r--compiler/rustc_resolve/src/late.rs57
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs3
-rw-r--r--compiler/rustc_resolve/src/lib.rs20
-rw-r--r--compiler/rustc_resolve/src/macros.rs11
8 files changed, 177 insertions, 79 deletions
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 07d261da813..54e8c03156d 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -297,6 +297,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                     Some(TypeNS),
                     parent_scope,
                     if finalize { Finalize::SimplePath(id, path.span) } else { Finalize::No },
+                    None,
                 ) {
                     PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
                         let res = module.res().expect("visibility resolved to unnamed block");
@@ -1124,12 +1125,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
             });
         } else {
             for ident in single_imports.iter().cloned() {
-                let result = self.r.resolve_ident_in_module(
+                let result = self.r.maybe_resolve_ident_in_module(
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     MacroNS,
                     &self.parent_scope,
-                    None,
                 );
                 if let Ok(binding) = result {
                     let import = macro_use_import(self, ident.span);
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 609dbd1fe1b..fdcc045efd8 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -25,7 +25,7 @@ use crate::imports::{Import, ImportKind, ImportResolver};
 use crate::path_names_to_string;
 use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind};
 use crate::{BindingError, HasGenericParams, MacroRulesScope, Module, ModuleOrUniformRoot};
-use crate::{Finalize, NameBinding, NameBindingKind, PrivacyError, VisResolutionError};
+use crate::{NameBinding, NameBindingKind, PrivacyError, VisResolutionError};
 use crate::{ParentScope, PathResult, ResolutionError, Resolver, Scope, ScopeSet, Segment};
 
 type Res = def::Res<ast::NodeId>;
@@ -1076,6 +1076,8 @@ impl<'a> Resolver<'a> {
                 &parent_scope,
                 None,
                 false,
+                false,
+                None,
             ) {
                 let desc = match binding.res() {
                     Res::Def(DefKind::Macro(MacroKind::Bang), _) => {
@@ -1422,7 +1424,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ) -> Option<(Vec<Segment>, Vec<String>)> {
         // Replace first ident with `self` and check if that is valid.
         path[0].ident.name = kw::SelfLower;
-        let result = self.r.resolve_path(&path, None, parent_scope, Finalize::No);
+        let result = self.r.maybe_resolve_path(&path, None, parent_scope);
         debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result { Some((path, Vec::new())) } else { None }
     }
@@ -1441,7 +1443,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ) -> Option<(Vec<Segment>, Vec<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Crate;
-        let result = self.r.resolve_path(&path, None, parent_scope, Finalize::No);
+        let result = self.r.maybe_resolve_path(&path, None, parent_scope);
         debug!("make_missing_crate_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((
@@ -1472,7 +1474,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ) -> Option<(Vec<Segment>, Vec<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Super;
-        let result = self.r.resolve_path(&path, None, parent_scope, Finalize::No);
+        let result = self.r.maybe_resolve_path(&path, None, parent_scope);
         debug!("make_missing_super_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result { Some((path, Vec::new())) } else { None }
     }
@@ -1506,7 +1508,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         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.r.resolve_path(&path, None, parent_scope, Finalize::No);
+            let result = self.r.maybe_resolve_path(&path, None, parent_scope);
             debug!(
                 "make_external_crate_suggestion: name={:?} path={:?} result={:?}",
                 name, path, result
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 3232e66e823..e528a50d147 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -280,6 +280,7 @@ impl<'a> Resolver<'a> {
     ///
     /// Invariant: This must only be called during main resolution, not during
     /// import resolution.
+    #[tracing::instrument(level = "debug", skip(self, ribs))]
     crate fn resolve_ident_in_lexical_scope(
         &mut self,
         mut ident: Ident,
@@ -287,6 +288,7 @@ impl<'a> Resolver<'a> {
         parent_scope: &ParentScope<'a>,
         finalize_full: Finalize,
         ribs: &[Rib<'a>],
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> Option<LexicalScopeBinding<'a>> {
         assert!(ns == TypeNS || ns == ValueNS);
         let orig_ident = ident;
@@ -349,6 +351,8 @@ impl<'a> Resolver<'a> {
                 ns,
                 parent_scope,
                 finalize,
+                false,
+                unusable_binding,
             );
             if let Ok(binding) = item {
                 // The ident resolves to an item.
@@ -361,6 +365,8 @@ impl<'a> Resolver<'a> {
             parent_scope,
             finalize,
             finalize.is_some(),
+            false,
+            unusable_binding,
         )
         .ok()
         .map(LexicalScopeBinding::Item)
@@ -371,6 +377,7 @@ impl<'a> Resolver<'a> {
     /// expansion and import resolution (perhaps they can be merged in the future).
     /// The function is used for resolving initial segments of macro paths (e.g., `foo` in
     /// `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
+    #[tracing::instrument(level = "debug", skip(self, scope_set))]
     crate fn early_resolve_ident_in_lexical_scope(
         &mut self,
         orig_ident: Ident,
@@ -378,6 +385,8 @@ impl<'a> Resolver<'a> {
         parent_scope: &ParentScope<'a>,
         finalize: Option<Span>,
         force: bool,
+        last_import_segment: bool,
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> Result<&'a NameBinding<'a>, Determinacy> {
         bitflags::bitflags! {
             struct Flags: u8 {
@@ -497,6 +506,8 @@ impl<'a> Resolver<'a> {
                             ns,
                             parent_scope,
                             finalize,
+                            last_import_segment,
+                            unusable_binding,
                         );
                         match binding {
                             Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)),
@@ -518,6 +529,8 @@ impl<'a> Resolver<'a> {
                             adjusted_parent_scope,
                             !matches!(scope_set, ScopeSet::Late(..)),
                             finalize,
+                            last_import_segment,
+                            unusable_binding,
                         );
                         match binding {
                             Ok(binding) => {
@@ -602,6 +615,8 @@ impl<'a> Resolver<'a> {
                                 ns,
                                 parent_scope,
                                 None,
+                                last_import_segment,
+                                unusable_binding,
                             ) {
                                 if use_prelude || this.is_builtin_macro(binding.res()) {
                                     result = Ok((binding, Flags::MISC_FROM_PRELUDE));
@@ -715,6 +730,19 @@ impl<'a> Resolver<'a> {
         Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
     }
 
+    #[tracing::instrument(level = "debug", skip(self))]
+    crate fn maybe_resolve_ident_in_module(
+        &mut self,
+        module: ModuleOrUniformRoot<'a>,
+        ident: Ident,
+        ns: Namespace,
+        parent_scope: &ParentScope<'a>,
+    ) -> Result<&'a NameBinding<'a>, Determinacy> {
+        self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, false, None)
+            .map_err(|(determinacy, _)| determinacy)
+    }
+
+    #[tracing::instrument(level = "debug", skip(self))]
     crate fn resolve_ident_in_module(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -722,11 +750,25 @@ impl<'a> Resolver<'a> {
         ns: Namespace,
         parent_scope: &ParentScope<'a>,
         finalize: Option<Span>,
+        // We are resolving a last import segment during import validation.
+        last_import_segment: bool,
+        // This binding should be ignored during in-module resolution, so that we don't get
+        // "self-confirming" import resolutions during import validation.
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> Result<&'a NameBinding<'a>, Determinacy> {
-        self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, finalize)
-            .map_err(|(determinacy, _)| determinacy)
+        self.resolve_ident_in_module_ext(
+            module,
+            ident,
+            ns,
+            parent_scope,
+            finalize,
+            last_import_segment,
+            unusable_binding,
+        )
+        .map_err(|(determinacy, _)| determinacy)
     }
 
+    #[tracing::instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_ext(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -734,6 +776,8 @@ impl<'a> Resolver<'a> {
         ns: Namespace,
         parent_scope: &ParentScope<'a>,
         finalize: Option<Span>,
+        last_import_segment: bool,
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
         let tmp_parent_scope;
         let mut adjusted_parent_scope = parent_scope;
@@ -759,9 +803,12 @@ impl<'a> Resolver<'a> {
             adjusted_parent_scope,
             false,
             finalize,
+            last_import_segment,
+            unusable_binding,
         )
     }
 
+    #[tracing::instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_unadjusted(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -769,6 +816,8 @@ impl<'a> Resolver<'a> {
         ns: Namespace,
         parent_scope: &ParentScope<'a>,
         finalize: Option<Span>,
+        last_import_segment: bool,
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> Result<&'a NameBinding<'a>, Determinacy> {
         self.resolve_ident_in_module_unadjusted_ext(
             module,
@@ -777,12 +826,15 @@ impl<'a> Resolver<'a> {
             parent_scope,
             false,
             finalize,
+            last_import_segment,
+            unusable_binding,
         )
         .map_err(|(determinacy, _)| determinacy)
     }
 
     /// Attempts to resolve `ident` in namespaces `ns` of `module`.
     /// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete.
+    #[tracing::instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_unadjusted_ext(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -791,6 +843,8 @@ impl<'a> Resolver<'a> {
         parent_scope: &ParentScope<'a>,
         restricted_shadowing: bool,
         finalize: Option<Span>,
+        last_import_segment: bool,
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
         let module = match module {
             ModuleOrUniformRoot::Module(module) => module,
@@ -802,6 +856,8 @@ impl<'a> Resolver<'a> {
                     parent_scope,
                     finalize,
                     finalize.is_some(),
+                    last_import_segment,
+                    unusable_binding,
                 );
                 return binding.map_err(|determinacy| (determinacy, Weak::No));
             }
@@ -841,6 +897,8 @@ impl<'a> Resolver<'a> {
                     parent_scope,
                     finalize,
                     finalize.is_some(),
+                    last_import_segment,
+                    unusable_binding,
                 );
                 return binding.map_err(|determinacy| (determinacy, Weak::No));
             }
@@ -865,7 +923,7 @@ impl<'a> Resolver<'a> {
             // binding if it exists. What we really want here is having two separate scopes in
             // a module - one for non-globs and one for globs, but until that's done use this
             // hack to avoid inconsistent resolution ICEs during import validation.
-            if let Some(unusable_binding) = self.unusable_binding
+            if let Some(unusable_binding) = unusable_binding
                 && ptr::eq(binding, unusable_binding)
             {
                 let Some(shadowed) = resolution.shadowed_glob else {
@@ -880,7 +938,7 @@ impl<'a> Resolver<'a> {
             }
 
             if !self.is_accessible_from(binding.vis, parent_scope.module) {
-                if self.last_import_segment {
+                if last_import_segment {
                     return Err((Determined, Weak::No));
                 } else {
                     self.privacy_errors.push(PrivacyError {
@@ -912,7 +970,7 @@ impl<'a> Resolver<'a> {
         }
 
         let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
-            if let Some(unusable_binding) = this.unusable_binding {
+            if let Some(unusable_binding) = unusable_binding {
                 if ptr::eq(binding, unusable_binding) {
                     return Err((Determined, Weak::No));
                 }
@@ -942,8 +1000,15 @@ impl<'a> Resolver<'a> {
             let ImportKind::Single { source: ident, .. } = single_import.kind else {
                 unreachable!();
             };
-            match self.resolve_ident_in_module(module, ident, ns, &single_import.parent_scope, None)
-            {
+            match self.resolve_ident_in_module(
+                module,
+                ident,
+                ns,
+                &single_import.parent_scope,
+                None,
+                last_import_segment,
+                unusable_binding,
+            ) {
                 Err(Determined) => continue,
                 Ok(binding)
                     if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
@@ -1018,6 +1083,8 @@ impl<'a> Resolver<'a> {
                 ns,
                 adjusted_parent_scope,
                 None,
+                last_import_segment,
+                unusable_binding,
             );
 
             match result {
@@ -1036,6 +1103,7 @@ impl<'a> Resolver<'a> {
     }
 
     /// Validate a local resolution (from ribs).
+    #[tracing::instrument(level = "debug", skip(self, all_ribs))]
     fn validate_res_from_ribs(
         &mut self,
         rib_index: usize,
@@ -1268,14 +1336,26 @@ impl<'a> Resolver<'a> {
         res
     }
 
+    #[tracing::instrument(level = "debug", skip(self))]
+    crate fn maybe_resolve_path(
+        &mut self,
+        path: &[Segment],
+        opt_ns: Option<Namespace>, // `None` indicates a module path in import
+        parent_scope: &ParentScope<'a>,
+    ) -> PathResult<'a> {
+        self.resolve_path_with_ribs(path, opt_ns, parent_scope, Finalize::No, None, None)
+    }
+
+    #[tracing::instrument(level = "debug", skip(self))]
     crate fn resolve_path(
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
         parent_scope: &ParentScope<'a>,
         finalize: Finalize,
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> PathResult<'a> {
-        self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None)
+        self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None, unusable_binding)
     }
 
     crate fn resolve_path_with_ribs(
@@ -1285,6 +1365,7 @@ impl<'a> Resolver<'a> {
         parent_scope: &ParentScope<'a>,
         finalize_full: Finalize,
         ribs: Option<&PerNS<Vec<Rib<'a>>>>,
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> PathResult<'a> {
         debug!("resolve_path(path={:?}, opt_ns={:?}, finalize={:?})", path, opt_ns, finalize_full);
 
@@ -1382,7 +1463,15 @@ impl<'a> Resolver<'a> {
             }
             let find_binding_in_ns = |this: &mut Self, ns| {
                 let binding = if let Some(module) = module {
-                    this.resolve_ident_in_module(module, ident, ns, parent_scope, finalize)
+                    this.resolve_ident_in_module(
+                        module,
+                        ident,
+                        ns,
+                        parent_scope,
+                        finalize,
+                        false,
+                        unusable_binding,
+                    )
                 } else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
                     let scopes = ScopeSet::All(ns, opt_ns.is_none());
                     this.early_resolve_ident_in_lexical_scope(
@@ -1391,6 +1480,8 @@ impl<'a> Resolver<'a> {
                         parent_scope,
                         finalize,
                         finalize.is_some(),
+                        false,
+                        unusable_binding,
                     )
                 } else {
                     match this.resolve_ident_in_lexical_scope(
@@ -1399,6 +1490,7 @@ impl<'a> Resolver<'a> {
                         parent_scope,
                         finalize_full,
                         &ribs.unwrap()[ns],
+                        unusable_binding,
                     ) {
                         // we found a locally-imported or available item/module
                         Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
@@ -1514,6 +1606,7 @@ impl<'a> Resolver<'a> {
                                         parent_scope,
                                         Finalize::No,
                                         &ribs.unwrap()[ValueNS],
+                                        unusable_binding,
                                     ) {
                                         // Name matches a local variable. For example:
                                         // ```
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 3d199afb13d..aab0c1f9771 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -499,7 +499,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             // not define any names while resolving its module path.
             let orig_vis = import.vis.replace(ty::Visibility::Invisible);
             let path_res =
-                self.r.resolve_path(&import.module_path, None, &import.parent_scope, Finalize::No);
+                self.r.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
             import.vis.set(orig_vis);
 
             match path_res {
@@ -539,6 +539,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                         ns,
                         &import.parent_scope,
                         None,
+                        false,
+                        None,
                     );
                     import.vis.set(orig_vis);
                     source_bindings[ns].set(binding);
@@ -584,10 +586,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     /// consolidate multiple unresolved import errors into a single diagnostic.
     fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> {
         let orig_vis = import.vis.replace(ty::Visibility::Invisible);
-        let orig_unusable_binding = match &import.kind {
-            ImportKind::Single { target_bindings, .. } => {
-                Some(mem::replace(&mut self.r.unusable_binding, target_bindings[TypeNS].get()))
-            }
+        let unusable_binding = match &import.kind {
+            ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
             _ => None,
         };
         let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
@@ -596,12 +596,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             root_span: import.root_span,
             path_span: import.span,
         };
-        let path_res =
-            self.r.resolve_path(&import.module_path, None, &import.parent_scope, finalize);
+        let path_res = self.r.resolve_path(
+            &import.module_path,
+            None,
+            &import.parent_scope,
+            finalize,
+            unusable_binding,
+        );
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
-        if let Some(orig_unusable_binding) = orig_unusable_binding {
-            self.r.unusable_binding = orig_unusable_binding;
-        }
         import.vis.set(orig_vis);
         if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
             // Consider erroneous imports used to avoid duplicate diagnostics.
@@ -714,18 +716,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         self.r.per_ns(|this, ns| {
             if !type_ns_only || ns == TypeNS {
                 let orig_vis = import.vis.replace(ty::Visibility::Invisible);
-                let orig_unusable_binding =
-                    mem::replace(&mut this.unusable_binding, target_bindings[ns].get());
-                let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true);
                 let binding = this.resolve_ident_in_module(
                     module,
                     ident,
                     ns,
                     &import.parent_scope,
                     Some(import.span),
+                    true,
+                    target_bindings[ns].get(),
                 );
-                this.last_import_segment = orig_last_import_segment;
-                this.unusable_binding = orig_unusable_binding;
                 import.vis.set(orig_vis);
 
                 match binding {
@@ -784,6 +783,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                         ns,
                         &import.parent_scope,
                         Some(import.span),
+                        false,
+                        None,
                     );
                     if binding.is_ok() {
                         all_ns_failed = false;
@@ -998,15 +999,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     return;
                 }
 
-                let orig_unusable_binding =
-                    mem::replace(&mut this.unusable_binding, target_bindings[ns].get());
-
                 match this.early_resolve_ident_in_lexical_scope(
                     target,
                     ScopeSet::All(ns, false),
                     &import.parent_scope,
                     None,
                     false,
+                    false,
+                    target_bindings[ns].get(),
                 ) {
                     Ok(other_binding) => {
                         is_redundant[ns] = Some(
@@ -1016,8 +1016,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     }
                     Err(_) => is_redundant[ns] = Some(false),
                 }
-
-                this.unusable_binding = orig_unusable_binding;
             }
         });
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 6fedabc816c..9084e659ae4 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -8,7 +8,7 @@
 use RibKind::*;
 
 use crate::{path_names_to_string, BindingError, Finalize, LexicalScopeBinding};
-use crate::{Module, ModuleOrUniformRoot, ParentScope, PathResult};
+use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
 use crate::{ResolutionError, Resolver, Segment, UseError};
 
 use rustc_ast::ptr::P;
@@ -487,6 +487,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                         self_ty,
                         TypeNS,
                         Finalize::SimplePath(ty.id, ty.span),
+                        None,
                     )
                     .map_or(Res::Err, |d| d.res());
                 self.r.record_partial_res(ty.id, PartialRes::new(res));
@@ -676,12 +677,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                     // checking.
                     if path.segments.len() == 1 && path.segments[0].args.is_none() {
                         let mut check_ns = |ns| {
-                            self.resolve_ident_in_lexical_scope(
-                                path.segments[0].ident,
-                                ns,
-                                Finalize::No,
-                            )
-                            .is_some()
+                            self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
+                                .is_some()
                         };
                         if !check_ns(TypeNS) && check_ns(ValueNS) {
                             // This must be equivalent to `visit_anon_const`, but we cannot call it
@@ -750,11 +747,27 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         }
     }
 
+    fn maybe_resolve_ident_in_lexical_scope(
+        &mut self,
+        ident: Ident,
+        ns: Namespace,
+    ) -> Option<LexicalScopeBinding<'a>> {
+        self.r.resolve_ident_in_lexical_scope(
+            ident,
+            ns,
+            &self.parent_scope,
+            Finalize::No,
+            &self.ribs[ns],
+            None,
+        )
+    }
+
     fn resolve_ident_in_lexical_scope(
         &mut self,
         ident: Ident,
         ns: Namespace,
         finalize: Finalize,
+        unusable_binding: Option<&'a NameBinding<'a>>,
     ) -> Option<LexicalScopeBinding<'a>> {
         self.r.resolve_ident_in_lexical_scope(
             ident,
@@ -762,6 +775,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             &self.parent_scope,
             finalize,
             &self.ribs[ns],
+            unusable_binding,
         )
     }
 
@@ -771,7 +785,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
         finalize: Finalize,
     ) -> PathResult<'a> {
-        self.r.resolve_path_with_ribs(path, opt_ns, &self.parent_scope, finalize, Some(&self.ribs))
+        self.r.resolve_path_with_ribs(
+            path,
+            opt_ns,
+            &self.parent_scope,
+            finalize,
+            Some(&self.ribs),
+            None,
+        )
     }
 
     // AST resolution
@@ -934,19 +955,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             };
 
             for &ns in nss {
-                match self.resolve_ident_in_lexical_scope(ident, ns, Finalize::No) {
+                match self.maybe_resolve_ident_in_lexical_scope(ident, ns) {
                     Some(LexicalScopeBinding::Res(..)) => {
                         report_error(self, ns);
                     }
                     Some(LexicalScopeBinding::Item(binding)) => {
-                        let orig_unusable_binding =
-                            replace(&mut self.r.unusable_binding, Some(binding));
-                        if let Some(LexicalScopeBinding::Res(..)) =
-                            self.resolve_ident_in_lexical_scope(ident, ns, Finalize::No)
+                        if let Some(LexicalScopeBinding::Res(..)) = self
+                            .resolve_ident_in_lexical_scope(ident, ns, Finalize::No, Some(binding))
                         {
                             report_error(self, ns);
                         }
-                        self.r.unusable_binding = orig_unusable_binding;
                     }
                     None => {}
                 }
@@ -1802,7 +1820,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         // also be interpreted as a path to e.g. a constant, variant, etc.
         let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
 
-        let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, Finalize::No)?;
+        let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
         let (res, binding) = match ls_binding {
             LexicalScopeBinding::Item(binding)
                 if is_syntactic_ambiguity && binding.is_ambiguity() =>
@@ -2071,17 +2089,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     }
 
     fn self_type_is_available(&mut self) -> bool {
-        let binding = self.resolve_ident_in_lexical_scope(
-            Ident::with_dummy_span(kw::SelfUpper),
-            TypeNS,
-            Finalize::No,
-        );
+        let binding = self
+            .maybe_resolve_ident_in_lexical_scope(Ident::with_dummy_span(kw::SelfUpper), TypeNS);
         if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
     }
 
     fn self_value_is_available(&mut self, self_span: Span) -> bool {
         let ident = Ident::new(kw::SelfLower, self_span);
-        let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, Finalize::No);
+        let binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS);
         if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
     }
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 1e943f0e44a..eae9e846c8b 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1271,12 +1271,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 
         // Look for associated items in the current trait.
         if let Some((module, _)) = self.current_trait_ref {
-            if let Ok(binding) = self.r.resolve_ident_in_module(
+            if let Ok(binding) = self.r.maybe_resolve_ident_in_module(
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
                 &self.parent_scope,
-                None,
             ) {
                 let res = binding.res();
                 if filter_fn(res) {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index f4a650e8d26..c0875bf547a 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -925,13 +925,6 @@ pub struct Resolver<'a> {
     /// All non-determined imports.
     indeterminate_imports: Vec<&'a Import<'a>>,
 
-    /// FIXME: Refactor things so that these fields are passed through arguments and not resolver.
-    /// We are resolving a last import segment during import validation.
-    last_import_segment: bool,
-    /// This binding should be ignored during in-module resolution, so that we don't get
-    /// "self-confirming" import resolutions during import validation.
-    unusable_binding: Option<&'a NameBinding<'a>>,
-
     // Spans for local variables found during pattern resolution.
     // Used for suggestions during error reporting.
     pat_span_map: NodeMap<Span>,
@@ -1339,9 +1332,6 @@ impl<'a> Resolver<'a> {
             determined_imports: Vec::new(),
             indeterminate_imports: Vec::new(),
 
-            last_import_segment: false,
-            unusable_binding: None,
-
             pat_span_map: Default::default(),
             partial_res_map: Default::default(),
             import_res_map: Default::default(),
@@ -2294,12 +2284,7 @@ impl<'a> Resolver<'a> {
         }
 
         let module = self.expect_module(module_id);
-        match self.resolve_path(
-            &segments,
-            Some(ns),
-            &ParentScope::module(module, self),
-            Finalize::No,
-        ) {
+        match self.maybe_resolve_path(&segments, Some(ns), &ParentScope::module(module, self)) {
             PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
             PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
                 Some(path_res.base_res())
@@ -2389,12 +2374,11 @@ impl<'a> Resolver<'a> {
         let ident = Ident::with_dummy_span(sym::main);
         let parent_scope = &ParentScope::module(module, self);
 
-        let Ok(name_binding) = self.resolve_ident_in_module(
+        let Ok(name_binding) = self.maybe_resolve_ident_in_module(
             ModuleOrUniformRoot::Module(module),
             ident,
             ValueNS,
             parent_scope,
-            None
         ) else {
             return;
         };
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 71795ef1633..01f0b11f1ac 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -412,7 +412,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
 
         let mut indeterminate = false;
         for ns in [TypeNS, ValueNS, MacroNS].iter().copied() {
-            match self.resolve_path(path, Some(ns), &parent_scope, Finalize::No) {
+            match self.maybe_resolve_path(path, Some(ns), &parent_scope) {
                 PathResult::Module(ModuleOrUniformRoot::Module(_)) => return Ok(true),
                 PathResult::NonModule(partial_res) if partial_res.unresolved_segments() == 0 => {
                     return Ok(true);
@@ -572,7 +572,7 @@ impl<'a> Resolver<'a> {
         }
 
         let res = if path.len() > 1 {
-            let res = match self.resolve_path(&path, Some(MacroNS), parent_scope, Finalize::No) {
+            let res = match self.maybe_resolve_path(&path, Some(MacroNS), parent_scope) {
                 PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
                     Ok(path_res.base_res())
                 }
@@ -604,6 +604,8 @@ impl<'a> Resolver<'a> {
                 parent_scope,
                 None,
                 force,
+                false,
+                None,
             );
             if let Err(Determinacy::Undetermined) = binding {
                 return Err(Determinacy::Undetermined);
@@ -672,6 +674,7 @@ impl<'a> Resolver<'a> {
                 Some(MacroNS),
                 &parent_scope,
                 Finalize::SimplePath(ast::CRATE_NODE_ID, path_span),
+                None,
             ) {
                 PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
                     let res = path_res.base_res();
@@ -707,6 +710,8 @@ impl<'a> Resolver<'a> {
                 &parent_scope,
                 Some(ident.span),
                 true,
+                false,
+                None,
             ) {
                 Ok(binding) => {
                     let initial_res = initial_binding.map(|initial_binding| {
@@ -748,6 +753,8 @@ impl<'a> Resolver<'a> {
                 &parent_scope,
                 Some(ident.span),
                 true,
+                false,
+                None,
             );
         }
     }