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