rustc_resolve/
ident.rs

1use std::ops::ControlFlow;
2
3use Determinacy::*;
4use Namespace::*;
5use rustc_ast::{self as ast, NodeId};
6use rustc_errors::ErrorGuaranteed;
7use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS};
8use rustc_middle::{bug, span_bug};
9use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
10use rustc_session::parse::feature_err;
11use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
12use rustc_span::{Ident, Macros20NormalizedIdent, Span, kw, sym};
13use smallvec::SmallVec;
14use tracing::{debug, instrument};
15
16use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
17use crate::imports::{Import, NameResolution};
18use crate::late::{
19    ConstantHasGenerics, DiagMetadata, NoConstantGenericsReason, PathSource, Rib, RibKind,
20};
21use crate::macros::{MacroRulesScope, sub_namespace_match};
22use crate::{
23    AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize,
24    ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult,
25    PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, errors,
26};
27
28#[derive(Copy, Clone)]
29pub enum UsePrelude {
30    No,
31    Yes,
32}
33
34impl From<UsePrelude> for bool {
35    fn from(up: UsePrelude) -> bool {
36        matches!(up, UsePrelude::Yes)
37    }
38}
39
40#[derive(Debug, PartialEq, Clone, Copy)]
41enum Shadowing {
42    Restricted,
43    Unrestricted,
44}
45
46impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
47    /// A generic scope visitor.
48    /// Visits scopes in order to resolve some identifier in them or perform other actions.
49    /// If the callback returns `Some` result, we stop visiting scopes and return it.
50    pub(crate) fn visit_scopes<'r, T>(
51        mut self: CmResolver<'r, 'ra, 'tcx>,
52        scope_set: ScopeSet<'ra>,
53        parent_scope: &ParentScope<'ra>,
54        orig_ctxt: SyntaxContext,
55        derive_fallback_lint_id: Option<NodeId>,
56        mut visitor: impl FnMut(
57            &mut CmResolver<'r, 'ra, 'tcx>,
58            Scope<'ra>,
59            UsePrelude,
60            SyntaxContext,
61        ) -> ControlFlow<T>,
62    ) -> Option<T> {
63        // General principles:
64        // 1. Not controlled (user-defined) names should have higher priority than controlled names
65        //    built into the language or standard library. This way we can add new names into the
66        //    language or standard library without breaking user code.
67        // 2. "Closed set" below means new names cannot appear after the current resolution attempt.
68        // Places to search (in order of decreasing priority):
69        // (Type NS)
70        // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet
71        //    (open set, not controlled).
72        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
73        //    (open, not controlled).
74        // 3. Extern prelude (open, the open part is from macro expansions, not controlled).
75        // 4. Tool modules (closed, controlled right now, but not in the future).
76        // 5. Standard library prelude (de-facto closed, controlled).
77        // 6. Language prelude (closed, controlled).
78        // (Value NS)
79        // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet
80        //    (open set, not controlled).
81        // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
82        //    (open, not controlled).
83        // 3. Standard library prelude (de-facto closed, controlled).
84        // (Macro NS)
85        // 1-3. Derive helpers (open, not controlled). All ambiguities with other names
86        //    are currently reported as errors. They should be higher in priority than preludes
87        //    and probably even names in modules according to the "general principles" above. They
88        //    also should be subject to restricted shadowing because are effectively produced by
89        //    derives (you need to resolve the derive first to add helpers into scope), but they
90        //    should be available before the derive is expanded for compatibility.
91        //    It's mess in general, so we are being conservative for now.
92        // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher
93        //    priority than prelude macros, but create ambiguities with macros in modules.
94        // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
95        //    (open, not controlled). Have higher priority than prelude macros, but create
96        //    ambiguities with `macro_rules`.
97        // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
98        // 4a. User-defined prelude from macro-use
99        //    (open, the open part is from macro expansions, not controlled).
100        // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).
101        // 4c. Standard library prelude (de-facto closed, controlled).
102        // 6. Language prelude: builtin attributes (closed, controlled).
103
104        let (ns, macro_kind) = match scope_set {
105            ScopeSet::All(ns)
106            | ScopeSet::Module(ns, _)
107            | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
108            ScopeSet::ExternPrelude => (TypeNS, None),
109            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
110        };
111        let module = match scope_set {
112            // Start with the specified module.
113            ScopeSet::Module(_, module) | ScopeSet::ModuleAndExternPrelude(_, module) => module,
114            // Jump out of trait or enum modules, they do not act as scopes.
115            _ => parent_scope.module.nearest_item_scope(),
116        };
117        let module_only = matches!(scope_set, ScopeSet::Module(..));
118        let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
119        let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude);
120        let mut scope = match ns {
121            _ if module_only || module_and_extern_prelude => Scope::ModuleNonGlobs(module, None),
122            _ if extern_prelude => Scope::ExternPreludeItems,
123            TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None),
124            MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
125        };
126        let mut ctxt = orig_ctxt.normalize_to_macros_2_0();
127        let mut use_prelude = !module.no_implicit_prelude;
128
129        loop {
130            let visit = match scope {
131                // Derive helpers are not in scope when resolving derives in the same container.
132                Scope::DeriveHelpers(expn_id) => {
133                    !(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
134                }
135                Scope::DeriveHelpersCompat => true,
136                Scope::MacroRules(macro_rules_scope) => {
137                    // Use "path compression" on `macro_rules` scope chains. This is an optimization
138                    // used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.
139                    // As another consequence of this optimization visitors never observe invocation
140                    // scopes for macros that were already expanded.
141                    while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
142                        if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
143                            macro_rules_scope.set(next_scope.get());
144                        } else {
145                            break;
146                        }
147                    }
148                    true
149                }
150                Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..) => true,
151                Scope::MacroUsePrelude => use_prelude || orig_ctxt.edition().is_rust_2015(),
152                Scope::BuiltinAttrs => true,
153                Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
154                    use_prelude || module_and_extern_prelude || extern_prelude
155                }
156                Scope::ToolPrelude => use_prelude,
157                Scope::StdLibPrelude => use_prelude || ns == MacroNS,
158                Scope::BuiltinTypes => true,
159            };
160
161            if visit {
162                let use_prelude = if use_prelude { UsePrelude::Yes } else { UsePrelude::No };
163                if let ControlFlow::Break(break_result) =
164                    visitor(&mut self, scope, use_prelude, ctxt)
165                {
166                    return Some(break_result);
167                }
168            }
169
170            scope = match scope {
171                Scope::DeriveHelpers(LocalExpnId::ROOT) => Scope::DeriveHelpersCompat,
172                Scope::DeriveHelpers(expn_id) => {
173                    // Derive helpers are not visible to code generated by bang or derive macros.
174                    let expn_data = expn_id.expn_data();
175                    match expn_data.kind {
176                        ExpnKind::Root
177                        | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
178                            Scope::DeriveHelpersCompat
179                        }
180                        _ => Scope::DeriveHelpers(expn_data.parent.expect_local()),
181                    }
182                }
183                Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
184                Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
185                    MacroRulesScope::Def(binding) => {
186                        Scope::MacroRules(binding.parent_macro_rules_scope)
187                    }
188                    MacroRulesScope::Invocation(invoc_id) => {
189                        Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
190                    }
191                    MacroRulesScope::Empty => Scope::ModuleNonGlobs(module, None),
192                },
193                Scope::ModuleNonGlobs(module, lint_id) => Scope::ModuleGlobs(module, lint_id),
194                Scope::ModuleGlobs(..) if module_only => break,
195                Scope::ModuleGlobs(..) if module_and_extern_prelude => match ns {
196                    TypeNS => {
197                        ctxt.adjust(ExpnId::root());
198                        Scope::ExternPreludeItems
199                    }
200                    ValueNS | MacroNS => break,
201                },
202                Scope::ModuleGlobs(module, prev_lint_id) => {
203                    use_prelude = !module.no_implicit_prelude;
204                    match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
205                        Some((parent_module, lint_id)) => {
206                            Scope::ModuleNonGlobs(parent_module, lint_id.or(prev_lint_id))
207                        }
208                        None => {
209                            ctxt.adjust(ExpnId::root());
210                            match ns {
211                                TypeNS => Scope::ExternPreludeItems,
212                                ValueNS => Scope::StdLibPrelude,
213                                MacroNS => Scope::MacroUsePrelude,
214                            }
215                        }
216                    }
217                }
218                Scope::MacroUsePrelude => Scope::StdLibPrelude,
219                Scope::BuiltinAttrs => break, // nowhere else to search
220                Scope::ExternPreludeItems => Scope::ExternPreludeFlags,
221                Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,
222                Scope::ExternPreludeFlags => Scope::ToolPrelude,
223                Scope::ToolPrelude => Scope::StdLibPrelude,
224                Scope::StdLibPrelude => match ns {
225                    TypeNS => Scope::BuiltinTypes,
226                    ValueNS => break, // nowhere else to search
227                    MacroNS => Scope::BuiltinAttrs,
228                },
229                Scope::BuiltinTypes => break, // nowhere else to search
230            };
231        }
232
233        None
234    }
235
236    fn hygienic_lexical_parent(
237        &self,
238        module: Module<'ra>,
239        ctxt: &mut SyntaxContext,
240        derive_fallback_lint_id: Option<NodeId>,
241    ) -> Option<(Module<'ra>, Option<NodeId>)> {
242        if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
243            return Some((self.expn_def_scope(ctxt.remove_mark()), None));
244        }
245
246        if let ModuleKind::Block = module.kind {
247            return Some((module.parent.unwrap().nearest_item_scope(), None));
248        }
249
250        // We need to support the next case under a deprecation warning
251        // ```
252        // struct MyStruct;
253        // ---- begin: this comes from a proc macro derive
254        // mod implementation_details {
255        //     // Note that `MyStruct` is not in scope here.
256        //     impl SomeTrait for MyStruct { ... }
257        // }
258        // ---- end
259        // ```
260        // So we have to fall back to the module's parent during lexical resolution in this case.
261        if derive_fallback_lint_id.is_some()
262            && let Some(parent) = module.parent
263            // Inner module is inside the macro
264            && module.expansion != parent.expansion
265            // Parent module is outside of the macro
266            && module.expansion.is_descendant_of(parent.expansion)
267            // The macro is a proc macro derive
268            && let Some(def_id) = module.expansion.expn_data().macro_def_id
269        {
270            let ext = &self.get_macro_by_def_id(def_id).ext;
271            if ext.builtin_name.is_none()
272                && ext.macro_kinds() == MacroKinds::DERIVE
273                && parent.expansion.outer_expn_is_descendant_of(*ctxt)
274            {
275                return Some((parent, derive_fallback_lint_id));
276            }
277        }
278
279        None
280    }
281
282    /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
283    /// More specifically, we proceed up the hierarchy of scopes and return the binding for
284    /// `ident` in the first scope that defines it (or None if no scopes define it).
285    ///
286    /// A block's items are above its local variables in the scope hierarchy, regardless of where
287    /// the items are defined in the block. For example,
288    /// ```rust
289    /// fn f() {
290    ///    g(); // Since there are no local variables in scope yet, this resolves to the item.
291    ///    let g = || {};
292    ///    fn g() {}
293    ///    g(); // This resolves to the local variable `g` since it shadows the item.
294    /// }
295    /// ```
296    ///
297    /// Invariant: This must only be called during main resolution, not during
298    /// import resolution.
299    #[instrument(level = "debug", skip(self, ribs))]
300    pub(crate) fn resolve_ident_in_lexical_scope(
301        &mut self,
302        mut ident: Ident,
303        ns: Namespace,
304        parent_scope: &ParentScope<'ra>,
305        finalize: Option<Finalize>,
306        ribs: &[Rib<'ra>],
307        ignore_decl: Option<Decl<'ra>>,
308        diag_metadata: Option<&DiagMetadata<'_>>,
309    ) -> Option<LateDecl<'ra>> {
310        let orig_ident = ident;
311        let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
312            // FIXME(jseyfried) improve `Self` hygiene
313            let empty_span = ident.span.with_ctxt(SyntaxContext::root());
314            (empty_span, empty_span)
315        } else if ns == TypeNS {
316            let normalized_span = ident.span.normalize_to_macros_2_0();
317            (normalized_span, normalized_span)
318        } else {
319            (ident.span.normalize_to_macro_rules(), ident.span.normalize_to_macros_2_0())
320        };
321        ident.span = general_span;
322        let normalized_ident = Ident { span: normalized_span, ..ident };
323
324        // Walk backwards up the ribs in scope.
325        for (i, rib) in ribs.iter().enumerate().rev() {
326            debug!("walk rib\n{:?}", rib.bindings);
327            // Use the rib kind to determine whether we are resolving parameters
328            // (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
329            let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
330            if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
331                // The ident resolves to a type parameter or local variable.
332                return Some(LateDecl::RibDef(self.validate_res_from_ribs(
333                    i,
334                    rib_ident,
335                    *res,
336                    finalize.map(|_| general_span),
337                    *original_rib_ident_def,
338                    ribs,
339                    diag_metadata,
340                )));
341            } else if let RibKind::Block(Some(module)) = rib.kind
342                && let Ok(binding) = self.cm().resolve_ident_in_scope_set(
343                    ident,
344                    ScopeSet::Module(ns, module),
345                    parent_scope,
346                    finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
347                    finalize.is_some(),
348                    ignore_decl,
349                    None,
350                )
351            {
352                // The ident resolves to an item in a block.
353                return Some(LateDecl::Decl(binding));
354            } else if let RibKind::Module(module) = rib.kind {
355                // Encountered a module item, abandon ribs and look into that module and preludes.
356                let parent_scope = &ParentScope { module, ..*parent_scope };
357                let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f });
358                return self
359                    .cm()
360                    .resolve_ident_in_scope_set(
361                        orig_ident,
362                        ScopeSet::All(ns),
363                        parent_scope,
364                        finalize,
365                        finalize.is_some(),
366                        ignore_decl,
367                        None,
368                    )
369                    .ok()
370                    .map(LateDecl::Decl);
371            }
372
373            if let RibKind::MacroDefinition(def) = rib.kind
374                && def == self.macro_def(ident.span.ctxt())
375            {
376                // If an invocation of this macro created `ident`, give up on `ident`
377                // and switch to `ident`'s source from the macro definition.
378                ident.span.remove_mark();
379            }
380        }
381
382        unreachable!()
383    }
384
385    /// Resolve an identifier in the specified set of scopes.
386    #[instrument(level = "debug", skip(self))]
387    pub(crate) fn resolve_ident_in_scope_set<'r>(
388        self: CmResolver<'r, 'ra, 'tcx>,
389        orig_ident: Ident,
390        scope_set: ScopeSet<'ra>,
391        parent_scope: &ParentScope<'ra>,
392        finalize: Option<Finalize>,
393        force: bool,
394        ignore_decl: Option<Decl<'ra>>,
395        ignore_import: Option<Import<'ra>>,
396    ) -> Result<Decl<'ra>, Determinacy> {
397        assert!(force || finalize.is_none()); // `finalize` implies `force`
398
399        // Make sure `self`, `super` etc produce an error when passed to here.
400        if !matches!(scope_set, ScopeSet::Module(..)) && orig_ident.is_path_segment_keyword() {
401            return Err(Determinacy::Determined);
402        }
403
404        let (ns, macro_kind) = match scope_set {
405            ScopeSet::All(ns)
406            | ScopeSet::Module(ns, _)
407            | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
408            ScopeSet::ExternPrelude => (TypeNS, None),
409            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
410        };
411        let derive_fallback_lint_id = match finalize {
412            Some(Finalize { node_id, stage: Stage::Late, .. }) => Some(node_id),
413            _ => None,
414        };
415
416        // This is *the* result, resolution from the scope closest to the resolved identifier.
417        // However, sometimes this result is "weak" because it comes from a glob import or
418        // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
419        // mod m { ... } // solution in outer scope
420        // {
421        //     use prefix::*; // imports another `m` - innermost solution
422        //                    // weak, cannot shadow the outer `m`, need to report ambiguity error
423        //     m::mac!();
424        // }
425        // So we have to save the innermost solution and continue searching in outer scopes
426        // to detect potential ambiguities.
427        let mut innermost_results: SmallVec<[(Decl<'_>, Scope<'_>); 2]> = SmallVec::new();
428        let mut determinacy = Determinacy::Determined;
429
430        // Go through all the scopes and try to resolve the name.
431        let break_result = self.visit_scopes(
432            scope_set,
433            parent_scope,
434            orig_ident.span.ctxt(),
435            derive_fallback_lint_id,
436            |this, scope, use_prelude, ctxt| {
437                let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
438                // The passed `ctxt` is already normalized, so avoid expensive double normalization.
439                let ident = Macros20NormalizedIdent(ident);
440                let res = match this.reborrow().resolve_ident_in_scope(
441                    ident,
442                    ns,
443                    scope,
444                    use_prelude,
445                    scope_set,
446                    parent_scope,
447                    // Shadowed decls don't need to be marked as used or non-speculatively loaded.
448                    if innermost_results.is_empty() { finalize } else { None },
449                    force,
450                    ignore_decl,
451                    ignore_import,
452                ) {
453                    Ok(decl) => Ok(decl),
454                    // We can break with an error at this step, it means we cannot determine the
455                    // resolution right now, but we must block and wait until we can, instead of
456                    // considering outer scopes. Although there's no need to do that if we already
457                    // have a better solution.
458                    Err(ControlFlow::Break(determinacy)) if innermost_results.is_empty() => {
459                        return ControlFlow::Break(Err(determinacy));
460                    }
461                    Err(determinacy) => Err(determinacy.into_value()),
462                };
463                match res {
464                    Ok(decl) if sub_namespace_match(decl.macro_kinds(), macro_kind) => {
465                        // Below we report various ambiguity errors.
466                        // We do not need to report them if we are either in speculative resolution,
467                        // or in late resolution when everything is already imported and expanded
468                        // and no ambiguities exist.
469                        if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) {
470                            return ControlFlow::Break(Ok(decl));
471                        }
472
473                        if let Some(&(innermost_decl, _)) = innermost_results.first() {
474                            // Found another solution, if the first one was "weak", report an error.
475                            if this.get_mut().maybe_push_ambiguity(
476                                orig_ident,
477                                ns,
478                                scope_set,
479                                parent_scope,
480                                decl,
481                                scope,
482                                &innermost_results,
483                            ) {
484                                // No need to search for more potential ambiguities, one is enough.
485                                return ControlFlow::Break(Ok(innermost_decl));
486                            }
487                        }
488
489                        innermost_results.push((decl, scope));
490                    }
491                    Ok(_) | Err(Determinacy::Determined) => {}
492                    Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
493                }
494
495                ControlFlow::Continue(())
496            },
497        );
498
499        // Scope visiting returned some result early.
500        if let Some(break_result) = break_result {
501            return break_result;
502        }
503
504        // Scope visiting walked all the scopes and maybe found something in one of them.
505        match innermost_results.first() {
506            Some(&(decl, ..)) => Ok(decl),
507            None => Err(Determinacy::determined(determinacy == Determinacy::Determined || force)),
508        }
509    }
510
511    fn resolve_ident_in_scope<'r>(
512        mut self: CmResolver<'r, 'ra, 'tcx>,
513        ident: Macros20NormalizedIdent,
514        ns: Namespace,
515        scope: Scope<'ra>,
516        use_prelude: UsePrelude,
517        scope_set: ScopeSet<'ra>,
518        parent_scope: &ParentScope<'ra>,
519        finalize: Option<Finalize>,
520        force: bool,
521        ignore_decl: Option<Decl<'ra>>,
522        ignore_import: Option<Import<'ra>>,
523    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
524        let ret = match scope {
525            Scope::DeriveHelpers(expn_id) => {
526                if let Some(decl) = self
527                    .helper_attrs
528                    .get(&expn_id)
529                    .and_then(|attrs| attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, d)| *d))
530                {
531                    Ok(decl)
532                } else {
533                    Err(Determinacy::Determined)
534                }
535            }
536            Scope::DeriveHelpersCompat => {
537                let mut result = Err(Determinacy::Determined);
538                for derive in parent_scope.derives {
539                    let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
540                    match self.reborrow().resolve_derive_macro_path(
541                        derive,
542                        parent_scope,
543                        force,
544                        ignore_import,
545                    ) {
546                        Ok((Some(ext), _)) => {
547                            if ext.helper_attrs.contains(&ident.name) {
548                                let decl = self.arenas.new_pub_def_decl(
549                                    Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
550                                    derive.span,
551                                    LocalExpnId::ROOT,
552                                );
553                                result = Ok(decl);
554                                break;
555                            }
556                        }
557                        Ok(_) | Err(Determinacy::Determined) => {}
558                        Err(Determinacy::Undetermined) => result = Err(Determinacy::Undetermined),
559                    }
560                }
561                result
562            }
563            Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
564                MacroRulesScope::Def(macro_rules_def) if ident == macro_rules_def.ident => {
565                    Ok(macro_rules_def.decl)
566                }
567                MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
568                _ => Err(Determinacy::Determined),
569            },
570            Scope::ModuleNonGlobs(module, derive_fallback_lint_id) => {
571                let (adjusted_parent_scope, adjusted_finalize) = if matches!(
572                    scope_set,
573                    ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..)
574                ) {
575                    (parent_scope, finalize)
576                } else {
577                    (
578                        &ParentScope { module, ..*parent_scope },
579                        finalize.map(|f| Finalize { used: Used::Scope, ..f }),
580                    )
581                };
582                let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted(
583                    module,
584                    ident,
585                    ns,
586                    adjusted_parent_scope,
587                    if matches!(scope_set, ScopeSet::Module(..)) {
588                        Shadowing::Unrestricted
589                    } else {
590                        Shadowing::Restricted
591                    },
592                    adjusted_finalize,
593                    ignore_decl,
594                    ignore_import,
595                );
596                match decl {
597                    Ok(decl) => {
598                        if let Some(lint_id) = derive_fallback_lint_id {
599                            self.get_mut().lint_buffer.buffer_lint(
600                                PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
601                                lint_id,
602                                ident.span,
603                                errors::ProcMacroDeriveResolutionFallback {
604                                    span: ident.span,
605                                    ns_descr: ns.descr(),
606                                    ident: ident.0,
607                                },
608                            );
609                        }
610                        Ok(decl)
611                    }
612                    Err(ControlFlow::Continue(determinacy)) => Err(determinacy),
613                    Err(ControlFlow::Break(determinacy)) => {
614                        return Err(ControlFlow::Break(Determinacy::determined(
615                            determinacy == Determinacy::Determined || force,
616                        )));
617                    }
618                }
619            }
620            Scope::ModuleGlobs(module, derive_fallback_lint_id) => {
621                let (adjusted_parent_scope, adjusted_finalize) = if matches!(
622                    scope_set,
623                    ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..)
624                ) {
625                    (parent_scope, finalize)
626                } else {
627                    (
628                        &ParentScope { module, ..*parent_scope },
629                        finalize.map(|f| Finalize { used: Used::Scope, ..f }),
630                    )
631                };
632                let binding = self.reborrow().resolve_ident_in_module_globs_unadjusted(
633                    module,
634                    ident,
635                    ns,
636                    adjusted_parent_scope,
637                    if matches!(scope_set, ScopeSet::Module(..)) {
638                        Shadowing::Unrestricted
639                    } else {
640                        Shadowing::Restricted
641                    },
642                    adjusted_finalize,
643                    ignore_decl,
644                    ignore_import,
645                );
646                match binding {
647                    Ok(binding) => {
648                        if let Some(lint_id) = derive_fallback_lint_id {
649                            self.get_mut().lint_buffer.buffer_lint(
650                                PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
651                                lint_id,
652                                ident.span,
653                                errors::ProcMacroDeriveResolutionFallback {
654                                    span: ident.span,
655                                    ns_descr: ns.descr(),
656                                    ident: ident.0,
657                                },
658                            );
659                        }
660                        Ok(binding)
661                    }
662                    Err(ControlFlow::Continue(determinacy)) => Err(determinacy),
663                    Err(ControlFlow::Break(determinacy)) => {
664                        return Err(ControlFlow::Break(Determinacy::determined(
665                            determinacy == Determinacy::Determined || force,
666                        )));
667                    }
668                }
669            }
670            Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() {
671                Some(decl) => Ok(decl),
672                None => Err(Determinacy::determined(
673                    self.graph_root.unexpanded_invocations.borrow().is_empty(),
674                )),
675            },
676            Scope::BuiltinAttrs => match self.builtin_attr_decls.get(&ident.name) {
677                Some(decl) => Ok(*decl),
678                None => Err(Determinacy::Determined),
679            },
680            Scope::ExternPreludeItems => {
681                match self.reborrow().extern_prelude_get_item(ident, finalize.is_some()) {
682                    Some(decl) => Ok(decl),
683                    None => Err(Determinacy::determined(
684                        self.graph_root.unexpanded_invocations.borrow().is_empty(),
685                    )),
686                }
687            }
688            Scope::ExternPreludeFlags => {
689                match self.extern_prelude_get_flag(ident, finalize.is_some()) {
690                    Some(decl) => Ok(decl),
691                    None => Err(Determinacy::Determined),
692                }
693            }
694            Scope::ToolPrelude => match self.registered_tool_decls.get(&ident) {
695                Some(decl) => Ok(*decl),
696                None => Err(Determinacy::Determined),
697            },
698            Scope::StdLibPrelude => {
699                let mut result = Err(Determinacy::Determined);
700                if let Some(prelude) = self.prelude
701                    && let Ok(decl) = self.reborrow().resolve_ident_in_scope_set(
702                        ident.0,
703                        ScopeSet::Module(ns, prelude),
704                        parent_scope,
705                        None,
706                        false,
707                        ignore_decl,
708                        ignore_import,
709                    )
710                    && (matches!(use_prelude, UsePrelude::Yes) || self.is_builtin_macro(decl.res()))
711                {
712                    result = Ok(decl)
713                }
714
715                result
716            }
717            Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) {
718                Some(decl) => {
719                    if matches!(ident.name, sym::f16)
720                        && !self.tcx.features().f16()
721                        && !ident.span.allows_unstable(sym::f16)
722                        && finalize.is_some()
723                    {
724                        feature_err(
725                            self.tcx.sess,
726                            sym::f16,
727                            ident.span,
728                            "the type `f16` is unstable",
729                        )
730                        .emit();
731                    }
732                    if matches!(ident.name, sym::f128)
733                        && !self.tcx.features().f128()
734                        && !ident.span.allows_unstable(sym::f128)
735                        && finalize.is_some()
736                    {
737                        feature_err(
738                            self.tcx.sess,
739                            sym::f128,
740                            ident.span,
741                            "the type `f128` is unstable",
742                        )
743                        .emit();
744                    }
745                    Ok(*decl)
746                }
747                None => Err(Determinacy::Determined),
748            },
749        };
750
751        ret.map_err(ControlFlow::Continue)
752    }
753
754    fn maybe_push_ambiguity(
755        &mut self,
756        orig_ident: Ident,
757        ns: Namespace,
758        scope_set: ScopeSet<'ra>,
759        parent_scope: &ParentScope<'ra>,
760        decl: Decl<'ra>,
761        scope: Scope<'ra>,
762        innermost_results: &[(Decl<'ra>, Scope<'ra>)],
763    ) -> bool {
764        let (innermost_decl, innermost_scope) = innermost_results[0];
765        let (res, innermost_res) = (decl.res(), innermost_decl.res());
766        if res == innermost_res {
767            return false;
768        }
769
770        // FIXME: Use `scope` instead of `res` to detect built-in attrs and derive helpers,
771        // it will exclude imports, make slightly more code legal, and will require lang approval.
772        let module_only = matches!(scope_set, ScopeSet::Module(..));
773        let is_builtin = |res| matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)));
774        let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
775        let derive_helper_compat = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
776
777        let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) {
778            Some(AmbiguityKind::BuiltinAttr)
779        } else if innermost_res == derive_helper_compat {
780            Some(AmbiguityKind::DeriveHelper)
781        } else if res == derive_helper_compat && innermost_res != derive_helper {
782            span_bug!(orig_ident.span, "impossible inner resolution kind")
783        } else if matches!(innermost_scope, Scope::MacroRules(_))
784            && matches!(scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))
785            && !self.disambiguate_macro_rules_vs_modularized(innermost_decl, decl)
786        {
787            Some(AmbiguityKind::MacroRulesVsModularized)
788        } else if matches!(scope, Scope::MacroRules(_))
789            && matches!(innermost_scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))
790        {
791            // should be impossible because of visitation order in
792            // visit_scopes
793            //
794            // we visit all macro_rules scopes (e.g. textual scope macros)
795            // before we visit any modules (e.g. path-based scope macros)
796            span_bug!(
797                orig_ident.span,
798                "ambiguous scoped macro resolutions with path-based \
799                                        scope resolution as first candidate"
800            )
801        } else if innermost_decl.is_glob_import() {
802            Some(AmbiguityKind::GlobVsOuter)
803        } else if !module_only && innermost_decl.may_appear_after(parent_scope.expansion, decl) {
804            Some(AmbiguityKind::MoreExpandedVsOuter)
805        } else if innermost_decl.expansion != LocalExpnId::ROOT
806            && (!module_only || ns == MacroNS)
807            && let Scope::ModuleGlobs(m1, _) = scope
808            && let Scope::ModuleNonGlobs(m2, _) = innermost_scope
809            && m1 == m2
810        {
811            // FIXME: this error is too conservative and technically unnecessary now when module
812            // scope is split into two scopes, at least when not resolving in `ScopeSet::Module`,
813            // remove it with lang team approval.
814            Some(AmbiguityKind::GlobVsExpanded)
815        } else {
816            None
817        };
818
819        if let Some(kind) = ambiguity_error_kind {
820            // Skip ambiguity errors for extern flag bindings "overridden"
821            // by extern item bindings.
822            // FIXME: Remove with lang team approval.
823            let issue_145575_hack = matches!(scope, Scope::ExternPreludeFlags)
824                && innermost_results[1..]
825                    .iter()
826                    .any(|(b, s)| matches!(s, Scope::ExternPreludeItems) && *b != innermost_decl);
827            // Skip ambiguity errors for nonglob module bindings "overridden"
828            // by glob module bindings in the same module.
829            // FIXME: Remove with lang team approval.
830            let issue_149681_hack = match scope {
831                Scope::ModuleGlobs(m1, _)
832                    if innermost_results[1..]
833                        .iter()
834                        .any(|(_, s)| matches!(*s, Scope::ModuleNonGlobs(m2, _) if m1 == m2)) =>
835                {
836                    true
837                }
838                _ => false,
839            };
840
841            if issue_145575_hack || issue_149681_hack {
842                self.issue_145575_hack_applied = true;
843            } else {
844                self.ambiguity_errors.push(AmbiguityError {
845                    kind,
846                    ident: orig_ident,
847                    b1: innermost_decl,
848                    b2: decl,
849                    scope1: innermost_scope,
850                    scope2: scope,
851                    warning: false,
852                });
853                return true;
854            }
855        }
856
857        false
858    }
859
860    #[instrument(level = "debug", skip(self))]
861    pub(crate) fn maybe_resolve_ident_in_module<'r>(
862        self: CmResolver<'r, 'ra, 'tcx>,
863        module: ModuleOrUniformRoot<'ra>,
864        ident: Ident,
865        ns: Namespace,
866        parent_scope: &ParentScope<'ra>,
867        ignore_import: Option<Import<'ra>>,
868    ) -> Result<Decl<'ra>, Determinacy> {
869        self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
870    }
871
872    #[instrument(level = "debug", skip(self))]
873    pub(crate) fn resolve_ident_in_module<'r>(
874        self: CmResolver<'r, 'ra, 'tcx>,
875        module: ModuleOrUniformRoot<'ra>,
876        mut ident: Ident,
877        ns: Namespace,
878        parent_scope: &ParentScope<'ra>,
879        finalize: Option<Finalize>,
880        ignore_decl: Option<Decl<'ra>>,
881        ignore_import: Option<Import<'ra>>,
882    ) -> Result<Decl<'ra>, Determinacy> {
883        let tmp_parent_scope;
884        let mut adjusted_parent_scope = parent_scope;
885        match module {
886            ModuleOrUniformRoot::Module(m) => {
887                if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
888                    tmp_parent_scope =
889                        ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
890                    adjusted_parent_scope = &tmp_parent_scope;
891                }
892            }
893            ModuleOrUniformRoot::ExternPrelude => {
894                ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
895            }
896            ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
897                // No adjustments
898            }
899        }
900        self.resolve_ident_in_virt_module_unadjusted(
901            module,
902            ident,
903            ns,
904            adjusted_parent_scope,
905            finalize,
906            ignore_decl,
907            ignore_import,
908        )
909    }
910
911    /// Attempts to resolve `ident` in namespace `ns` of `module`.
912    #[instrument(level = "debug", skip(self))]
913    fn resolve_ident_in_virt_module_unadjusted<'r>(
914        self: CmResolver<'r, 'ra, 'tcx>,
915        module: ModuleOrUniformRoot<'ra>,
916        ident: Ident,
917        ns: Namespace,
918        parent_scope: &ParentScope<'ra>,
919        finalize: Option<Finalize>,
920        ignore_decl: Option<Decl<'ra>>,
921        ignore_import: Option<Import<'ra>>,
922    ) -> Result<Decl<'ra>, Determinacy> {
923        match module {
924            ModuleOrUniformRoot::Module(module) => self.resolve_ident_in_scope_set(
925                ident,
926                ScopeSet::Module(ns, module),
927                parent_scope,
928                finalize,
929                finalize.is_some(),
930                ignore_decl,
931                ignore_import,
932            ),
933            ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(
934                ident,
935                ScopeSet::ModuleAndExternPrelude(ns, module),
936                parent_scope,
937                finalize,
938                finalize.is_some(),
939                ignore_decl,
940                ignore_import,
941            ),
942            ModuleOrUniformRoot::ExternPrelude => {
943                if ns != TypeNS {
944                    Err(Determined)
945                } else {
946                    self.resolve_ident_in_scope_set(
947                        ident,
948                        ScopeSet::ExternPrelude,
949                        parent_scope,
950                        finalize,
951                        finalize.is_some(),
952                        ignore_decl,
953                        ignore_import,
954                    )
955                }
956            }
957            ModuleOrUniformRoot::CurrentScope => {
958                if ns == TypeNS {
959                    if ident.name == kw::Crate || ident.name == kw::DollarCrate {
960                        let module = self.resolve_crate_root(ident);
961                        return Ok(module.self_decl.unwrap());
962                    } else if ident.name == kw::Super || ident.name == kw::SelfLower {
963                        // FIXME: Implement these with renaming requirements so that e.g.
964                        // `use super;` doesn't work, but `use super as name;` does.
965                        // Fall through here to get an error from `early_resolve_...`.
966                    }
967                }
968
969                self.resolve_ident_in_scope_set(
970                    ident,
971                    ScopeSet::All(ns),
972                    parent_scope,
973                    finalize,
974                    finalize.is_some(),
975                    ignore_decl,
976                    ignore_import,
977                )
978            }
979        }
980    }
981
982    /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in `module`.
983    fn resolve_ident_in_module_non_globs_unadjusted<'r>(
984        mut self: CmResolver<'r, 'ra, 'tcx>,
985        module: Module<'ra>,
986        ident: Macros20NormalizedIdent,
987        ns: Namespace,
988        parent_scope: &ParentScope<'ra>,
989        shadowing: Shadowing,
990        finalize: Option<Finalize>,
991        // This binding should be ignored during in-module resolution, so that we don't get
992        // "self-confirming" import resolutions during import validation and checking.
993        ignore_decl: Option<Decl<'ra>>,
994        ignore_import: Option<Import<'ra>>,
995    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
996        let key = BindingKey::new(ident, ns);
997        // `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding
998        // doesn't need to be mutable. It will fail when there is a cycle of imports, and without
999        // the exclusive access infinite recursion will crash the compiler with stack overflow.
1000        let resolution = &*self
1001            .resolution_or_default(module, key)
1002            .try_borrow_mut_unchecked()
1003            .map_err(|_| ControlFlow::Continue(Determined))?;
1004
1005        let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl);
1006
1007        if let Some(finalize) = finalize {
1008            return self.get_mut().finalize_module_binding(
1009                ident.0,
1010                binding,
1011                parent_scope,
1012                module,
1013                finalize,
1014                shadowing,
1015            );
1016        }
1017
1018        // Items and single imports are not shadowable, if we have one, then it's determined.
1019        if let Some(binding) = binding {
1020            let accessible = self.is_accessible_from(binding.vis(), parent_scope.module);
1021            return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) };
1022        }
1023
1024        // Check if one of single imports can still define the name, block if it can.
1025        if self.reborrow().single_import_can_define_name(
1026            &resolution,
1027            None,
1028            ns,
1029            ignore_import,
1030            ignore_decl,
1031            parent_scope,
1032        ) {
1033            return Err(ControlFlow::Break(Undetermined));
1034        }
1035
1036        // Check if one of unexpanded macros can still define the name.
1037        if !module.unexpanded_invocations.borrow().is_empty() {
1038            return Err(ControlFlow::Continue(Undetermined));
1039        }
1040
1041        // No resolution and no one else can define the name - determinate error.
1042        Err(ControlFlow::Continue(Determined))
1043    }
1044
1045    /// Attempts to resolve `ident` in namespace `ns` of glob bindings in `module`.
1046    fn resolve_ident_in_module_globs_unadjusted<'r>(
1047        mut self: CmResolver<'r, 'ra, 'tcx>,
1048        module: Module<'ra>,
1049        ident: Macros20NormalizedIdent,
1050        ns: Namespace,
1051        parent_scope: &ParentScope<'ra>,
1052        shadowing: Shadowing,
1053        finalize: Option<Finalize>,
1054        ignore_decl: Option<Decl<'ra>>,
1055        ignore_import: Option<Import<'ra>>,
1056    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
1057        let key = BindingKey::new(ident, ns);
1058        // `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding
1059        // doesn't need to be mutable. It will fail when there is a cycle of imports, and without
1060        // the exclusive access infinite recursion will crash the compiler with stack overflow.
1061        let resolution = &*self
1062            .resolution_or_default(module, key)
1063            .try_borrow_mut_unchecked()
1064            .map_err(|_| ControlFlow::Continue(Determined))?;
1065
1066        let binding = resolution.glob_decl.filter(|b| Some(*b) != ignore_decl);
1067
1068        if let Some(finalize) = finalize {
1069            return self.get_mut().finalize_module_binding(
1070                ident.0,
1071                binding,
1072                parent_scope,
1073                module,
1074                finalize,
1075                shadowing,
1076            );
1077        }
1078
1079        // Check if one of single imports can still define the name,
1080        // if it can then our result is not determined and can be invalidated.
1081        if self.reborrow().single_import_can_define_name(
1082            &resolution,
1083            binding,
1084            ns,
1085            ignore_import,
1086            ignore_decl,
1087            parent_scope,
1088        ) {
1089            return Err(ControlFlow::Break(Undetermined));
1090        }
1091
1092        // So we have a resolution that's from a glob import. This resolution is determined
1093        // if it cannot be shadowed by some new item/import expanded from a macro.
1094        // This happens either if there are no unexpanded macros, or expanded names cannot
1095        // shadow globs (that happens in macro namespace or with restricted shadowing).
1096        //
1097        // Additionally, any macro in any module can plant names in the root module if it creates
1098        // `macro_export` macros, so the root module effectively has unresolved invocations if any
1099        // module has unresolved invocations.
1100        // However, it causes resolution/expansion to stuck too often (#53144), so, to make
1101        // progress, we have to ignore those potential unresolved invocations from other modules
1102        // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted
1103        // shadowing is enabled, see `macro_expanded_macro_export_errors`).
1104        if let Some(binding) = binding {
1105            return if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
1106                let accessible = self.is_accessible_from(binding.vis(), parent_scope.module);
1107                if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }
1108            } else {
1109                Err(ControlFlow::Break(Undetermined))
1110            };
1111        }
1112
1113        // Now we are in situation when new item/import can appear only from a glob or a macro
1114        // expansion. With restricted shadowing names from globs and macro expansions cannot
1115        // shadow names from outer scopes, so we can freely fallback from module search to search
1116        // in outer scopes. For `resolve_ident_in_scope_set` to continue search in outer
1117        // scopes we return `Undetermined` with `ControlFlow::Continue`.
1118        // Check if one of unexpanded macros can still define the name,
1119        // if it can then our "no resolution" result is not determined and can be invalidated.
1120        if !module.unexpanded_invocations.borrow().is_empty() {
1121            return Err(ControlFlow::Continue(Undetermined));
1122        }
1123
1124        // Check if one of glob imports can still define the name,
1125        // if it can then our "no resolution" result is not determined and can be invalidated.
1126        for glob_import in module.globs.borrow().iter() {
1127            if ignore_import == Some(*glob_import) {
1128                continue;
1129            }
1130            if !self.is_accessible_from(glob_import.vis, parent_scope.module) {
1131                continue;
1132            }
1133            let module = match glob_import.imported_module.get() {
1134                Some(ModuleOrUniformRoot::Module(module)) => module,
1135                Some(_) => continue,
1136                None => return Err(ControlFlow::Continue(Undetermined)),
1137            };
1138            let tmp_parent_scope;
1139            let (mut adjusted_parent_scope, mut ident) = (parent_scope, ident);
1140            match ident.0.span.glob_adjust(module.expansion, glob_import.span) {
1141                Some(Some(def)) => {
1142                    tmp_parent_scope =
1143                        ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
1144                    adjusted_parent_scope = &tmp_parent_scope;
1145                }
1146                Some(None) => {}
1147                None => continue,
1148            };
1149            let result = self.reborrow().resolve_ident_in_scope_set(
1150                ident.0,
1151                ScopeSet::Module(ns, module),
1152                adjusted_parent_scope,
1153                None,
1154                false,
1155                ignore_decl,
1156                ignore_import,
1157            );
1158
1159            match result {
1160                Err(Determined) => continue,
1161                Ok(binding)
1162                    if !self.is_accessible_from(binding.vis(), glob_import.parent_scope.module) =>
1163                {
1164                    continue;
1165                }
1166                Ok(_) | Err(Undetermined) => return Err(ControlFlow::Continue(Undetermined)),
1167            }
1168        }
1169
1170        // No resolution and no one else can define the name - determinate error.
1171        Err(ControlFlow::Continue(Determined))
1172    }
1173
1174    fn finalize_module_binding(
1175        &mut self,
1176        ident: Ident,
1177        binding: Option<Decl<'ra>>,
1178        parent_scope: &ParentScope<'ra>,
1179        module: Module<'ra>,
1180        finalize: Finalize,
1181        shadowing: Shadowing,
1182    ) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
1183        let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1184
1185        let Some(binding) = binding else {
1186            return Err(ControlFlow::Continue(Determined));
1187        };
1188
1189        if !self.is_accessible_from(binding.vis(), parent_scope.module) {
1190            if report_private {
1191                self.privacy_errors.push(PrivacyError {
1192                    ident,
1193                    decl: binding,
1194                    dedup_span: path_span,
1195                    outermost_res: None,
1196                    source: None,
1197                    parent_scope: *parent_scope,
1198                    single_nested: path_span != root_span,
1199                });
1200            } else {
1201                return Err(ControlFlow::Break(Determined));
1202            }
1203        }
1204
1205        if shadowing == Shadowing::Unrestricted
1206            && binding.expansion != LocalExpnId::ROOT
1207            && let DeclKind::Import { import, .. } = binding.kind
1208            && matches!(import.kind, ImportKind::MacroExport)
1209        {
1210            self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
1211        }
1212
1213        // If we encounter a re-export for a type with private fields, it will not be able to
1214        // be constructed through this re-export. We track that case here to expand later
1215        // privacy errors with appropriate information.
1216        if let Res::Def(_, def_id) = binding.res() {
1217            let struct_ctor = match def_id.as_local() {
1218                Some(def_id) => self.struct_constructors.get(&def_id).cloned(),
1219                None => {
1220                    let ctor = self.cstore().ctor_untracked(self.tcx(), def_id);
1221                    ctor.map(|(ctor_kind, ctor_def_id)| {
1222                        let ctor_res = Res::Def(
1223                            DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind),
1224                            ctor_def_id,
1225                        );
1226                        let ctor_vis = self.tcx.visibility(ctor_def_id);
1227                        let field_visibilities = self
1228                            .tcx
1229                            .associated_item_def_ids(def_id)
1230                            .iter()
1231                            .map(|field_id| self.tcx.visibility(field_id))
1232                            .collect();
1233                        (ctor_res, ctor_vis, field_visibilities)
1234                    })
1235                }
1236            };
1237            if let Some((_, _, fields)) = struct_ctor
1238                && fields.iter().any(|vis| !self.is_accessible_from(*vis, module))
1239            {
1240                self.inaccessible_ctor_reexport.insert(path_span, binding.span);
1241            }
1242        }
1243
1244        self.record_use(ident, binding, used);
1245        return Ok(binding);
1246    }
1247
1248    // Checks if a single import can define the `Ident` corresponding to `binding`.
1249    // This is used to check whether we can definitively accept a glob as a resolution.
1250    fn single_import_can_define_name<'r>(
1251        mut self: CmResolver<'r, 'ra, 'tcx>,
1252        resolution: &NameResolution<'ra>,
1253        binding: Option<Decl<'ra>>,
1254        ns: Namespace,
1255        ignore_import: Option<Import<'ra>>,
1256        ignore_decl: Option<Decl<'ra>>,
1257        parent_scope: &ParentScope<'ra>,
1258    ) -> bool {
1259        for single_import in &resolution.single_imports {
1260            if let Some(decl) = resolution.non_glob_decl
1261                && let DeclKind::Import { import, .. } = decl.kind
1262                && import == *single_import
1263            {
1264                // Single import has already defined the name and we are aware of it,
1265                // no need to block the globs.
1266                continue;
1267            }
1268            if ignore_import == Some(*single_import) {
1269                continue;
1270            }
1271            if !self.is_accessible_from(single_import.vis, parent_scope.module) {
1272                continue;
1273            }
1274            if let Some(ignored) = ignore_decl
1275                && let DeclKind::Import { import, .. } = ignored.kind
1276                && import == *single_import
1277            {
1278                continue;
1279            }
1280
1281            let Some(module) = single_import.imported_module.get() else {
1282                return true;
1283            };
1284            let ImportKind::Single { source, target, decls, .. } = &single_import.kind else {
1285                unreachable!();
1286            };
1287            if source != target {
1288                if decls.iter().all(|d| d.get().decl().is_none()) {
1289                    return true;
1290                } else if decls[ns].get().decl().is_none() && binding.is_some() {
1291                    return true;
1292                }
1293            }
1294
1295            match self.reborrow().resolve_ident_in_module(
1296                module,
1297                *source,
1298                ns,
1299                &single_import.parent_scope,
1300                None,
1301                ignore_decl,
1302                ignore_import,
1303            ) {
1304                Err(Determined) => continue,
1305                Ok(binding)
1306                    if !self
1307                        .is_accessible_from(binding.vis(), single_import.parent_scope.module) =>
1308                {
1309                    continue;
1310                }
1311                Ok(_) | Err(Undetermined) => return true,
1312            }
1313        }
1314
1315        false
1316    }
1317
1318    /// Validate a local resolution (from ribs).
1319    #[instrument(level = "debug", skip(self, all_ribs))]
1320    fn validate_res_from_ribs(
1321        &mut self,
1322        rib_index: usize,
1323        rib_ident: Ident,
1324        res: Res,
1325        finalize: Option<Span>,
1326        original_rib_ident_def: Ident,
1327        all_ribs: &[Rib<'ra>],
1328        diag_metadata: Option<&DiagMetadata<'_>>,
1329    ) -> Res {
1330        debug!("validate_res_from_ribs({:?})", res);
1331        let ribs = &all_ribs[rib_index + 1..];
1332
1333        // An invalid forward use of a generic parameter from a previous default
1334        // or in a const param ty.
1335        if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
1336            if let Some(span) = finalize {
1337                let res_error = if rib_ident.name == kw::SelfUpper {
1338                    ResolutionError::ForwardDeclaredSelf(reason)
1339                } else {
1340                    ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
1341                };
1342                self.report_error(span, res_error);
1343            }
1344            assert_eq!(res, Res::Err);
1345            return Res::Err;
1346        }
1347
1348        match res {
1349            Res::Local(_) => {
1350                use ResolutionError::*;
1351                let mut res_err = None;
1352
1353                for rib in ribs {
1354                    match rib.kind {
1355                        RibKind::Normal
1356                        | RibKind::Block(..)
1357                        | RibKind::FnOrCoroutine
1358                        | RibKind::Module(..)
1359                        | RibKind::MacroDefinition(..)
1360                        | RibKind::ForwardGenericParamBan(_) => {
1361                            // Nothing to do. Continue.
1362                        }
1363                        RibKind::Item(..) | RibKind::AssocItem => {
1364                            // This was an attempt to access an upvar inside a
1365                            // named function item. This is not allowed, so we
1366                            // report an error.
1367                            if let Some(span) = finalize {
1368                                // We don't immediately trigger a resolve error, because
1369                                // we want certain other resolution errors (namely those
1370                                // emitted for `ConstantItemRibKind` below) to take
1371                                // precedence.
1372                                res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
1373                            }
1374                        }
1375                        RibKind::ConstantItem(_, item) => {
1376                            // Still doesn't deal with upvars
1377                            if let Some(span) = finalize {
1378                                let (span, resolution_error) = match item {
1379                                    None if rib_ident.name == kw::SelfLower => {
1380                                        (span, LowercaseSelf)
1381                                    }
1382                                    None => {
1383                                        // If we have a `let name = expr;`, we have the span for
1384                                        // `name` and use that to see if it is followed by a type
1385                                        // specifier. If not, then we know we need to suggest
1386                                        // `const name: Ty = expr;`. This is a heuristic, it will
1387                                        // break down in the presence of macros.
1388                                        let sm = self.tcx.sess.source_map();
1389                                        let type_span = match sm.span_look_ahead(
1390                                            original_rib_ident_def.span,
1391                                            ":",
1392                                            None,
1393                                        ) {
1394                                            None => {
1395                                                Some(original_rib_ident_def.span.shrink_to_hi())
1396                                            }
1397                                            Some(_) => None,
1398                                        };
1399                                        (
1400                                            rib_ident.span,
1401                                            AttemptToUseNonConstantValueInConstant {
1402                                                ident: original_rib_ident_def,
1403                                                suggestion: "const",
1404                                                current: "let",
1405                                                type_span,
1406                                            },
1407                                        )
1408                                    }
1409                                    Some((ident, kind)) => (
1410                                        span,
1411                                        AttemptToUseNonConstantValueInConstant {
1412                                            ident,
1413                                            suggestion: "let",
1414                                            current: kind.as_str(),
1415                                            type_span: None,
1416                                        },
1417                                    ),
1418                                };
1419                                self.report_error(span, resolution_error);
1420                            }
1421                            return Res::Err;
1422                        }
1423                        RibKind::ConstParamTy => {
1424                            if let Some(span) = finalize {
1425                                self.report_error(
1426                                    span,
1427                                    ParamInTyOfConstParam { name: rib_ident.name },
1428                                );
1429                            }
1430                            return Res::Err;
1431                        }
1432                        RibKind::InlineAsmSym => {
1433                            if let Some(span) = finalize {
1434                                self.report_error(span, InvalidAsmSym);
1435                            }
1436                            return Res::Err;
1437                        }
1438                    }
1439                }
1440                if let Some((span, res_err)) = res_err {
1441                    self.report_error(span, res_err);
1442                    return Res::Err;
1443                }
1444            }
1445            Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
1446                for rib in ribs {
1447                    let (has_generic_params, def_kind) = match rib.kind {
1448                        RibKind::Normal
1449                        | RibKind::Block(..)
1450                        | RibKind::FnOrCoroutine
1451                        | RibKind::Module(..)
1452                        | RibKind::MacroDefinition(..)
1453                        | RibKind::InlineAsmSym
1454                        | RibKind::AssocItem
1455                        | RibKind::ForwardGenericParamBan(_) => {
1456                            // Nothing to do. Continue.
1457                            continue;
1458                        }
1459
1460                        RibKind::ConstParamTy => {
1461                            if !self.tcx.features().generic_const_parameter_types() {
1462                                if let Some(span) = finalize {
1463                                    self.report_error(
1464                                        span,
1465                                        ResolutionError::ParamInTyOfConstParam {
1466                                            name: rib_ident.name,
1467                                        },
1468                                    );
1469                                }
1470                                return Res::Err;
1471                            } else {
1472                                continue;
1473                            }
1474                        }
1475
1476                        RibKind::ConstantItem(trivial, _) => {
1477                            if let ConstantHasGenerics::No(cause) = trivial
1478                                && !matches!(res, Res::SelfTyAlias { .. })
1479                            {
1480                                if let Some(span) = finalize {
1481                                    let error = match cause {
1482                                        NoConstantGenericsReason::IsEnumDiscriminant => {
1483                                            ResolutionError::ParamInEnumDiscriminant {
1484                                                name: rib_ident.name,
1485                                                param_kind: ParamKindInEnumDiscriminant::Type,
1486                                            }
1487                                        }
1488                                        NoConstantGenericsReason::NonTrivialConstArg => {
1489                                            ResolutionError::ParamInNonTrivialAnonConst {
1490                                                name: rib_ident.name,
1491                                                param_kind: ParamKindInNonTrivialAnonConst::Type,
1492                                            }
1493                                        }
1494                                    };
1495                                    let _: ErrorGuaranteed = self.report_error(span, error);
1496                                }
1497
1498                                return Res::Err;
1499                            }
1500
1501                            continue;
1502                        }
1503
1504                        // This was an attempt to use a type parameter outside its scope.
1505                        RibKind::Item(has_generic_params, def_kind) => {
1506                            (has_generic_params, def_kind)
1507                        }
1508                    };
1509
1510                    if let Some(span) = finalize {
1511                        let item = if let Some(diag_metadata) = diag_metadata
1512                            && let Some(current_item) = diag_metadata.current_item
1513                        {
1514                            let span = current_item
1515                                .kind
1516                                .ident()
1517                                .map(|i| i.span)
1518                                .unwrap_or(current_item.span);
1519                            Some((span, current_item.kind.clone()))
1520                        } else {
1521                            None
1522                        };
1523                        self.report_error(
1524                            span,
1525                            ResolutionError::GenericParamsFromOuterItem {
1526                                outer_res: res,
1527                                has_generic_params,
1528                                def_kind,
1529                                inner_item: item,
1530                                current_self_ty: diag_metadata
1531                                    .and_then(|m| m.current_self_type.as_ref())
1532                                    .and_then(|ty| {
1533                                        self.tcx.sess.source_map().span_to_snippet(ty.span).ok()
1534                                    }),
1535                            },
1536                        );
1537                    }
1538                    return Res::Err;
1539                }
1540            }
1541            Res::Def(DefKind::ConstParam, _) => {
1542                for rib in ribs {
1543                    let (has_generic_params, def_kind) = match rib.kind {
1544                        RibKind::Normal
1545                        | RibKind::Block(..)
1546                        | RibKind::FnOrCoroutine
1547                        | RibKind::Module(..)
1548                        | RibKind::MacroDefinition(..)
1549                        | RibKind::InlineAsmSym
1550                        | RibKind::AssocItem
1551                        | RibKind::ForwardGenericParamBan(_) => continue,
1552
1553                        RibKind::ConstParamTy => {
1554                            if !self.tcx.features().generic_const_parameter_types() {
1555                                if let Some(span) = finalize {
1556                                    self.report_error(
1557                                        span,
1558                                        ResolutionError::ParamInTyOfConstParam {
1559                                            name: rib_ident.name,
1560                                        },
1561                                    );
1562                                }
1563                                return Res::Err;
1564                            } else {
1565                                continue;
1566                            }
1567                        }
1568
1569                        RibKind::ConstantItem(trivial, _) => {
1570                            if let ConstantHasGenerics::No(cause) = trivial {
1571                                if let Some(span) = finalize {
1572                                    let error = match cause {
1573                                        NoConstantGenericsReason::IsEnumDiscriminant => {
1574                                            ResolutionError::ParamInEnumDiscriminant {
1575                                                name: rib_ident.name,
1576                                                param_kind: ParamKindInEnumDiscriminant::Const,
1577                                            }
1578                                        }
1579                                        NoConstantGenericsReason::NonTrivialConstArg => {
1580                                            ResolutionError::ParamInNonTrivialAnonConst {
1581                                                name: rib_ident.name,
1582                                                param_kind: ParamKindInNonTrivialAnonConst::Const {
1583                                                    name: rib_ident.name,
1584                                                },
1585                                            }
1586                                        }
1587                                    };
1588                                    self.report_error(span, error);
1589                                }
1590
1591                                return Res::Err;
1592                            }
1593
1594                            continue;
1595                        }
1596
1597                        RibKind::Item(has_generic_params, def_kind) => {
1598                            (has_generic_params, def_kind)
1599                        }
1600                    };
1601
1602                    // This was an attempt to use a const parameter outside its scope.
1603                    if let Some(span) = finalize {
1604                        let item = if let Some(diag_metadata) = diag_metadata
1605                            && let Some(current_item) = diag_metadata.current_item
1606                        {
1607                            let span = current_item
1608                                .kind
1609                                .ident()
1610                                .map(|i| i.span)
1611                                .unwrap_or(current_item.span);
1612                            Some((span, current_item.kind.clone()))
1613                        } else {
1614                            None
1615                        };
1616                        self.report_error(
1617                            span,
1618                            ResolutionError::GenericParamsFromOuterItem {
1619                                outer_res: res,
1620                                has_generic_params,
1621                                def_kind,
1622                                inner_item: item,
1623                                current_self_ty: diag_metadata
1624                                    .and_then(|m| m.current_self_type.as_ref())
1625                                    .and_then(|ty| {
1626                                        self.tcx.sess.source_map().span_to_snippet(ty.span).ok()
1627                                    }),
1628                            },
1629                        );
1630                    }
1631                    return Res::Err;
1632                }
1633            }
1634            _ => {}
1635        }
1636
1637        res
1638    }
1639
1640    #[instrument(level = "debug", skip(self))]
1641    pub(crate) fn maybe_resolve_path<'r>(
1642        self: CmResolver<'r, 'ra, 'tcx>,
1643        path: &[Segment],
1644        opt_ns: Option<Namespace>, // `None` indicates a module path in import
1645        parent_scope: &ParentScope<'ra>,
1646        ignore_import: Option<Import<'ra>>,
1647    ) -> PathResult<'ra> {
1648        self.resolve_path_with_ribs(
1649            path,
1650            opt_ns,
1651            parent_scope,
1652            None,
1653            None,
1654            None,
1655            None,
1656            ignore_import,
1657            None,
1658        )
1659    }
1660    #[instrument(level = "debug", skip(self))]
1661    pub(crate) fn resolve_path<'r>(
1662        self: CmResolver<'r, 'ra, 'tcx>,
1663        path: &[Segment],
1664        opt_ns: Option<Namespace>, // `None` indicates a module path in import
1665        parent_scope: &ParentScope<'ra>,
1666        finalize: Option<Finalize>,
1667        ignore_decl: Option<Decl<'ra>>,
1668        ignore_import: Option<Import<'ra>>,
1669    ) -> PathResult<'ra> {
1670        self.resolve_path_with_ribs(
1671            path,
1672            opt_ns,
1673            parent_scope,
1674            None,
1675            finalize,
1676            None,
1677            ignore_decl,
1678            ignore_import,
1679            None,
1680        )
1681    }
1682
1683    pub(crate) fn resolve_path_with_ribs<'r>(
1684        mut self: CmResolver<'r, 'ra, 'tcx>,
1685        path: &[Segment],
1686        opt_ns: Option<Namespace>, // `None` indicates a module path in import
1687        parent_scope: &ParentScope<'ra>,
1688        source: Option<PathSource<'_, '_, '_>>,
1689        finalize: Option<Finalize>,
1690        ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
1691        ignore_decl: Option<Decl<'ra>>,
1692        ignore_import: Option<Import<'ra>>,
1693        diag_metadata: Option<&DiagMetadata<'_>>,
1694    ) -> PathResult<'ra> {
1695        let mut module = None;
1696        let mut module_had_parse_errors = false;
1697        let mut allow_super = true;
1698        let mut second_binding = None;
1699
1700        // We'll provide more context to the privacy errors later, up to `len`.
1701        let privacy_errors_len = self.privacy_errors.len();
1702        fn record_segment_res<'r, 'ra, 'tcx>(
1703            mut this: CmResolver<'r, 'ra, 'tcx>,
1704            finalize: Option<Finalize>,
1705            res: Res,
1706            id: Option<NodeId>,
1707        ) {
1708            if finalize.is_some()
1709                && let Some(id) = id
1710                && !this.partial_res_map.contains_key(&id)
1711            {
1712                assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
1713                this.get_mut().record_partial_res(id, PartialRes::new(res));
1714            }
1715        }
1716
1717        for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
1718            debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
1719
1720            let is_last = segment_idx + 1 == path.len();
1721            let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
1722            let name = ident.name;
1723
1724            allow_super &= ns == TypeNS && (name == kw::SelfLower || name == kw::Super);
1725
1726            if ns == TypeNS {
1727                if allow_super && name == kw::Super {
1728                    let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1729                    let self_module = match segment_idx {
1730                        0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)),
1731                        _ => match module {
1732                            Some(ModuleOrUniformRoot::Module(module)) => Some(module),
1733                            _ => None,
1734                        },
1735                    };
1736                    if let Some(self_module) = self_module
1737                        && let Some(parent) = self_module.parent
1738                    {
1739                        module =
1740                            Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
1741                        continue;
1742                    }
1743                    return PathResult::failed(
1744                        ident,
1745                        false,
1746                        finalize.is_some(),
1747                        module_had_parse_errors,
1748                        module,
1749                        || ("there are too many leading `super` keywords".to_string(), None),
1750                    );
1751                }
1752                if segment_idx == 0 {
1753                    if name == kw::SelfLower {
1754                        let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1755                        let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
1756                        if let Some(res) = self_mod.res() {
1757                            record_segment_res(self.reborrow(), finalize, res, id);
1758                        }
1759                        module = Some(ModuleOrUniformRoot::Module(self_mod));
1760                        continue;
1761                    }
1762                    if name == kw::PathRoot && ident.span.at_least_rust_2018() {
1763                        module = Some(ModuleOrUniformRoot::ExternPrelude);
1764                        continue;
1765                    }
1766                    if name == kw::PathRoot
1767                        && ident.span.is_rust_2015()
1768                        && self.tcx.sess.at_least_rust_2018()
1769                    {
1770                        // `::a::b` from 2015 macro on 2018 global edition
1771                        let crate_root = self.resolve_crate_root(ident);
1772                        module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
1773                        continue;
1774                    }
1775                    if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
1776                        // `::a::b`, `crate::a::b` or `$crate::a::b`
1777                        let crate_root = self.resolve_crate_root(ident);
1778                        if let Some(res) = crate_root.res() {
1779                            record_segment_res(self.reborrow(), finalize, res, id);
1780                        }
1781                        module = Some(ModuleOrUniformRoot::Module(crate_root));
1782                        continue;
1783                    }
1784                }
1785            }
1786
1787            // Report special messages for path segment keywords in wrong positions.
1788            if ident.is_path_segment_keyword() && segment_idx != 0 {
1789                return PathResult::failed(
1790                    ident,
1791                    false,
1792                    finalize.is_some(),
1793                    module_had_parse_errors,
1794                    module,
1795                    || {
1796                        let name_str = if name == kw::PathRoot {
1797                            "crate root".to_string()
1798                        } else {
1799                            format!("`{name}`")
1800                        };
1801                        let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
1802                            format!("global paths cannot start with {name_str}")
1803                        } else {
1804                            format!("{name_str} in paths can only be used in start position")
1805                        };
1806                        (label, None)
1807                    },
1808                );
1809            }
1810
1811            let binding = if let Some(module) = module {
1812                self.reborrow().resolve_ident_in_module(
1813                    module,
1814                    ident,
1815                    ns,
1816                    parent_scope,
1817                    finalize,
1818                    ignore_decl,
1819                    ignore_import,
1820                )
1821            } else if let Some(ribs) = ribs
1822                && let Some(TypeNS | ValueNS) = opt_ns
1823            {
1824                assert!(ignore_import.is_none());
1825                match self.get_mut().resolve_ident_in_lexical_scope(
1826                    ident,
1827                    ns,
1828                    parent_scope,
1829                    finalize,
1830                    &ribs[ns],
1831                    ignore_decl,
1832                    diag_metadata,
1833                ) {
1834                    // we found a locally-imported or available item/module
1835                    Some(LateDecl::Decl(binding)) => Ok(binding),
1836                    // we found a local variable or type param
1837                    Some(LateDecl::RibDef(res)) => {
1838                        record_segment_res(self.reborrow(), finalize, res, id);
1839                        return PathResult::NonModule(PartialRes::with_unresolved_segments(
1840                            res,
1841                            path.len() - 1,
1842                        ));
1843                    }
1844                    _ => Err(Determinacy::determined(finalize.is_some())),
1845                }
1846            } else {
1847                self.reborrow().resolve_ident_in_scope_set(
1848                    ident,
1849                    ScopeSet::All(ns),
1850                    parent_scope,
1851                    finalize,
1852                    finalize.is_some(),
1853                    ignore_decl,
1854                    ignore_import,
1855                )
1856            };
1857
1858            match binding {
1859                Ok(binding) => {
1860                    if segment_idx == 1 {
1861                        second_binding = Some(binding);
1862                    }
1863                    let res = binding.res();
1864
1865                    // Mark every privacy error in this path with the res to the last element. This allows us
1866                    // to detect the item the user cares about and either find an alternative import, or tell
1867                    // the user it is not accessible.
1868                    if finalize.is_some() {
1869                        for error in &mut self.get_mut().privacy_errors[privacy_errors_len..] {
1870                            error.outermost_res = Some((res, ident));
1871                            error.source = match source {
1872                                Some(PathSource::Struct(Some(expr)))
1873                                | Some(PathSource::Expr(Some(expr))) => Some(expr.clone()),
1874                                _ => None,
1875                            };
1876                        }
1877                    }
1878
1879                    let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
1880                    if let Some(def_id) = binding.res().module_like_def_id() {
1881                        if self.mods_with_parse_errors.contains(&def_id) {
1882                            module_had_parse_errors = true;
1883                        }
1884                        module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id)));
1885                        record_segment_res(self.reborrow(), finalize, res, id);
1886                    } else if res == Res::ToolMod && !is_last && opt_ns.is_some() {
1887                        if binding.is_import() {
1888                            self.dcx().emit_err(errors::ToolModuleImported {
1889                                span: ident.span,
1890                                import: binding.span,
1891                            });
1892                        }
1893                        let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
1894                        return PathResult::NonModule(PartialRes::new(res));
1895                    } else if res == Res::Err {
1896                        return PathResult::NonModule(PartialRes::new(Res::Err));
1897                    } else if opt_ns.is_some() && (is_last || maybe_assoc) {
1898                        if let Some(finalize) = finalize {
1899                            self.get_mut().lint_if_path_starts_with_module(
1900                                finalize,
1901                                path,
1902                                second_binding,
1903                            );
1904                        }
1905                        record_segment_res(self.reborrow(), finalize, res, id);
1906                        return PathResult::NonModule(PartialRes::with_unresolved_segments(
1907                            res,
1908                            path.len() - segment_idx - 1,
1909                        ));
1910                    } else {
1911                        return PathResult::failed(
1912                            ident,
1913                            is_last,
1914                            finalize.is_some(),
1915                            module_had_parse_errors,
1916                            module,
1917                            || {
1918                                let label = format!(
1919                                    "`{ident}` is {} {}, not a module",
1920                                    res.article(),
1921                                    res.descr()
1922                                );
1923                                (label, None)
1924                            },
1925                        );
1926                    }
1927                }
1928                Err(Undetermined) => return PathResult::Indeterminate,
1929                Err(Determined) => {
1930                    if let Some(ModuleOrUniformRoot::Module(module)) = module
1931                        && opt_ns.is_some()
1932                        && !module.is_normal()
1933                    {
1934                        return PathResult::NonModule(PartialRes::with_unresolved_segments(
1935                            module.res().unwrap(),
1936                            path.len() - segment_idx,
1937                        ));
1938                    }
1939
1940                    let mut this = self.reborrow();
1941                    return PathResult::failed(
1942                        ident,
1943                        is_last,
1944                        finalize.is_some(),
1945                        module_had_parse_errors,
1946                        module,
1947                        || {
1948                            this.get_mut().report_path_resolution_error(
1949                                path,
1950                                opt_ns,
1951                                parent_scope,
1952                                ribs,
1953                                ignore_decl,
1954                                ignore_import,
1955                                module,
1956                                segment_idx,
1957                                ident,
1958                                diag_metadata,
1959                            )
1960                        },
1961                    );
1962                }
1963            }
1964        }
1965
1966        if let Some(finalize) = finalize {
1967            self.get_mut().lint_if_path_starts_with_module(finalize, path, second_binding);
1968        }
1969
1970        PathResult::Module(match module {
1971            Some(module) => module,
1972            None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
1973            _ => bug!("resolve_path: non-empty path `{:?}` has no module", path),
1974        })
1975    }
1976}