rustc_resolve/
late.rs

1// ignore-tidy-filelength
2//! "Late resolution" is the pass that resolves most of names in a crate beside imports and macros.
3//! It runs when the crate is fully expanded and its module structure is fully built.
4//! So it just walks through the crate and resolves all the expressions, types, etc.
5//!
6//! If you wonder why there's no `early.rs`, that's because it's split into three files -
7//! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`.
8
9use std::assert_matches::debug_assert_matches;
10use std::borrow::Cow;
11use std::collections::BTreeSet;
12use std::collections::hash_map::Entry;
13use std::mem::{replace, swap, take};
14
15use rustc_ast::ptr::P;
16use rustc_ast::visit::{
17    AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, try_visit, visit_opt, walk_list,
18};
19use rustc_ast::*;
20use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
21use rustc_data_structures::unord::{UnordMap, UnordSet};
22use rustc_errors::codes::*;
23use rustc_errors::{
24    Applicability, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions,
25};
26use rustc_hir::def::Namespace::{self, *};
27use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
28use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId};
29use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate};
30use rustc_middle::middle::resolve_bound_vars::Set1;
31use rustc_middle::ty::DelegationFnSig;
32use rustc_middle::{bug, span_bug};
33use rustc_session::config::{CrateType, ResolveDocLinks};
34use rustc_session::lint::{self, BuiltinLintDiag};
35use rustc_session::parse::feature_err;
36use rustc_span::source_map::{Spanned, respan};
37use rustc_span::{BytePos, Ident, Span, Symbol, SyntaxContext, kw, sym};
38use smallvec::{SmallVec, smallvec};
39use tracing::{debug, instrument, trace};
40
41use crate::{
42    BindingError, BindingKey, Finalize, LexicalScopeBinding, Module, ModuleOrUniformRoot,
43    NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, TyCtxt, UseError,
44    Used, errors, path_names_to_string, rustdoc,
45};
46
47mod diagnostics;
48
49type Res = def::Res<NodeId>;
50
51use diagnostics::{ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime};
52
53#[derive(Copy, Clone, Debug)]
54struct BindingInfo {
55    span: Span,
56    annotation: BindingMode,
57}
58
59#[derive(Copy, Clone, PartialEq, Eq, Debug)]
60pub(crate) enum PatternSource {
61    Match,
62    Let,
63    For,
64    FnParam,
65}
66
67#[derive(Copy, Clone, Debug, PartialEq, Eq)]
68enum IsRepeatExpr {
69    No,
70    Yes,
71}
72
73struct IsNeverPattern;
74
75/// Describes whether an `AnonConst` is a type level const arg or
76/// some other form of anon const (i.e. inline consts or enum discriminants)
77#[derive(Copy, Clone, Debug, PartialEq, Eq)]
78enum AnonConstKind {
79    EnumDiscriminant,
80    FieldDefaultValue,
81    InlineConst,
82    ConstArg(IsRepeatExpr),
83}
84
85impl PatternSource {
86    fn descr(self) -> &'static str {
87        match self {
88            PatternSource::Match => "match binding",
89            PatternSource::Let => "let binding",
90            PatternSource::For => "for binding",
91            PatternSource::FnParam => "function parameter",
92        }
93    }
94}
95
96impl IntoDiagArg for PatternSource {
97    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
98        DiagArgValue::Str(Cow::Borrowed(self.descr()))
99    }
100}
101
102/// Denotes whether the context for the set of already bound bindings is a `Product`
103/// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
104/// See those functions for more information.
105#[derive(PartialEq)]
106enum PatBoundCtx {
107    /// A product pattern context, e.g., `Variant(a, b)`.
108    Product,
109    /// An or-pattern context, e.g., `p_0 | ... | p_n`.
110    Or,
111}
112
113/// Does this the item (from the item rib scope) allow generic parameters?
114#[derive(Copy, Clone, Debug)]
115pub(crate) enum HasGenericParams {
116    Yes(Span),
117    No,
118}
119
120/// May this constant have generics?
121#[derive(Copy, Clone, Debug, Eq, PartialEq)]
122pub(crate) enum ConstantHasGenerics {
123    Yes,
124    No(NoConstantGenericsReason),
125}
126
127impl ConstantHasGenerics {
128    fn force_yes_if(self, b: bool) -> Self {
129        if b { Self::Yes } else { self }
130    }
131}
132
133/// Reason for why an anon const is not allowed to reference generic parameters
134#[derive(Copy, Clone, Debug, Eq, PartialEq)]
135pub(crate) enum NoConstantGenericsReason {
136    /// Const arguments are only allowed to use generic parameters when:
137    /// - `feature(generic_const_exprs)` is enabled
138    /// or
139    /// - the const argument is a sole const generic parameter, i.e. `foo::<{ N }>()`
140    ///
141    /// If neither of the above are true then this is used as the cause.
142    NonTrivialConstArg,
143    /// Enum discriminants are not allowed to reference generic parameters ever, this
144    /// is used when an anon const is in the following position:
145    ///
146    /// ```rust,compile_fail
147    /// enum Foo<const N: isize> {
148    ///     Variant = { N }, // this anon const is not allowed to use generics
149    /// }
150    /// ```
151    IsEnumDiscriminant,
152}
153
154#[derive(Copy, Clone, Debug, Eq, PartialEq)]
155pub(crate) enum ConstantItemKind {
156    Const,
157    Static,
158}
159
160impl ConstantItemKind {
161    pub(crate) fn as_str(&self) -> &'static str {
162        match self {
163            Self::Const => "const",
164            Self::Static => "static",
165        }
166    }
167}
168
169#[derive(Debug, Copy, Clone, PartialEq, Eq)]
170enum RecordPartialRes {
171    Yes,
172    No,
173}
174
175/// The rib kind restricts certain accesses,
176/// e.g. to a `Res::Local` of an outer item.
177#[derive(Copy, Clone, Debug)]
178pub(crate) enum RibKind<'ra> {
179    /// No restriction needs to be applied.
180    Normal,
181
182    /// We passed through an impl or trait and are now in one of its
183    /// methods or associated types. Allow references to ty params that impl or trait
184    /// binds. Disallow any other upvars (including other ty params that are
185    /// upvars).
186    AssocItem,
187
188    /// We passed through a function, closure or coroutine signature. Disallow labels.
189    FnOrCoroutine,
190
191    /// We passed through an item scope. Disallow upvars.
192    Item(HasGenericParams, DefKind),
193
194    /// We're in a constant item. Can't refer to dynamic stuff.
195    ///
196    /// The item may reference generic parameters in trivial constant expressions.
197    /// All other constants aren't allowed to use generic params at all.
198    ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
199
200    /// We passed through a module.
201    Module(Module<'ra>),
202
203    /// We passed through a `macro_rules!` statement
204    MacroDefinition(DefId),
205
206    /// All bindings in this rib are generic parameters that can't be used
207    /// from the default of a generic parameter because they're not declared
208    /// before said generic parameter. Also see the `visit_generics` override.
209    ForwardGenericParamBan(ForwardGenericParamBanReason),
210
211    /// We are inside of the type of a const parameter. Can't refer to any
212    /// parameters.
213    ConstParamTy,
214
215    /// We are inside a `sym` inline assembly operand. Can only refer to
216    /// globals.
217    InlineAsmSym,
218}
219
220#[derive(Copy, Clone, PartialEq, Eq, Debug)]
221pub(crate) enum ForwardGenericParamBanReason {
222    Default,
223    ConstParamTy,
224}
225
226impl RibKind<'_> {
227    /// Whether this rib kind contains generic parameters, as opposed to local
228    /// variables.
229    pub(crate) fn contains_params(&self) -> bool {
230        match self {
231            RibKind::Normal
232            | RibKind::FnOrCoroutine
233            | RibKind::ConstantItem(..)
234            | RibKind::Module(_)
235            | RibKind::MacroDefinition(_)
236            | RibKind::InlineAsmSym => false,
237            RibKind::ConstParamTy
238            | RibKind::AssocItem
239            | RibKind::Item(..)
240            | RibKind::ForwardGenericParamBan(_) => true,
241        }
242    }
243
244    /// This rib forbids referring to labels defined in upwards ribs.
245    fn is_label_barrier(self) -> bool {
246        match self {
247            RibKind::Normal | RibKind::MacroDefinition(..) => false,
248
249            RibKind::AssocItem
250            | RibKind::FnOrCoroutine
251            | RibKind::Item(..)
252            | RibKind::ConstantItem(..)
253            | RibKind::Module(..)
254            | RibKind::ForwardGenericParamBan(_)
255            | RibKind::ConstParamTy
256            | RibKind::InlineAsmSym => true,
257        }
258    }
259}
260
261/// A single local scope.
262///
263/// A rib represents a scope names can live in. Note that these appear in many places, not just
264/// around braces. At any place where the list of accessible names (of the given namespace)
265/// changes or a new restrictions on the name accessibility are introduced, a new rib is put onto a
266/// stack. This may be, for example, a `let` statement (because it introduces variables), a macro,
267/// etc.
268///
269/// Different [rib kinds](enum@RibKind) are transparent for different names.
270///
271/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
272/// resolving, the name is looked up from inside out.
273#[derive(Debug)]
274pub(crate) struct Rib<'ra, R = Res> {
275    pub bindings: FxHashMap<Ident, R>,
276    pub patterns_with_skipped_bindings: UnordMap<DefId, Vec<(Span, Result<(), ErrorGuaranteed>)>>,
277    pub kind: RibKind<'ra>,
278}
279
280impl<'ra, R> Rib<'ra, R> {
281    fn new(kind: RibKind<'ra>) -> Rib<'ra, R> {
282        Rib {
283            bindings: Default::default(),
284            patterns_with_skipped_bindings: Default::default(),
285            kind,
286        }
287    }
288}
289
290#[derive(Clone, Copy, Debug)]
291enum LifetimeUseSet {
292    One { use_span: Span, use_ctxt: visit::LifetimeCtxt },
293    Many,
294}
295
296#[derive(Copy, Clone, Debug)]
297enum LifetimeRibKind {
298    // -- Ribs introducing named lifetimes
299    //
300    /// This rib declares generic parameters.
301    /// Only for this kind the `LifetimeRib::bindings` field can be non-empty.
302    Generics { binder: NodeId, span: Span, kind: LifetimeBinderKind },
303
304    // -- Ribs introducing unnamed lifetimes
305    //
306    /// Create a new anonymous lifetime parameter and reference it.
307    ///
308    /// If `report_in_path`, report an error when encountering lifetime elision in a path:
309    /// ```compile_fail
310    /// struct Foo<'a> { x: &'a () }
311    /// async fn foo(x: Foo) {}
312    /// ```
313    ///
314    /// Note: the error should not trigger when the elided lifetime is in a pattern or
315    /// expression-position path:
316    /// ```
317    /// struct Foo<'a> { x: &'a () }
318    /// async fn foo(Foo { x: _ }: Foo<'_>) {}
319    /// ```
320    AnonymousCreateParameter { binder: NodeId, report_in_path: bool },
321
322    /// Replace all anonymous lifetimes by provided lifetime.
323    Elided(LifetimeRes),
324
325    // -- Barrier ribs that stop lifetime lookup, or continue it but produce an error later.
326    //
327    /// Give a hard error when either `&` or `'_` is written. Used to
328    /// rule out things like `where T: Foo<'_>`. Does not imply an
329    /// error on default object bounds (e.g., `Box<dyn Foo>`).
330    AnonymousReportError,
331
332    /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,
333    /// otherwise give a warning that the previous behavior of introducing a new early-bound
334    /// lifetime is a bug and will be removed (if `emit_lint` is enabled).
335    StaticIfNoLifetimeInScope { lint_id: NodeId, emit_lint: bool },
336
337    /// Signal we cannot find which should be the anonymous lifetime.
338    ElisionFailure,
339
340    /// This rib forbids usage of generic parameters inside of const parameter types.
341    ///
342    /// While this is desirable to support eventually, it is difficult to do and so is
343    /// currently forbidden. See rust-lang/project-const-generics#28 for more info.
344    ConstParamTy,
345
346    /// Usage of generic parameters is forbidden in various positions for anon consts:
347    /// - const arguments when `generic_const_exprs` is not enabled
348    /// - enum discriminant values
349    ///
350    /// This rib emits an error when a lifetime would resolve to a lifetime parameter.
351    ConcreteAnonConst(NoConstantGenericsReason),
352
353    /// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
354    Item,
355}
356
357#[derive(Copy, Clone, Debug)]
358enum LifetimeBinderKind {
359    BareFnType,
360    PolyTrait,
361    WhereBound,
362    Item,
363    ConstItem,
364    Function,
365    Closure,
366    ImplBlock,
367}
368
369impl LifetimeBinderKind {
370    fn descr(self) -> &'static str {
371        use LifetimeBinderKind::*;
372        match self {
373            BareFnType => "type",
374            PolyTrait => "bound",
375            WhereBound => "bound",
376            Item | ConstItem => "item",
377            ImplBlock => "impl block",
378            Function => "function",
379            Closure => "closure",
380        }
381    }
382}
383
384#[derive(Debug)]
385struct LifetimeRib {
386    kind: LifetimeRibKind,
387    // We need to preserve insertion order for async fns.
388    bindings: FxIndexMap<Ident, (NodeId, LifetimeRes)>,
389}
390
391impl LifetimeRib {
392    fn new(kind: LifetimeRibKind) -> LifetimeRib {
393        LifetimeRib { bindings: Default::default(), kind }
394    }
395}
396
397#[derive(Copy, Clone, PartialEq, Eq, Debug)]
398pub(crate) enum AliasPossibility {
399    No,
400    Maybe,
401}
402
403#[derive(Copy, Clone, Debug)]
404pub(crate) enum PathSource<'a> {
405    /// Type paths `Path`.
406    Type,
407    /// Trait paths in bounds or impls.
408    Trait(AliasPossibility),
409    /// Expression paths `path`, with optional parent context.
410    Expr(Option<&'a Expr>),
411    /// Paths in path patterns `Path`.
412    Pat,
413    /// Paths in struct expressions and patterns `Path { .. }`.
414    Struct,
415    /// Paths in tuple struct patterns `Path(..)`.
416    TupleStruct(Span, &'a [Span]),
417    /// `m::A::B` in `<T as m::A>::B::C`.
418    TraitItem(Namespace),
419    /// Paths in delegation item
420    Delegation,
421    /// An arg in a `use<'a, N>` precise-capturing bound.
422    PreciseCapturingArg(Namespace),
423    /// Paths that end with `(..)`, for return type notation.
424    ReturnTypeNotation,
425    /// Paths from `#[define_opaque]` attributes
426    DefineOpaques,
427}
428
429impl<'a> PathSource<'a> {
430    fn namespace(self) -> Namespace {
431        match self {
432            PathSource::Type
433            | PathSource::Trait(_)
434            | PathSource::Struct
435            | PathSource::DefineOpaques => TypeNS,
436            PathSource::Expr(..)
437            | PathSource::Pat
438            | PathSource::TupleStruct(..)
439            | PathSource::Delegation
440            | PathSource::ReturnTypeNotation => ValueNS,
441            PathSource::TraitItem(ns) => ns,
442            PathSource::PreciseCapturingArg(ns) => ns,
443        }
444    }
445
446    fn defer_to_typeck(self) -> bool {
447        match self {
448            PathSource::Type
449            | PathSource::Expr(..)
450            | PathSource::Pat
451            | PathSource::Struct
452            | PathSource::TupleStruct(..)
453            | PathSource::ReturnTypeNotation => true,
454            PathSource::Trait(_)
455            | PathSource::TraitItem(..)
456            | PathSource::DefineOpaques
457            | PathSource::Delegation
458            | PathSource::PreciseCapturingArg(..) => false,
459        }
460    }
461
462    fn descr_expected(self) -> &'static str {
463        match &self {
464            PathSource::DefineOpaques => "type alias or associated type with opaqaue types",
465            PathSource::Type => "type",
466            PathSource::Trait(_) => "trait",
467            PathSource::Pat => "unit struct, unit variant or constant",
468            PathSource::Struct => "struct, variant or union type",
469            PathSource::TupleStruct(..) => "tuple struct or tuple variant",
470            PathSource::TraitItem(ns) => match ns {
471                TypeNS => "associated type",
472                ValueNS => "method or associated constant",
473                MacroNS => bug!("associated macro"),
474            },
475            PathSource::Expr(parent) => match parent.as_ref().map(|p| &p.kind) {
476                // "function" here means "anything callable" rather than `DefKind::Fn`,
477                // this is not precise but usually more helpful than just "value".
478                Some(ExprKind::Call(call_expr, _)) => match &call_expr.kind {
479                    // the case of `::some_crate()`
480                    ExprKind::Path(_, path)
481                        if let [segment, _] = path.segments.as_slice()
482                            && segment.ident.name == kw::PathRoot =>
483                    {
484                        "external crate"
485                    }
486                    ExprKind::Path(_, path)
487                        if let Some(segment) = path.segments.last()
488                            && let Some(c) = segment.ident.to_string().chars().next()
489                            && c.is_uppercase() =>
490                    {
491                        "function, tuple struct or tuple variant"
492                    }
493                    _ => "function",
494                },
495                _ => "value",
496            },
497            PathSource::ReturnTypeNotation | PathSource::Delegation => "function",
498            PathSource::PreciseCapturingArg(..) => "type or const parameter",
499        }
500    }
501
502    fn is_call(self) -> bool {
503        matches!(self, PathSource::Expr(Some(&Expr { kind: ExprKind::Call(..), .. })))
504    }
505
506    pub(crate) fn is_expected(self, res: Res) -> bool {
507        match self {
508            PathSource::DefineOpaques => {
509                matches!(
510                    res,
511                    Res::Def(
512                        DefKind::Struct
513                            | DefKind::Union
514                            | DefKind::Enum
515                            | DefKind::TyAlias
516                            | DefKind::AssocTy,
517                        _
518                    ) | Res::SelfTyAlias { .. }
519                )
520            }
521            PathSource::Type => matches!(
522                res,
523                Res::Def(
524                    DefKind::Struct
525                        | DefKind::Union
526                        | DefKind::Enum
527                        | DefKind::Trait
528                        | DefKind::TraitAlias
529                        | DefKind::TyAlias
530                        | DefKind::AssocTy
531                        | DefKind::TyParam
532                        | DefKind::OpaqueTy
533                        | DefKind::ForeignTy,
534                    _,
535                ) | Res::PrimTy(..)
536                    | Res::SelfTyParam { .. }
537                    | Res::SelfTyAlias { .. }
538            ),
539            PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),
540            PathSource::Trait(AliasPossibility::Maybe) => {
541                matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
542            }
543            PathSource::Expr(..) => matches!(
544                res,
545                Res::Def(
546                    DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn)
547                        | DefKind::Const
548                        | DefKind::Static { .. }
549                        | DefKind::Fn
550                        | DefKind::AssocFn
551                        | DefKind::AssocConst
552                        | DefKind::ConstParam,
553                    _,
554                ) | Res::Local(..)
555                    | Res::SelfCtor(..)
556            ),
557            PathSource::Pat => {
558                res.expected_in_unit_struct_pat()
559                    || matches!(res, Res::Def(DefKind::Const | DefKind::AssocConst, _))
560            }
561            PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),
562            PathSource::Struct => matches!(
563                res,
564                Res::Def(
565                    DefKind::Struct
566                        | DefKind::Union
567                        | DefKind::Variant
568                        | DefKind::TyAlias
569                        | DefKind::AssocTy,
570                    _,
571                ) | Res::SelfTyParam { .. }
572                    | Res::SelfTyAlias { .. }
573            ),
574            PathSource::TraitItem(ns) => match res {
575                Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
576                Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
577                _ => false,
578            },
579            PathSource::ReturnTypeNotation => match res {
580                Res::Def(DefKind::AssocFn, _) => true,
581                _ => false,
582            },
583            PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),
584            PathSource::PreciseCapturingArg(ValueNS) => {
585                matches!(res, Res::Def(DefKind::ConstParam, _))
586            }
587            // We allow `SelfTyAlias` here so we can give a more descriptive error later.
588            PathSource::PreciseCapturingArg(TypeNS) => matches!(
589                res,
590                Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }
591            ),
592            PathSource::PreciseCapturingArg(MacroNS) => false,
593        }
594    }
595
596    fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {
597        match (self, has_unexpected_resolution) {
598            (PathSource::Trait(_), true) => E0404,
599            (PathSource::Trait(_), false) => E0405,
600            (PathSource::Type | PathSource::DefineOpaques, true) => E0573,
601            (PathSource::Type | PathSource::DefineOpaques, false) => E0412,
602            (PathSource::Struct, true) => E0574,
603            (PathSource::Struct, false) => E0422,
604            (PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
605            (PathSource::Expr(..), false) | (PathSource::Delegation, false) => E0425,
606            (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,
607            (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
608            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, true) => E0575,
609            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, false) => E0576,
610            (PathSource::PreciseCapturingArg(..), true) => E0799,
611            (PathSource::PreciseCapturingArg(..), false) => E0800,
612        }
613    }
614}
615
616/// At this point for most items we can answer whether that item is exported or not,
617/// but some items like impls require type information to determine exported-ness, so we make a
618/// conservative estimate for them (e.g. based on nominal visibility).
619#[derive(Clone, Copy)]
620enum MaybeExported<'a> {
621    Ok(NodeId),
622    Impl(Option<DefId>),
623    ImplItem(Result<DefId, &'a Visibility>),
624    NestedUse(&'a Visibility),
625}
626
627impl MaybeExported<'_> {
628    fn eval(self, r: &Resolver<'_, '_>) -> bool {
629        let def_id = match self {
630            MaybeExported::Ok(node_id) => Some(r.local_def_id(node_id)),
631            MaybeExported::Impl(Some(trait_def_id)) | MaybeExported::ImplItem(Ok(trait_def_id)) => {
632                trait_def_id.as_local()
633            }
634            MaybeExported::Impl(None) => return true,
635            MaybeExported::ImplItem(Err(vis)) | MaybeExported::NestedUse(vis) => {
636                return vis.kind.is_pub();
637            }
638        };
639        def_id.is_none_or(|def_id| r.effective_visibilities.is_exported(def_id))
640    }
641}
642
643/// Used for recording UnnecessaryQualification.
644#[derive(Debug)]
645pub(crate) struct UnnecessaryQualification<'ra> {
646    pub binding: LexicalScopeBinding<'ra>,
647    pub node_id: NodeId,
648    pub path_span: Span,
649    pub removal_span: Span,
650}
651
652#[derive(Default, Debug)]
653struct DiagMetadata<'ast> {
654    /// The current trait's associated items' ident, used for diagnostic suggestions.
655    current_trait_assoc_items: Option<&'ast [P<AssocItem>]>,
656
657    /// The current self type if inside an impl (used for better errors).
658    current_self_type: Option<Ty>,
659
660    /// The current self item if inside an ADT (used for better errors).
661    current_self_item: Option<NodeId>,
662
663    /// The current trait (used to suggest).
664    current_item: Option<&'ast Item>,
665
666    /// When processing generic arguments and encountering an unresolved ident not found,
667    /// suggest introducing a type or const param depending on the context.
668    currently_processing_generic_args: bool,
669
670    /// The current enclosing (non-closure) function (used for better errors).
671    current_function: Option<(FnKind<'ast>, Span)>,
672
673    /// A list of labels as of yet unused. Labels will be removed from this map when
674    /// they are used (in a `break` or `continue` statement)
675    unused_labels: FxHashMap<NodeId, Span>,
676
677    /// Only used for better errors on `let x = { foo: bar };`.
678    /// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only
679    /// needed for cases where this parses as a correct type ascription.
680    current_block_could_be_bare_struct_literal: Option<Span>,
681
682    /// Only used for better errors on `let <pat>: <expr, not type>;`.
683    current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
684
685    current_pat: Option<&'ast Pat>,
686
687    /// Used to detect possible `if let` written without `let` and to provide structured suggestion.
688    in_if_condition: Option<&'ast Expr>,
689
690    /// Used to detect possible new binding written without `let` and to provide structured suggestion.
691    in_assignment: Option<&'ast Expr>,
692    is_assign_rhs: bool,
693
694    /// If we are setting an associated type in trait impl, is it a non-GAT type?
695    in_non_gat_assoc_type: Option<bool>,
696
697    /// Used to detect possible `.` -> `..` typo when calling methods.
698    in_range: Option<(&'ast Expr, &'ast Expr)>,
699
700    /// If we are currently in a trait object definition. Used to point at the bounds when
701    /// encountering a struct or enum.
702    current_trait_object: Option<&'ast [ast::GenericBound]>,
703
704    /// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
705    current_where_predicate: Option<&'ast WherePredicate>,
706
707    current_type_path: Option<&'ast Ty>,
708
709    /// The current impl items (used to suggest).
710    current_impl_items: Option<&'ast [P<AssocItem>]>,
711
712    /// When processing impl trait
713    currently_processing_impl_trait: Option<(TraitRef, Ty)>,
714
715    /// Accumulate the errors due to missed lifetime elision,
716    /// and report them all at once for each function.
717    current_elision_failures: Vec<MissingLifetime>,
718}
719
720struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
721    r: &'a mut Resolver<'ra, 'tcx>,
722
723    /// The module that represents the current item scope.
724    parent_scope: ParentScope<'ra>,
725
726    /// The current set of local scopes for types and values.
727    ribs: PerNS<Vec<Rib<'ra>>>,
728
729    /// Previous popped `rib`, only used for diagnostic.
730    last_block_rib: Option<Rib<'ra>>,
731
732    /// The current set of local scopes, for labels.
733    label_ribs: Vec<Rib<'ra, NodeId>>,
734
735    /// The current set of local scopes for lifetimes.
736    lifetime_ribs: Vec<LifetimeRib>,
737
738    /// We are looking for lifetimes in an elision context.
739    /// The set contains all the resolutions that we encountered so far.
740    /// They will be used to determine the correct lifetime for the fn return type.
741    /// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named
742    /// lifetimes.
743    lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,
744
745    /// The trait that the current context can refer to.
746    current_trait_ref: Option<(Module<'ra>, TraitRef)>,
747
748    /// Fields used to add information to diagnostic errors.
749    diag_metadata: Box<DiagMetadata<'ast>>,
750
751    /// State used to know whether to ignore resolution errors for function bodies.
752    ///
753    /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items.
754    /// In most cases this will be `None`, in which case errors will always be reported.
755    /// If it is `true`, then it will be updated when entering a nested function or trait body.
756    in_func_body: bool,
757
758    /// Count the number of places a lifetime is used.
759    lifetime_uses: FxHashMap<LocalDefId, LifetimeUseSet>,
760}
761
762/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
763impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
764    fn visit_attribute(&mut self, _: &'ast Attribute) {
765        // We do not want to resolve expressions that appear in attributes,
766        // as they do not correspond to actual code.
767    }
768    fn visit_item(&mut self, item: &'ast Item) {
769        let prev = replace(&mut self.diag_metadata.current_item, Some(item));
770        // Always report errors in items we just entered.
771        let old_ignore = replace(&mut self.in_func_body, false);
772        self.with_lifetime_rib(LifetimeRibKind::Item, |this| this.resolve_item(item));
773        self.in_func_body = old_ignore;
774        self.diag_metadata.current_item = prev;
775    }
776    fn visit_arm(&mut self, arm: &'ast Arm) {
777        self.resolve_arm(arm);
778    }
779    fn visit_block(&mut self, block: &'ast Block) {
780        let old_macro_rules = self.parent_scope.macro_rules;
781        self.resolve_block(block);
782        self.parent_scope.macro_rules = old_macro_rules;
783    }
784    fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
785        bug!("encountered anon const without a manual call to `resolve_anon_const`: {constant:#?}");
786    }
787    fn visit_expr(&mut self, expr: &'ast Expr) {
788        self.resolve_expr(expr, None);
789    }
790    fn visit_pat(&mut self, p: &'ast Pat) {
791        let prev = self.diag_metadata.current_pat;
792        self.diag_metadata.current_pat = Some(p);
793        visit::walk_pat(self, p);
794        self.diag_metadata.current_pat = prev;
795    }
796    fn visit_local(&mut self, local: &'ast Local) {
797        let local_spans = match local.pat.kind {
798            // We check for this to avoid tuple struct fields.
799            PatKind::Wild => None,
800            _ => Some((
801                local.pat.span,
802                local.ty.as_ref().map(|ty| ty.span),
803                local.kind.init().map(|init| init.span),
804            )),
805        };
806        let original = replace(&mut self.diag_metadata.current_let_binding, local_spans);
807        self.resolve_local(local);
808        self.diag_metadata.current_let_binding = original;
809    }
810    fn visit_ty(&mut self, ty: &'ast Ty) {
811        let prev = self.diag_metadata.current_trait_object;
812        let prev_ty = self.diag_metadata.current_type_path;
813        match &ty.kind {
814            TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => {
815                // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
816                // NodeId `ty.id`.
817                // This span will be used in case of elision failure.
818                let span = self.r.tcx.sess.source_map().start_point(ty.span);
819                self.resolve_elided_lifetime(ty.id, span);
820                visit::walk_ty(self, ty);
821            }
822            TyKind::Path(qself, path) => {
823                self.diag_metadata.current_type_path = Some(ty);
824
825                // If we have a path that ends with `(..)`, then it must be
826                // return type notation. Resolve that path in the *value*
827                // namespace.
828                let source = if let Some(seg) = path.segments.last()
829                    && let Some(args) = &seg.args
830                    && matches!(**args, GenericArgs::ParenthesizedElided(..))
831                {
832                    PathSource::ReturnTypeNotation
833                } else {
834                    PathSource::Type
835                };
836
837                self.smart_resolve_path(ty.id, qself, path, source);
838
839                // Check whether we should interpret this as a bare trait object.
840                if qself.is_none()
841                    && let Some(partial_res) = self.r.partial_res_map.get(&ty.id)
842                    && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) =
843                        partial_res.full_res()
844                {
845                    // This path is actually a bare trait object. In case of a bare `Fn`-trait
846                    // object with anonymous lifetimes, we need this rib to correctly place the
847                    // synthetic lifetimes.
848                    let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo());
849                    self.with_generic_param_rib(
850                        &[],
851                        RibKind::Normal,
852                        LifetimeRibKind::Generics {
853                            binder: ty.id,
854                            kind: LifetimeBinderKind::PolyTrait,
855                            span,
856                        },
857                        |this| this.visit_path(path, ty.id),
858                    );
859                } else {
860                    visit::walk_ty(self, ty)
861                }
862            }
863            TyKind::ImplicitSelf => {
864                let self_ty = Ident::with_dummy_span(kw::SelfUpper);
865                let res = self
866                    .resolve_ident_in_lexical_scope(
867                        self_ty,
868                        TypeNS,
869                        Some(Finalize::new(ty.id, ty.span)),
870                        None,
871                    )
872                    .map_or(Res::Err, |d| d.res());
873                self.r.record_partial_res(ty.id, PartialRes::new(res));
874                visit::walk_ty(self, ty)
875            }
876            TyKind::ImplTrait(..) => {
877                let candidates = self.lifetime_elision_candidates.take();
878                visit::walk_ty(self, ty);
879                self.lifetime_elision_candidates = candidates;
880            }
881            TyKind::TraitObject(bounds, ..) => {
882                self.diag_metadata.current_trait_object = Some(&bounds[..]);
883                visit::walk_ty(self, ty)
884            }
885            TyKind::BareFn(bare_fn) => {
886                let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo());
887                self.with_generic_param_rib(
888                    &bare_fn.generic_params,
889                    RibKind::Normal,
890                    LifetimeRibKind::Generics {
891                        binder: ty.id,
892                        kind: LifetimeBinderKind::BareFnType,
893                        span,
894                    },
895                    |this| {
896                        this.visit_generic_params(&bare_fn.generic_params, false);
897                        this.with_lifetime_rib(
898                            LifetimeRibKind::AnonymousCreateParameter {
899                                binder: ty.id,
900                                report_in_path: false,
901                            },
902                            |this| {
903                                this.resolve_fn_signature(
904                                    ty.id,
905                                    false,
906                                    // We don't need to deal with patterns in parameters, because
907                                    // they are not possible for foreign or bodiless functions.
908                                    bare_fn
909                                        .decl
910                                        .inputs
911                                        .iter()
912                                        .map(|Param { ty, .. }| (None, &**ty)),
913                                    &bare_fn.decl.output,
914                                )
915                            },
916                        );
917                    },
918                )
919            }
920            TyKind::UnsafeBinder(unsafe_binder) => {
921                // FIXME(unsafe_binder): Better span
922                let span = ty.span;
923                self.with_generic_param_rib(
924                    &unsafe_binder.generic_params,
925                    RibKind::Normal,
926                    LifetimeRibKind::Generics {
927                        binder: ty.id,
928                        kind: LifetimeBinderKind::BareFnType,
929                        span,
930                    },
931                    |this| {
932                        this.visit_generic_params(&unsafe_binder.generic_params, false);
933                        this.with_lifetime_rib(
934                            // We don't allow anonymous `unsafe &'_ ()` binders,
935                            // although I guess we could.
936                            LifetimeRibKind::AnonymousReportError,
937                            |this| this.visit_ty(&unsafe_binder.inner_ty),
938                        );
939                    },
940                )
941            }
942            TyKind::Array(element_ty, length) => {
943                self.visit_ty(element_ty);
944                self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
945            }
946            TyKind::Typeof(ct) => {
947                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
948            }
949            _ => visit::walk_ty(self, ty),
950        }
951        self.diag_metadata.current_trait_object = prev;
952        self.diag_metadata.current_type_path = prev_ty;
953    }
954
955    fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
956        match &t.kind {
957            TyPatKind::Range(start, end, _) => {
958                if let Some(start) = start {
959                    self.resolve_anon_const(start, AnonConstKind::ConstArg(IsRepeatExpr::No));
960                }
961                if let Some(end) = end {
962                    self.resolve_anon_const(end, AnonConstKind::ConstArg(IsRepeatExpr::No));
963                }
964            }
965            TyPatKind::Err(_) => {}
966        }
967    }
968
969    fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
970        let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
971        self.with_generic_param_rib(
972            &tref.bound_generic_params,
973            RibKind::Normal,
974            LifetimeRibKind::Generics {
975                binder: tref.trait_ref.ref_id,
976                kind: LifetimeBinderKind::PolyTrait,
977                span,
978            },
979            |this| {
980                this.visit_generic_params(&tref.bound_generic_params, false);
981                this.smart_resolve_path(
982                    tref.trait_ref.ref_id,
983                    &None,
984                    &tref.trait_ref.path,
985                    PathSource::Trait(AliasPossibility::Maybe),
986                );
987                this.visit_trait_ref(&tref.trait_ref);
988            },
989        );
990    }
991    fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
992        self.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id));
993        let def_kind = self.r.local_def_kind(foreign_item.id);
994        match foreign_item.kind {
995            ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
996                self.with_generic_param_rib(
997                    &generics.params,
998                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
999                    LifetimeRibKind::Generics {
1000                        binder: foreign_item.id,
1001                        kind: LifetimeBinderKind::Item,
1002                        span: generics.span,
1003                    },
1004                    |this| visit::walk_item(this, foreign_item),
1005                );
1006            }
1007            ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
1008                self.with_generic_param_rib(
1009                    &generics.params,
1010                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
1011                    LifetimeRibKind::Generics {
1012                        binder: foreign_item.id,
1013                        kind: LifetimeBinderKind::Function,
1014                        span: generics.span,
1015                    },
1016                    |this| visit::walk_item(this, foreign_item),
1017                );
1018            }
1019            ForeignItemKind::Static(..) => {
1020                self.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item))
1021            }
1022            ForeignItemKind::MacCall(..) => {
1023                panic!("unexpanded macro in resolve!")
1024            }
1025        }
1026    }
1027    fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) {
1028        let previous_value = self.diag_metadata.current_function;
1029        match fn_kind {
1030            // Bail if the function is foreign, and thus cannot validly have
1031            // a body, or if there's no body for some other reason.
1032            FnKind::Fn(FnCtxt::Foreign, _, _, Fn { sig, generics, .. })
1033            | FnKind::Fn(_, _, _, Fn { sig, generics, body: None, .. }) => {
1034                self.visit_fn_header(&sig.header);
1035                self.visit_generics(generics);
1036                self.with_lifetime_rib(
1037                    LifetimeRibKind::AnonymousCreateParameter {
1038                        binder: fn_id,
1039                        report_in_path: false,
1040                    },
1041                    |this| {
1042                        this.resolve_fn_signature(
1043                            fn_id,
1044                            sig.decl.has_self(),
1045                            sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
1046                            &sig.decl.output,
1047                        );
1048                    },
1049                );
1050                return;
1051            }
1052            FnKind::Fn(..) => {
1053                self.diag_metadata.current_function = Some((fn_kind, sp));
1054            }
1055            // Do not update `current_function` for closures: it suggests `self` parameters.
1056            FnKind::Closure(..) => {}
1057        };
1058        debug!("(resolving function) entering function");
1059
1060        // Create a value rib for the function.
1061        self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
1062            // Create a label rib for the function.
1063            this.with_label_rib(RibKind::FnOrCoroutine, |this| {
1064                match fn_kind {
1065                    FnKind::Fn(_, _, _, Fn { sig, generics, contract, body, .. }) => {
1066                        this.visit_generics(generics);
1067
1068                        let declaration = &sig.decl;
1069                        let coro_node_id = sig
1070                            .header
1071                            .coroutine_kind
1072                            .map(|coroutine_kind| coroutine_kind.return_id());
1073
1074                        this.with_lifetime_rib(
1075                            LifetimeRibKind::AnonymousCreateParameter {
1076                                binder: fn_id,
1077                                report_in_path: coro_node_id.is_some(),
1078                            },
1079                            |this| {
1080                                this.resolve_fn_signature(
1081                                    fn_id,
1082                                    declaration.has_self(),
1083                                    declaration
1084                                        .inputs
1085                                        .iter()
1086                                        .map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)),
1087                                    &declaration.output,
1088                                );
1089                            },
1090                        );
1091
1092                        if let Some(contract) = contract {
1093                            this.visit_contract(contract);
1094                        }
1095
1096                        if let Some(body) = body {
1097                            // Ignore errors in function bodies if this is rustdoc
1098                            // Be sure not to set this until the function signature has been resolved.
1099                            let previous_state = replace(&mut this.in_func_body, true);
1100                            // We only care block in the same function
1101                            this.last_block_rib = None;
1102                            // Resolve the function body, potentially inside the body of an async closure
1103                            this.with_lifetime_rib(
1104                                LifetimeRibKind::Elided(LifetimeRes::Infer),
1105                                |this| this.visit_block(body),
1106                            );
1107
1108                            debug!("(resolving function) leaving function");
1109                            this.in_func_body = previous_state;
1110                        }
1111                    }
1112                    FnKind::Closure(binder, _, declaration, body) => {
1113                        this.visit_closure_binder(binder);
1114
1115                        this.with_lifetime_rib(
1116                            match binder {
1117                                // We do not have any explicit generic lifetime parameter.
1118                                ClosureBinder::NotPresent => {
1119                                    LifetimeRibKind::AnonymousCreateParameter {
1120                                        binder: fn_id,
1121                                        report_in_path: false,
1122                                    }
1123                                }
1124                                ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,
1125                            },
1126                            // Add each argument to the rib.
1127                            |this| this.resolve_params(&declaration.inputs),
1128                        );
1129                        this.with_lifetime_rib(
1130                            match binder {
1131                                ClosureBinder::NotPresent => {
1132                                    LifetimeRibKind::Elided(LifetimeRes::Infer)
1133                                }
1134                                ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,
1135                            },
1136                            |this| visit::walk_fn_ret_ty(this, &declaration.output),
1137                        );
1138
1139                        // Ignore errors in function bodies if this is rustdoc
1140                        // Be sure not to set this until the function signature has been resolved.
1141                        let previous_state = replace(&mut this.in_func_body, true);
1142                        // Resolve the function body, potentially inside the body of an async closure
1143                        this.with_lifetime_rib(
1144                            LifetimeRibKind::Elided(LifetimeRes::Infer),
1145                            |this| this.visit_expr(body),
1146                        );
1147
1148                        debug!("(resolving function) leaving function");
1149                        this.in_func_body = previous_state;
1150                    }
1151                }
1152            })
1153        });
1154        self.diag_metadata.current_function = previous_value;
1155    }
1156
1157    fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {
1158        self.resolve_lifetime(lifetime, use_ctxt)
1159    }
1160
1161    fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {
1162        match arg {
1163            // Lower the lifetime regularly; we'll resolve the lifetime and check
1164            // it's a parameter later on in HIR lowering.
1165            PreciseCapturingArg::Lifetime(_) => {}
1166
1167            PreciseCapturingArg::Arg(path, id) => {
1168                // we want `impl use<C>` to try to resolve `C` as both a type parameter or
1169                // a const parameter. Since the resolver specifically doesn't allow having
1170                // two generic params with the same name, even if they're a different namespace,
1171                // it doesn't really matter which we try resolving first, but just like
1172                // `Ty::Param` we just fall back to the value namespace only if it's missing
1173                // from the type namespace.
1174                let mut check_ns = |ns| {
1175                    self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some()
1176                };
1177                // Like `Ty::Param`, we try resolving this as both a const and a type.
1178                if !check_ns(TypeNS) && check_ns(ValueNS) {
1179                    self.smart_resolve_path(
1180                        *id,
1181                        &None,
1182                        path,
1183                        PathSource::PreciseCapturingArg(ValueNS),
1184                    );
1185                } else {
1186                    self.smart_resolve_path(
1187                        *id,
1188                        &None,
1189                        path,
1190                        PathSource::PreciseCapturingArg(TypeNS),
1191                    );
1192                }
1193            }
1194        }
1195
1196        visit::walk_precise_capturing_arg(self, arg)
1197    }
1198
1199    fn visit_generics(&mut self, generics: &'ast Generics) {
1200        self.visit_generic_params(&generics.params, self.diag_metadata.current_self_item.is_some());
1201        for p in &generics.where_clause.predicates {
1202            self.visit_where_predicate(p);
1203        }
1204    }
1205
1206    fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) {
1207        match b {
1208            ClosureBinder::NotPresent => {}
1209            ClosureBinder::For { generic_params, .. } => {
1210                self.visit_generic_params(
1211                    generic_params,
1212                    self.diag_metadata.current_self_item.is_some(),
1213                );
1214            }
1215        }
1216    }
1217
1218    fn visit_generic_arg(&mut self, arg: &'ast GenericArg) {
1219        debug!("visit_generic_arg({:?})", arg);
1220        let prev = replace(&mut self.diag_metadata.currently_processing_generic_args, true);
1221        match arg {
1222            GenericArg::Type(ty) => {
1223                // We parse const arguments as path types as we cannot distinguish them during
1224                // parsing. We try to resolve that ambiguity by attempting resolution the type
1225                // namespace first, and if that fails we try again in the value namespace. If
1226                // resolution in the value namespace succeeds, we have an generic const argument on
1227                // our hands.
1228                if let TyKind::Path(None, ref path) = ty.kind
1229                    // We cannot disambiguate multi-segment paths right now as that requires type
1230                    // checking.
1231                    && path.is_potential_trivial_const_arg(false)
1232                {
1233                    let mut check_ns = |ns| {
1234                        self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
1235                            .is_some()
1236                    };
1237                    if !check_ns(TypeNS) && check_ns(ValueNS) {
1238                        self.resolve_anon_const_manual(
1239                            true,
1240                            AnonConstKind::ConstArg(IsRepeatExpr::No),
1241                            |this| {
1242                                this.smart_resolve_path(ty.id, &None, path, PathSource::Expr(None));
1243                                this.visit_path(path, ty.id);
1244                            },
1245                        );
1246
1247                        self.diag_metadata.currently_processing_generic_args = prev;
1248                        return;
1249                    }
1250                }
1251
1252                self.visit_ty(ty);
1253            }
1254            GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg),
1255            GenericArg::Const(ct) => {
1256                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
1257            }
1258        }
1259        self.diag_metadata.currently_processing_generic_args = prev;
1260    }
1261
1262    fn visit_assoc_item_constraint(&mut self, constraint: &'ast AssocItemConstraint) {
1263        self.visit_ident(&constraint.ident);
1264        if let Some(ref gen_args) = constraint.gen_args {
1265            // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.
1266            self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
1267                this.visit_generic_args(gen_args)
1268            });
1269        }
1270        match constraint.kind {
1271            AssocItemConstraintKind::Equality { ref term } => match term {
1272                Term::Ty(ty) => self.visit_ty(ty),
1273                Term::Const(c) => {
1274                    self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
1275                }
1276            },
1277            AssocItemConstraintKind::Bound { ref bounds } => {
1278                walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
1279            }
1280        }
1281    }
1282
1283    fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
1284        let Some(ref args) = path_segment.args else {
1285            return;
1286        };
1287
1288        match &**args {
1289            GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),
1290            GenericArgs::Parenthesized(p_args) => {
1291                // Probe the lifetime ribs to know how to behave.
1292                for rib in self.lifetime_ribs.iter().rev() {
1293                    match rib.kind {
1294                        // We are inside a `PolyTraitRef`. The lifetimes are
1295                        // to be introduced in that (maybe implicit) `for<>` binder.
1296                        LifetimeRibKind::Generics {
1297                            binder,
1298                            kind: LifetimeBinderKind::PolyTrait,
1299                            ..
1300                        } => {
1301                            self.with_lifetime_rib(
1302                                LifetimeRibKind::AnonymousCreateParameter {
1303                                    binder,
1304                                    report_in_path: false,
1305                                },
1306                                |this| {
1307                                    this.resolve_fn_signature(
1308                                        binder,
1309                                        false,
1310                                        p_args.inputs.iter().map(|ty| (None, &**ty)),
1311                                        &p_args.output,
1312                                    )
1313                                },
1314                            );
1315                            break;
1316                        }
1317                        // We have nowhere to introduce generics. Code is malformed,
1318                        // so use regular lifetime resolution to avoid spurious errors.
1319                        LifetimeRibKind::Item | LifetimeRibKind::Generics { .. } => {
1320                            visit::walk_generic_args(self, args);
1321                            break;
1322                        }
1323                        LifetimeRibKind::AnonymousCreateParameter { .. }
1324                        | LifetimeRibKind::AnonymousReportError
1325                        | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
1326                        | LifetimeRibKind::Elided(_)
1327                        | LifetimeRibKind::ElisionFailure
1328                        | LifetimeRibKind::ConcreteAnonConst(_)
1329                        | LifetimeRibKind::ConstParamTy => {}
1330                    }
1331                }
1332            }
1333            GenericArgs::ParenthesizedElided(_) => {}
1334        }
1335    }
1336
1337    fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
1338        debug!("visit_where_predicate {:?}", p);
1339        let previous_value = replace(&mut self.diag_metadata.current_where_predicate, Some(p));
1340        self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
1341            if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {
1342                bounded_ty,
1343                bounds,
1344                bound_generic_params,
1345                ..
1346            }) = &p.kind
1347            {
1348                let span = p.span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
1349                this.with_generic_param_rib(
1350                    bound_generic_params,
1351                    RibKind::Normal,
1352                    LifetimeRibKind::Generics {
1353                        binder: bounded_ty.id,
1354                        kind: LifetimeBinderKind::WhereBound,
1355                        span,
1356                    },
1357                    |this| {
1358                        this.visit_generic_params(bound_generic_params, false);
1359                        this.visit_ty(bounded_ty);
1360                        for bound in bounds {
1361                            this.visit_param_bound(bound, BoundKind::Bound)
1362                        }
1363                    },
1364                );
1365            } else {
1366                visit::walk_where_predicate(this, p);
1367            }
1368        });
1369        self.diag_metadata.current_where_predicate = previous_value;
1370    }
1371
1372    fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) {
1373        for (op, _) in &asm.operands {
1374            match op {
1375                InlineAsmOperand::In { expr, .. }
1376                | InlineAsmOperand::Out { expr: Some(expr), .. }
1377                | InlineAsmOperand::InOut { expr, .. } => self.visit_expr(expr),
1378                InlineAsmOperand::Out { expr: None, .. } => {}
1379                InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
1380                    self.visit_expr(in_expr);
1381                    if let Some(out_expr) = out_expr {
1382                        self.visit_expr(out_expr);
1383                    }
1384                }
1385                InlineAsmOperand::Const { anon_const, .. } => {
1386                    // Although this is `DefKind::AnonConst`, it is allowed to reference outer
1387                    // generic parameters like an inline const.
1388                    self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);
1389                }
1390                InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
1391                InlineAsmOperand::Label { block } => self.visit_block(block),
1392            }
1393        }
1394    }
1395
1396    fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
1397        // This is similar to the code for AnonConst.
1398        self.with_rib(ValueNS, RibKind::InlineAsmSym, |this| {
1399            this.with_rib(TypeNS, RibKind::InlineAsmSym, |this| {
1400                this.with_label_rib(RibKind::InlineAsmSym, |this| {
1401                    this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));
1402                    visit::walk_inline_asm_sym(this, sym);
1403                });
1404            })
1405        });
1406    }
1407
1408    fn visit_variant(&mut self, v: &'ast Variant) {
1409        self.resolve_doc_links(&v.attrs, MaybeExported::Ok(v.id));
1410        visit::walk_variant(self, v)
1411    }
1412
1413    fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
1414        self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant);
1415    }
1416
1417    fn visit_field_def(&mut self, f: &'ast FieldDef) {
1418        self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));
1419        let FieldDef {
1420            attrs,
1421            id: _,
1422            span: _,
1423            vis,
1424            ident,
1425            ty,
1426            is_placeholder: _,
1427            default,
1428            safety: _,
1429        } = f;
1430        walk_list!(self, visit_attribute, attrs);
1431        try_visit!(self.visit_vis(vis));
1432        visit_opt!(self, visit_ident, ident);
1433        try_visit!(self.visit_ty(ty));
1434        if let Some(v) = &default {
1435            self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue);
1436        }
1437    }
1438}
1439
1440impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
1441    fn new(resolver: &'a mut Resolver<'ra, 'tcx>) -> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
1442        // During late resolution we only track the module component of the parent scope,
1443        // although it may be useful to track other components as well for diagnostics.
1444        let graph_root = resolver.graph_root;
1445        let parent_scope = ParentScope::module(graph_root, resolver);
1446        let start_rib_kind = RibKind::Module(graph_root);
1447        LateResolutionVisitor {
1448            r: resolver,
1449            parent_scope,
1450            ribs: PerNS {
1451                value_ns: vec![Rib::new(start_rib_kind)],
1452                type_ns: vec![Rib::new(start_rib_kind)],
1453                macro_ns: vec![Rib::new(start_rib_kind)],
1454            },
1455            last_block_rib: None,
1456            label_ribs: Vec::new(),
1457            lifetime_ribs: Vec::new(),
1458            lifetime_elision_candidates: None,
1459            current_trait_ref: None,
1460            diag_metadata: Default::default(),
1461            // errors at module scope should always be reported
1462            in_func_body: false,
1463            lifetime_uses: Default::default(),
1464        }
1465    }
1466
1467    fn maybe_resolve_ident_in_lexical_scope(
1468        &mut self,
1469        ident: Ident,
1470        ns: Namespace,
1471    ) -> Option<LexicalScopeBinding<'ra>> {
1472        self.r.resolve_ident_in_lexical_scope(
1473            ident,
1474            ns,
1475            &self.parent_scope,
1476            None,
1477            &self.ribs[ns],
1478            None,
1479        )
1480    }
1481
1482    fn resolve_ident_in_lexical_scope(
1483        &mut self,
1484        ident: Ident,
1485        ns: Namespace,
1486        finalize: Option<Finalize>,
1487        ignore_binding: Option<NameBinding<'ra>>,
1488    ) -> Option<LexicalScopeBinding<'ra>> {
1489        self.r.resolve_ident_in_lexical_scope(
1490            ident,
1491            ns,
1492            &self.parent_scope,
1493            finalize,
1494            &self.ribs[ns],
1495            ignore_binding,
1496        )
1497    }
1498
1499    fn resolve_path(
1500        &mut self,
1501        path: &[Segment],
1502        opt_ns: Option<Namespace>, // `None` indicates a module path in import
1503        finalize: Option<Finalize>,
1504    ) -> PathResult<'ra> {
1505        self.r.resolve_path_with_ribs(
1506            path,
1507            opt_ns,
1508            &self.parent_scope,
1509            finalize,
1510            Some(&self.ribs),
1511            None,
1512            None,
1513        )
1514    }
1515
1516    // AST resolution
1517    //
1518    // We maintain a list of value ribs and type ribs.
1519    //
1520    // Simultaneously, we keep track of the current position in the module
1521    // graph in the `parent_scope.module` pointer. When we go to resolve a name in
1522    // the value or type namespaces, we first look through all the ribs and
1523    // then query the module graph. When we resolve a name in the module
1524    // namespace, we can skip all the ribs (since nested modules are not
1525    // allowed within blocks in Rust) and jump straight to the current module
1526    // graph node.
1527    //
1528    // Named implementations are handled separately. When we find a method
1529    // call, we consult the module node to find all of the implementations in
1530    // scope. This information is lazily cached in the module node. We then
1531    // generate a fake "implementation scope" containing all the
1532    // implementations thus found, for compatibility with old resolve pass.
1533
1534    /// Do some `work` within a new innermost rib of the given `kind` in the given namespace (`ns`).
1535    fn with_rib<T>(
1536        &mut self,
1537        ns: Namespace,
1538        kind: RibKind<'ra>,
1539        work: impl FnOnce(&mut Self) -> T,
1540    ) -> T {
1541        self.ribs[ns].push(Rib::new(kind));
1542        let ret = work(self);
1543        self.ribs[ns].pop();
1544        ret
1545    }
1546
1547    fn with_scope<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
1548        if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) {
1549            // Move down in the graph.
1550            let orig_module = replace(&mut self.parent_scope.module, module);
1551            self.with_rib(ValueNS, RibKind::Module(module), |this| {
1552                this.with_rib(TypeNS, RibKind::Module(module), |this| {
1553                    let ret = f(this);
1554                    this.parent_scope.module = orig_module;
1555                    ret
1556                })
1557            })
1558        } else {
1559            f(self)
1560        }
1561    }
1562
1563    fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper: bool) {
1564        // For type parameter defaults, we have to ban access
1565        // to following type parameters, as the GenericArgs can only
1566        // provide previous type parameters as they're built. We
1567        // put all the parameters on the ban list and then remove
1568        // them one by one as they are processed and become available.
1569        let mut forward_ty_ban_rib =
1570            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
1571        let mut forward_const_ban_rib =
1572            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
1573        for param in params.iter() {
1574            match param.kind {
1575                GenericParamKind::Type { .. } => {
1576                    forward_ty_ban_rib
1577                        .bindings
1578                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);
1579                }
1580                GenericParamKind::Const { .. } => {
1581                    forward_const_ban_rib
1582                        .bindings
1583                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);
1584                }
1585                GenericParamKind::Lifetime => {}
1586            }
1587        }
1588
1589        // rust-lang/rust#61631: The type `Self` is essentially
1590        // another type parameter. For ADTs, we consider it
1591        // well-defined only after all of the ADT type parameters have
1592        // been provided. Therefore, we do not allow use of `Self`
1593        // anywhere in ADT type parameter defaults.
1594        //
1595        // (We however cannot ban `Self` for defaults on *all* generic
1596        // lists; e.g. trait generics can usefully refer to `Self`,
1597        // such as in the case of `trait Add<Rhs = Self>`.)
1598        if add_self_upper {
1599            // (`Some` if + only if we are in ADT's generics.)
1600            forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
1601        }
1602
1603        // NOTE: We use different ribs here not for a technical reason, but just
1604        // for better diagnostics.
1605        let mut forward_ty_ban_rib_const_param_ty = Rib {
1606            bindings: forward_ty_ban_rib.bindings.clone(),
1607            patterns_with_skipped_bindings: Default::default(),
1608            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
1609        };
1610        let mut forward_const_ban_rib_const_param_ty = Rib {
1611            bindings: forward_const_ban_rib.bindings.clone(),
1612            patterns_with_skipped_bindings: Default::default(),
1613            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
1614        };
1615        // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better
1616        // diagnostics, so we don't mention anything about const param tys having generics at all.
1617        if !self.r.tcx.features().generic_const_parameter_types() {
1618            forward_ty_ban_rib_const_param_ty.bindings.clear();
1619            forward_const_ban_rib_const_param_ty.bindings.clear();
1620        }
1621
1622        self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
1623            for param in params {
1624                match param.kind {
1625                    GenericParamKind::Lifetime => {
1626                        for bound in &param.bounds {
1627                            this.visit_param_bound(bound, BoundKind::Bound);
1628                        }
1629                    }
1630                    GenericParamKind::Type { ref default } => {
1631                        for bound in &param.bounds {
1632                            this.visit_param_bound(bound, BoundKind::Bound);
1633                        }
1634
1635                        if let Some(ty) = default {
1636                            this.ribs[TypeNS].push(forward_ty_ban_rib);
1637                            this.ribs[ValueNS].push(forward_const_ban_rib);
1638                            this.visit_ty(ty);
1639                            forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
1640                            forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
1641                        }
1642
1643                        // Allow all following defaults to refer to this type parameter.
1644                        let i = &Ident::with_dummy_span(param.ident.name);
1645                        forward_ty_ban_rib.bindings.remove(i);
1646                        forward_ty_ban_rib_const_param_ty.bindings.remove(i);
1647                    }
1648                    GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
1649                        // Const parameters can't have param bounds.
1650                        assert!(param.bounds.is_empty());
1651
1652                        this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty);
1653                        this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty);
1654                        if this.r.tcx.features().generic_const_parameter_types() {
1655                            this.visit_ty(ty)
1656                        } else {
1657                            this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
1658                            this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
1659                            this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
1660                                this.visit_ty(ty)
1661                            });
1662                            this.ribs[TypeNS].pop().unwrap();
1663                            this.ribs[ValueNS].pop().unwrap();
1664                        }
1665                        forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();
1666                        forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();
1667
1668                        if let Some(expr) = default {
1669                            this.ribs[TypeNS].push(forward_ty_ban_rib);
1670                            this.ribs[ValueNS].push(forward_const_ban_rib);
1671                            this.resolve_anon_const(
1672                                expr,
1673                                AnonConstKind::ConstArg(IsRepeatExpr::No),
1674                            );
1675                            forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
1676                            forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
1677                        }
1678
1679                        // Allow all following defaults to refer to this const parameter.
1680                        let i = &Ident::with_dummy_span(param.ident.name);
1681                        forward_const_ban_rib.bindings.remove(i);
1682                        forward_const_ban_rib_const_param_ty.bindings.remove(i);
1683                    }
1684                }
1685            }
1686        })
1687    }
1688
1689    #[instrument(level = "debug", skip(self, work))]
1690    fn with_lifetime_rib<T>(
1691        &mut self,
1692        kind: LifetimeRibKind,
1693        work: impl FnOnce(&mut Self) -> T,
1694    ) -> T {
1695        self.lifetime_ribs.push(LifetimeRib::new(kind));
1696        let outer_elision_candidates = self.lifetime_elision_candidates.take();
1697        let ret = work(self);
1698        self.lifetime_elision_candidates = outer_elision_candidates;
1699        self.lifetime_ribs.pop();
1700        ret
1701    }
1702
1703    #[instrument(level = "debug", skip(self))]
1704    fn resolve_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {
1705        let ident = lifetime.ident;
1706
1707        if ident.name == kw::StaticLifetime {
1708            self.record_lifetime_res(
1709                lifetime.id,
1710                LifetimeRes::Static { suppress_elision_warning: false },
1711                LifetimeElisionCandidate::Named,
1712            );
1713            return;
1714        }
1715
1716        if ident.name == kw::UnderscoreLifetime {
1717            return self.resolve_anonymous_lifetime(lifetime, lifetime.id, false);
1718        }
1719
1720        let mut lifetime_rib_iter = self.lifetime_ribs.iter().rev();
1721        while let Some(rib) = lifetime_rib_iter.next() {
1722            let normalized_ident = ident.normalize_to_macros_2_0();
1723            if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) {
1724                self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named);
1725
1726                if let LifetimeRes::Param { param, binder } = res {
1727                    match self.lifetime_uses.entry(param) {
1728                        Entry::Vacant(v) => {
1729                            debug!("First use of {:?} at {:?}", res, ident.span);
1730                            let use_set = self
1731                                .lifetime_ribs
1732                                .iter()
1733                                .rev()
1734                                .find_map(|rib| match rib.kind {
1735                                    // Do not suggest eliding a lifetime where an anonymous
1736                                    // lifetime would be illegal.
1737                                    LifetimeRibKind::Item
1738                                    | LifetimeRibKind::AnonymousReportError
1739                                    | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
1740                                    | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
1741                                    // An anonymous lifetime is legal here, and bound to the right
1742                                    // place, go ahead.
1743                                    LifetimeRibKind::AnonymousCreateParameter {
1744                                        binder: anon_binder,
1745                                        ..
1746                                    } => Some(if binder == anon_binder {
1747                                        LifetimeUseSet::One { use_span: ident.span, use_ctxt }
1748                                    } else {
1749                                        LifetimeUseSet::Many
1750                                    }),
1751                                    // Only report if eliding the lifetime would have the same
1752                                    // semantics.
1753                                    LifetimeRibKind::Elided(r) => Some(if res == r {
1754                                        LifetimeUseSet::One { use_span: ident.span, use_ctxt }
1755                                    } else {
1756                                        LifetimeUseSet::Many
1757                                    }),
1758                                    LifetimeRibKind::Generics { .. }
1759                                    | LifetimeRibKind::ConstParamTy => None,
1760                                    LifetimeRibKind::ConcreteAnonConst(_) => {
1761                                        span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)
1762                                    }
1763                                })
1764                                .unwrap_or(LifetimeUseSet::Many);
1765                            debug!(?use_ctxt, ?use_set);
1766                            v.insert(use_set);
1767                        }
1768                        Entry::Occupied(mut o) => {
1769                            debug!("Many uses of {:?} at {:?}", res, ident.span);
1770                            *o.get_mut() = LifetimeUseSet::Many;
1771                        }
1772                    }
1773                }
1774                return;
1775            }
1776
1777            match rib.kind {
1778                LifetimeRibKind::Item => break,
1779                LifetimeRibKind::ConstParamTy => {
1780                    self.emit_non_static_lt_in_const_param_ty_error(lifetime);
1781                    self.record_lifetime_res(
1782                        lifetime.id,
1783                        LifetimeRes::Error,
1784                        LifetimeElisionCandidate::Ignore,
1785                    );
1786                    return;
1787                }
1788                LifetimeRibKind::ConcreteAnonConst(cause) => {
1789                    self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
1790                    self.record_lifetime_res(
1791                        lifetime.id,
1792                        LifetimeRes::Error,
1793                        LifetimeElisionCandidate::Ignore,
1794                    );
1795                    return;
1796                }
1797                LifetimeRibKind::AnonymousCreateParameter { .. }
1798                | LifetimeRibKind::Elided(_)
1799                | LifetimeRibKind::Generics { .. }
1800                | LifetimeRibKind::ElisionFailure
1801                | LifetimeRibKind::AnonymousReportError
1802                | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {}
1803            }
1804        }
1805
1806        let normalized_ident = ident.normalize_to_macros_2_0();
1807        let outer_res = lifetime_rib_iter
1808            .find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer));
1809
1810        self.emit_undeclared_lifetime_error(lifetime, outer_res);
1811        self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named);
1812    }
1813
1814    #[instrument(level = "debug", skip(self))]
1815    fn resolve_anonymous_lifetime(
1816        &mut self,
1817        lifetime: &Lifetime,
1818        id_for_lint: NodeId,
1819        elided: bool,
1820    ) {
1821        debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
1822
1823        let kind =
1824            if elided { MissingLifetimeKind::Ampersand } else { MissingLifetimeKind::Underscore };
1825        let missing_lifetime = MissingLifetime {
1826            id: lifetime.id,
1827            span: lifetime.ident.span,
1828            kind,
1829            count: 1,
1830            id_for_lint,
1831        };
1832        let elision_candidate = LifetimeElisionCandidate::Missing(missing_lifetime);
1833        for (i, rib) in self.lifetime_ribs.iter().enumerate().rev() {
1834            debug!(?rib.kind);
1835            match rib.kind {
1836                LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
1837                    let res = self.create_fresh_lifetime(lifetime.ident, binder, kind);
1838                    self.record_lifetime_res(lifetime.id, res, elision_candidate);
1839                    return;
1840                }
1841                LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {
1842                    let mut lifetimes_in_scope = vec![];
1843                    for rib in &self.lifetime_ribs[..i] {
1844                        lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));
1845                        // Consider any anonymous lifetimes, too
1846                        if let LifetimeRibKind::AnonymousCreateParameter { binder, .. } = rib.kind
1847                            && let Some(extra) = self.r.extra_lifetime_params_map.get(&binder)
1848                        {
1849                            lifetimes_in_scope.extend(extra.iter().map(|(ident, _, _)| ident.span));
1850                        }
1851                    }
1852                    if lifetimes_in_scope.is_empty() {
1853                        self.record_lifetime_res(
1854                            lifetime.id,
1855                            // We are inside a const item, so do not warn.
1856                            LifetimeRes::Static { suppress_elision_warning: true },
1857                            elision_candidate,
1858                        );
1859                        return;
1860                    } else if emit_lint {
1861                        self.r.lint_buffer.buffer_lint(
1862                            lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
1863                            node_id,
1864                            lifetime.ident.span,
1865                            lint::BuiltinLintDiag::AssociatedConstElidedLifetime {
1866                                elided,
1867                                span: lifetime.ident.span,
1868                                lifetimes_in_scope: lifetimes_in_scope.into(),
1869                            },
1870                        );
1871                    }
1872                }
1873                LifetimeRibKind::AnonymousReportError => {
1874                    if elided {
1875                        let suggestion = self.lifetime_ribs[i..].iter().rev().find_map(|rib| {
1876                            if let LifetimeRibKind::Generics {
1877                                span,
1878                                kind: LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound,
1879                                ..
1880                            } = rib.kind
1881                            {
1882                                Some(errors::ElidedAnonymousLivetimeReportErrorSuggestion {
1883                                    lo: span.shrink_to_lo(),
1884                                    hi: lifetime.ident.span.shrink_to_hi(),
1885                                })
1886                            } else {
1887                                None
1888                            }
1889                        });
1890                        // are we trying to use an anonymous lifetime
1891                        // on a non GAT associated trait type?
1892                        if !self.in_func_body
1893                            && let Some((module, _)) = &self.current_trait_ref
1894                            && let Some(ty) = &self.diag_metadata.current_self_type
1895                            && Some(true) == self.diag_metadata.in_non_gat_assoc_type
1896                            && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind
1897                        {
1898                            if def_id_matches_path(
1899                                self.r.tcx,
1900                                trait_id,
1901                                &["core", "iter", "traits", "iterator", "Iterator"],
1902                            ) {
1903                                self.r.dcx().emit_err(errors::LendingIteratorReportError {
1904                                    lifetime: lifetime.ident.span,
1905                                    ty: ty.span,
1906                                });
1907                            } else {
1908                                self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError {
1909                                    lifetime: lifetime.ident.span,
1910                                });
1911                            }
1912                        } else {
1913                            self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
1914                                span: lifetime.ident.span,
1915                                suggestion,
1916                            });
1917                        }
1918                    } else {
1919                        self.r.dcx().emit_err(errors::ExplicitAnonymousLivetimeReportError {
1920                            span: lifetime.ident.span,
1921                        });
1922                    };
1923                    self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1924                    return;
1925                }
1926                LifetimeRibKind::Elided(res) => {
1927                    self.record_lifetime_res(lifetime.id, res, elision_candidate);
1928                    return;
1929                }
1930                LifetimeRibKind::ElisionFailure => {
1931                    self.diag_metadata.current_elision_failures.push(missing_lifetime);
1932                    self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1933                    return;
1934                }
1935                LifetimeRibKind::Item => break,
1936                LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
1937                LifetimeRibKind::ConcreteAnonConst(_) => {
1938                    // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
1939                    span_bug!(lifetime.ident.span, "unexpected rib kind: {:?}", rib.kind)
1940                }
1941            }
1942        }
1943        self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1944        self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
1945    }
1946
1947    #[instrument(level = "debug", skip(self))]
1948    fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) {
1949        let id = self.r.next_node_id();
1950        let lt = Lifetime { id, ident: Ident::new(kw::UnderscoreLifetime, span) };
1951
1952        self.record_lifetime_res(
1953            anchor_id,
1954            LifetimeRes::ElidedAnchor { start: id, end: NodeId::from_u32(id.as_u32() + 1) },
1955            LifetimeElisionCandidate::Ignore,
1956        );
1957        self.resolve_anonymous_lifetime(&lt, anchor_id, true);
1958    }
1959
1960    #[instrument(level = "debug", skip(self))]
1961    fn create_fresh_lifetime(
1962        &mut self,
1963        ident: Ident,
1964        binder: NodeId,
1965        kind: MissingLifetimeKind,
1966    ) -> LifetimeRes {
1967        debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1968        debug!(?ident.span);
1969
1970        // Leave the responsibility to create the `LocalDefId` to lowering.
1971        let param = self.r.next_node_id();
1972        let res = LifetimeRes::Fresh { param, binder, kind };
1973        self.record_lifetime_param(param, res);
1974
1975        // Record the created lifetime parameter so lowering can pick it up and add it to HIR.
1976        self.r
1977            .extra_lifetime_params_map
1978            .entry(binder)
1979            .or_insert_with(Vec::new)
1980            .push((ident, param, res));
1981        res
1982    }
1983
1984    #[instrument(level = "debug", skip(self))]
1985    fn resolve_elided_lifetimes_in_path(
1986        &mut self,
1987        partial_res: PartialRes,
1988        path: &[Segment],
1989        source: PathSource<'_>,
1990        path_span: Span,
1991    ) {
1992        let proj_start = path.len() - partial_res.unresolved_segments();
1993        for (i, segment) in path.iter().enumerate() {
1994            if segment.has_lifetime_args {
1995                continue;
1996            }
1997            let Some(segment_id) = segment.id else {
1998                continue;
1999            };
2000
2001            // Figure out if this is a type/trait segment,
2002            // which may need lifetime elision performed.
2003            let type_def_id = match partial_res.base_res() {
2004                Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => {
2005                    self.r.tcx.parent(def_id)
2006                }
2007                Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => {
2008                    self.r.tcx.parent(def_id)
2009                }
2010                Res::Def(DefKind::Struct, def_id)
2011                | Res::Def(DefKind::Union, def_id)
2012                | Res::Def(DefKind::Enum, def_id)
2013                | Res::Def(DefKind::TyAlias, def_id)
2014                | Res::Def(DefKind::Trait, def_id)
2015                    if i + 1 == proj_start =>
2016                {
2017                    def_id
2018                }
2019                _ => continue,
2020            };
2021
2022            let expected_lifetimes = self.r.item_generics_num_lifetimes(type_def_id);
2023            if expected_lifetimes == 0 {
2024                continue;
2025            }
2026
2027            let node_ids = self.r.next_node_ids(expected_lifetimes);
2028            self.record_lifetime_res(
2029                segment_id,
2030                LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end },
2031                LifetimeElisionCandidate::Ignore,
2032            );
2033
2034            let inferred = match source {
2035                PathSource::Trait(..)
2036                | PathSource::TraitItem(..)
2037                | PathSource::Type
2038                | PathSource::PreciseCapturingArg(..)
2039                | PathSource::ReturnTypeNotation => false,
2040                PathSource::Expr(..)
2041                | PathSource::Pat
2042                | PathSource::Struct
2043                | PathSource::TupleStruct(..)
2044                | PathSource::DefineOpaques
2045                | PathSource::Delegation => true,
2046            };
2047            if inferred {
2048                // Do not create a parameter for patterns and expressions: type checking can infer
2049                // the appropriate lifetime for us.
2050                for id in node_ids {
2051                    self.record_lifetime_res(
2052                        id,
2053                        LifetimeRes::Infer,
2054                        LifetimeElisionCandidate::Named,
2055                    );
2056                }
2057                continue;
2058            }
2059
2060            let elided_lifetime_span = if segment.has_generic_args {
2061                // If there are brackets, but not generic arguments, then use the opening bracket
2062                segment.args_span.with_hi(segment.args_span.lo() + BytePos(1))
2063            } else {
2064                // If there are no brackets, use the identifier span.
2065                // HACK: we use find_ancestor_inside to properly suggest elided spans in paths
2066                // originating from macros, since the segment's span might be from a macro arg.
2067                segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
2068            };
2069            let ident = Ident::new(kw::UnderscoreLifetime, elided_lifetime_span);
2070
2071            let kind = if segment.has_generic_args {
2072                MissingLifetimeKind::Comma
2073            } else {
2074                MissingLifetimeKind::Brackets
2075            };
2076            let missing_lifetime = MissingLifetime {
2077                id: node_ids.start,
2078                id_for_lint: segment_id,
2079                span: elided_lifetime_span,
2080                kind,
2081                count: expected_lifetimes,
2082            };
2083            let mut should_lint = true;
2084            for rib in self.lifetime_ribs.iter().rev() {
2085                match rib.kind {
2086                    // In create-parameter mode we error here because we don't want to support
2087                    // deprecated impl elision in new features like impl elision and `async fn`,
2088                    // both of which work using the `CreateParameter` mode:
2089                    //
2090                    //     impl Foo for std::cell::Ref<u32> // note lack of '_
2091                    //     async fn foo(_: std::cell::Ref<u32>) { ... }
2092                    LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
2093                    | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {
2094                        let sess = self.r.tcx.sess;
2095                        let subdiag = rustc_errors::elided_lifetime_in_path_suggestion(
2096                            sess.source_map(),
2097                            expected_lifetimes,
2098                            path_span,
2099                            !segment.has_generic_args,
2100                            elided_lifetime_span,
2101                        );
2102                        self.r.dcx().emit_err(errors::ImplicitElidedLifetimeNotAllowedHere {
2103                            span: path_span,
2104                            subdiag,
2105                        });
2106                        should_lint = false;
2107
2108                        for id in node_ids {
2109                            self.record_lifetime_res(
2110                                id,
2111                                LifetimeRes::Error,
2112                                LifetimeElisionCandidate::Named,
2113                            );
2114                        }
2115                        break;
2116                    }
2117                    // Do not create a parameter for patterns and expressions.
2118                    LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
2119                        // Group all suggestions into the first record.
2120                        let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime);
2121                        for id in node_ids {
2122                            let res = self.create_fresh_lifetime(ident, binder, kind);
2123                            self.record_lifetime_res(
2124                                id,
2125                                res,
2126                                replace(&mut candidate, LifetimeElisionCandidate::Named),
2127                            );
2128                        }
2129                        break;
2130                    }
2131                    LifetimeRibKind::Elided(res) => {
2132                        let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime);
2133                        for id in node_ids {
2134                            self.record_lifetime_res(
2135                                id,
2136                                res,
2137                                replace(&mut candidate, LifetimeElisionCandidate::Ignore),
2138                            );
2139                        }
2140                        break;
2141                    }
2142                    LifetimeRibKind::ElisionFailure => {
2143                        self.diag_metadata.current_elision_failures.push(missing_lifetime);
2144                        for id in node_ids {
2145                            self.record_lifetime_res(
2146                                id,
2147                                LifetimeRes::Error,
2148                                LifetimeElisionCandidate::Ignore,
2149                            );
2150                        }
2151                        break;
2152                    }
2153                    // `LifetimeRes::Error`, which would usually be used in the case of
2154                    // `ReportError`, is unsuitable here, as we don't emit an error yet. Instead,
2155                    // we simply resolve to an implicit lifetime, which will be checked later, at
2156                    // which point a suitable error will be emitted.
2157                    LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => {
2158                        for id in node_ids {
2159                            self.record_lifetime_res(
2160                                id,
2161                                LifetimeRes::Error,
2162                                LifetimeElisionCandidate::Ignore,
2163                            );
2164                        }
2165                        self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
2166                        break;
2167                    }
2168                    LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
2169                    LifetimeRibKind::ConcreteAnonConst(_) => {
2170                        // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
2171                        span_bug!(elided_lifetime_span, "unexpected rib kind: {:?}", rib.kind)
2172                    }
2173                }
2174            }
2175
2176            if should_lint {
2177                self.r.lint_buffer.buffer_lint(
2178                    lint::builtin::ELIDED_LIFETIMES_IN_PATHS,
2179                    segment_id,
2180                    elided_lifetime_span,
2181                    lint::BuiltinLintDiag::ElidedLifetimesInPaths(
2182                        expected_lifetimes,
2183                        path_span,
2184                        !segment.has_generic_args,
2185                        elided_lifetime_span,
2186                    ),
2187                );
2188            }
2189        }
2190    }
2191
2192    #[instrument(level = "debug", skip(self))]
2193    fn record_lifetime_res(
2194        &mut self,
2195        id: NodeId,
2196        res: LifetimeRes,
2197        candidate: LifetimeElisionCandidate,
2198    ) {
2199        if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
2200            panic!("lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)")
2201        }
2202
2203        match candidate {
2204            LifetimeElisionCandidate::Missing(missing @ MissingLifetime { .. }) => {
2205                debug_assert_eq!(id, missing.id);
2206                match res {
2207                    LifetimeRes::Static { suppress_elision_warning } => {
2208                        if !suppress_elision_warning {
2209                            self.r.lint_buffer.buffer_lint(
2210                                lint::builtin::ELIDED_NAMED_LIFETIMES,
2211                                missing.id_for_lint,
2212                                missing.span,
2213                                BuiltinLintDiag::ElidedNamedLifetimes {
2214                                    elided: (missing.span, missing.kind),
2215                                    resolution: lint::ElidedLifetimeResolution::Static,
2216                                },
2217                            );
2218                        }
2219                    }
2220                    LifetimeRes::Param { param, binder: _ } => {
2221                        let tcx = self.r.tcx();
2222                        self.r.lint_buffer.buffer_lint(
2223                            lint::builtin::ELIDED_NAMED_LIFETIMES,
2224                            missing.id_for_lint,
2225                            missing.span,
2226                            BuiltinLintDiag::ElidedNamedLifetimes {
2227                                elided: (missing.span, missing.kind),
2228                                resolution: lint::ElidedLifetimeResolution::Param(
2229                                    tcx.item_name(param.into()),
2230                                    tcx.source_span(param),
2231                                ),
2232                            },
2233                        );
2234                    }
2235                    LifetimeRes::Fresh { .. }
2236                    | LifetimeRes::Infer
2237                    | LifetimeRes::Error
2238                    | LifetimeRes::ElidedAnchor { .. } => {}
2239                }
2240            }
2241            LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {}
2242        }
2243
2244        match res {
2245            LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static { .. } => {
2246                if let Some(ref mut candidates) = self.lifetime_elision_candidates {
2247                    candidates.push((res, candidate));
2248                }
2249            }
2250            LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
2251        }
2252    }
2253
2254    #[instrument(level = "debug", skip(self))]
2255    fn record_lifetime_param(&mut self, id: NodeId, res: LifetimeRes) {
2256        if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
2257            panic!(
2258                "lifetime parameter {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)"
2259            )
2260        }
2261    }
2262
2263    /// Perform resolution of a function signature, accounting for lifetime elision.
2264    #[instrument(level = "debug", skip(self, inputs))]
2265    fn resolve_fn_signature(
2266        &mut self,
2267        fn_id: NodeId,
2268        has_self: bool,
2269        inputs: impl Iterator<Item = (Option<&'ast Pat>, &'ast Ty)> + Clone,
2270        output_ty: &'ast FnRetTy,
2271    ) {
2272        // Add each argument to the rib.
2273        let elision_lifetime = self.resolve_fn_params(has_self, inputs);
2274        debug!(?elision_lifetime);
2275
2276        let outer_failures = take(&mut self.diag_metadata.current_elision_failures);
2277        let output_rib = if let Ok(res) = elision_lifetime.as_ref() {
2278            self.r.lifetime_elision_allowed.insert(fn_id);
2279            LifetimeRibKind::Elided(*res)
2280        } else {
2281            LifetimeRibKind::ElisionFailure
2282        };
2283        self.with_lifetime_rib(output_rib, |this| visit::walk_fn_ret_ty(this, output_ty));
2284        let elision_failures =
2285            replace(&mut self.diag_metadata.current_elision_failures, outer_failures);
2286        if !elision_failures.is_empty() {
2287            let Err(failure_info) = elision_lifetime else { bug!() };
2288            self.report_missing_lifetime_specifiers(elision_failures, Some(failure_info));
2289        }
2290    }
2291
2292    /// Resolve inside function parameters and parameter types.
2293    /// Returns the lifetime for elision in fn return type,
2294    /// or diagnostic information in case of elision failure.
2295    fn resolve_fn_params(
2296        &mut self,
2297        has_self: bool,
2298        inputs: impl Iterator<Item = (Option<&'ast Pat>, &'ast Ty)>,
2299    ) -> Result<LifetimeRes, (Vec<MissingLifetime>, Vec<ElisionFnParameter>)> {
2300        enum Elision {
2301            /// We have not found any candidate.
2302            None,
2303            /// We have a candidate bound to `self`.
2304            Self_(LifetimeRes),
2305            /// We have a candidate bound to a parameter.
2306            Param(LifetimeRes),
2307            /// We failed elision.
2308            Err,
2309        }
2310
2311        // Save elision state to reinstate it later.
2312        let outer_candidates = self.lifetime_elision_candidates.take();
2313
2314        // Result of elision.
2315        let mut elision_lifetime = Elision::None;
2316        // Information for diagnostics.
2317        let mut parameter_info = Vec::new();
2318        let mut all_candidates = Vec::new();
2319
2320        let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
2321        for (index, (pat, ty)) in inputs.enumerate() {
2322            debug!(?pat, ?ty);
2323            self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
2324                if let Some(pat) = pat {
2325                    this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
2326                }
2327            });
2328
2329            // Record elision candidates only for this parameter.
2330            debug_assert_matches!(self.lifetime_elision_candidates, None);
2331            self.lifetime_elision_candidates = Some(Default::default());
2332            self.visit_ty(ty);
2333            let local_candidates = self.lifetime_elision_candidates.take();
2334
2335            if let Some(candidates) = local_candidates {
2336                let distinct: UnordSet<_> = candidates.iter().map(|(res, _)| *res).collect();
2337                let lifetime_count = distinct.len();
2338                if lifetime_count != 0 {
2339                    parameter_info.push(ElisionFnParameter {
2340                        index,
2341                        ident: if let Some(pat) = pat
2342                            && let PatKind::Ident(_, ident, _) = pat.kind
2343                        {
2344                            Some(ident)
2345                        } else {
2346                            None
2347                        },
2348                        lifetime_count,
2349                        span: ty.span,
2350                    });
2351                    all_candidates.extend(candidates.into_iter().filter_map(|(_, candidate)| {
2352                        match candidate {
2353                            LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {
2354                                None
2355                            }
2356                            LifetimeElisionCandidate::Missing(missing) => Some(missing),
2357                        }
2358                    }));
2359                }
2360                if !distinct.is_empty() {
2361                    match elision_lifetime {
2362                        // We are the first parameter to bind lifetimes.
2363                        Elision::None => {
2364                            if let Some(res) = distinct.get_only() {
2365                                // We have a single lifetime => success.
2366                                elision_lifetime = Elision::Param(*res)
2367                            } else {
2368                                // We have multiple lifetimes => error.
2369                                elision_lifetime = Elision::Err;
2370                            }
2371                        }
2372                        // We have 2 parameters that bind lifetimes => error.
2373                        Elision::Param(_) => elision_lifetime = Elision::Err,
2374                        // `self` elision takes precedence over everything else.
2375                        Elision::Self_(_) | Elision::Err => {}
2376                    }
2377                }
2378            }
2379
2380            // Handle `self` specially.
2381            if index == 0 && has_self {
2382                let self_lifetime = self.find_lifetime_for_self(ty);
2383                elision_lifetime = match self_lifetime {
2384                    // We found `self` elision.
2385                    Set1::One(lifetime) => Elision::Self_(lifetime),
2386                    // `self` itself had ambiguous lifetimes, e.g.
2387                    // &Box<&Self>. In this case we won't consider
2388                    // taking an alternative parameter lifetime; just avoid elision
2389                    // entirely.
2390                    Set1::Many => Elision::Err,
2391                    // We do not have `self` elision: disregard the `Elision::Param` that we may
2392                    // have found.
2393                    Set1::Empty => Elision::None,
2394                }
2395            }
2396            debug!("(resolving function / closure) recorded parameter");
2397        }
2398
2399        // Reinstate elision state.
2400        debug_assert_matches!(self.lifetime_elision_candidates, None);
2401        self.lifetime_elision_candidates = outer_candidates;
2402
2403        if let Elision::Param(res) | Elision::Self_(res) = elision_lifetime {
2404            return Ok(res);
2405        }
2406
2407        // We do not have a candidate.
2408        Err((all_candidates, parameter_info))
2409    }
2410
2411    /// List all the lifetimes that appear in the provided type.
2412    fn find_lifetime_for_self(&self, ty: &'ast Ty) -> Set1<LifetimeRes> {
2413        /// Visits a type to find all the &references, and determines the
2414        /// set of lifetimes for all of those references where the referent
2415        /// contains Self.
2416        struct FindReferenceVisitor<'a, 'ra, 'tcx> {
2417            r: &'a Resolver<'ra, 'tcx>,
2418            impl_self: Option<Res>,
2419            lifetime: Set1<LifetimeRes>,
2420        }
2421
2422        impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> {
2423            fn visit_ty(&mut self, ty: &'ra Ty) {
2424                trace!("FindReferenceVisitor considering ty={:?}", ty);
2425                if let TyKind::Ref(lt, _) | TyKind::PinnedRef(lt, _) = ty.kind {
2426                    // See if anything inside the &thing contains Self
2427                    let mut visitor =
2428                        SelfVisitor { r: self.r, impl_self: self.impl_self, self_found: false };
2429                    visitor.visit_ty(ty);
2430                    trace!("FindReferenceVisitor: SelfVisitor self_found={:?}", visitor.self_found);
2431                    if visitor.self_found {
2432                        let lt_id = if let Some(lt) = lt {
2433                            lt.id
2434                        } else {
2435                            let res = self.r.lifetimes_res_map[&ty.id];
2436                            let LifetimeRes::ElidedAnchor { start, .. } = res else { bug!() };
2437                            start
2438                        };
2439                        let lt_res = self.r.lifetimes_res_map[&lt_id];
2440                        trace!("FindReferenceVisitor inserting res={:?}", lt_res);
2441                        self.lifetime.insert(lt_res);
2442                    }
2443                }
2444                visit::walk_ty(self, ty)
2445            }
2446
2447            // A type may have an expression as a const generic argument.
2448            // We do not want to recurse into those.
2449            fn visit_expr(&mut self, _: &'ra Expr) {}
2450        }
2451
2452        /// Visitor which checks the referent of a &Thing to see if the
2453        /// Thing contains Self
2454        struct SelfVisitor<'a, 'ra, 'tcx> {
2455            r: &'a Resolver<'ra, 'tcx>,
2456            impl_self: Option<Res>,
2457            self_found: bool,
2458        }
2459
2460        impl SelfVisitor<'_, '_, '_> {
2461            // Look for `self: &'a Self` - also desugared from `&'a self`
2462            fn is_self_ty(&self, ty: &Ty) -> bool {
2463                match ty.kind {
2464                    TyKind::ImplicitSelf => true,
2465                    TyKind::Path(None, _) => {
2466                        let path_res = self.r.partial_res_map[&ty.id].full_res();
2467                        if let Some(Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }) = path_res {
2468                            return true;
2469                        }
2470                        self.impl_self.is_some() && path_res == self.impl_self
2471                    }
2472                    _ => false,
2473                }
2474            }
2475        }
2476
2477        impl<'ra> Visitor<'ra> for SelfVisitor<'_, '_, '_> {
2478            fn visit_ty(&mut self, ty: &'ra Ty) {
2479                trace!("SelfVisitor considering ty={:?}", ty);
2480                if self.is_self_ty(ty) {
2481                    trace!("SelfVisitor found Self");
2482                    self.self_found = true;
2483                }
2484                visit::walk_ty(self, ty)
2485            }
2486
2487            // A type may have an expression as a const generic argument.
2488            // We do not want to recurse into those.
2489            fn visit_expr(&mut self, _: &'ra Expr) {}
2490        }
2491
2492        let impl_self = self
2493            .diag_metadata
2494            .current_self_type
2495            .as_ref()
2496            .and_then(|ty| {
2497                if let TyKind::Path(None, _) = ty.kind {
2498                    self.r.partial_res_map.get(&ty.id)
2499                } else {
2500                    None
2501                }
2502            })
2503            .and_then(|res| res.full_res())
2504            .filter(|res| {
2505                // Permit the types that unambiguously always
2506                // result in the same type constructor being used
2507                // (it can't differ between `Self` and `self`).
2508                matches!(
2509                    res,
2510                    Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, _,) | Res::PrimTy(_)
2511                )
2512            });
2513        let mut visitor = FindReferenceVisitor { r: self.r, impl_self, lifetime: Set1::Empty };
2514        visitor.visit_ty(ty);
2515        trace!("FindReferenceVisitor found={:?}", visitor.lifetime);
2516        visitor.lifetime
2517    }
2518
2519    /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
2520    /// label and reports an error if the label is not found or is unreachable.
2521    fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'ra>> {
2522        let mut suggestion = None;
2523
2524        for i in (0..self.label_ribs.len()).rev() {
2525            let rib = &self.label_ribs[i];
2526
2527            if let RibKind::MacroDefinition(def) = rib.kind
2528                // If an invocation of this macro created `ident`, give up on `ident`
2529                // and switch to `ident`'s source from the macro definition.
2530                && def == self.r.macro_def(label.span.ctxt())
2531            {
2532                label.span.remove_mark();
2533            }
2534
2535            let ident = label.normalize_to_macro_rules();
2536            if let Some((ident, id)) = rib.bindings.get_key_value(&ident) {
2537                let definition_span = ident.span;
2538                return if self.is_label_valid_from_rib(i) {
2539                    Ok((*id, definition_span))
2540                } else {
2541                    Err(ResolutionError::UnreachableLabel {
2542                        name: label.name,
2543                        definition_span,
2544                        suggestion,
2545                    })
2546                };
2547            }
2548
2549            // Diagnostics: Check if this rib contains a label with a similar name, keep track of
2550            // the first such label that is encountered.
2551            suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label));
2552        }
2553
2554        Err(ResolutionError::UndeclaredLabel { name: label.name, suggestion })
2555    }
2556
2557    /// Determine whether or not a label from the `rib_index`th label rib is reachable.
2558    fn is_label_valid_from_rib(&self, rib_index: usize) -> bool {
2559        let ribs = &self.label_ribs[rib_index + 1..];
2560        ribs.iter().all(|rib| !rib.kind.is_label_barrier())
2561    }
2562
2563    fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) {
2564        debug!("resolve_adt");
2565        let kind = self.r.local_def_kind(item.id);
2566        self.with_current_self_item(item, |this| {
2567            this.with_generic_param_rib(
2568                &generics.params,
2569                RibKind::Item(HasGenericParams::Yes(generics.span), kind),
2570                LifetimeRibKind::Generics {
2571                    binder: item.id,
2572                    kind: LifetimeBinderKind::Item,
2573                    span: generics.span,
2574                },
2575                |this| {
2576                    let item_def_id = this.r.local_def_id(item.id).to_def_id();
2577                    this.with_self_rib(
2578                        Res::SelfTyAlias {
2579                            alias_to: item_def_id,
2580                            forbid_generic: false,
2581                            is_trait_impl: false,
2582                        },
2583                        |this| {
2584                            visit::walk_item(this, item);
2585                        },
2586                    );
2587                },
2588            );
2589        });
2590    }
2591
2592    fn future_proof_import(&mut self, use_tree: &UseTree) {
2593        if let [segment, rest @ ..] = use_tree.prefix.segments.as_slice() {
2594            let ident = segment.ident;
2595            if ident.is_path_segment_keyword() || ident.span.is_rust_2015() {
2596                return;
2597            }
2598
2599            let nss = match use_tree.kind {
2600                UseTreeKind::Simple(..) if rest.is_empty() => &[TypeNS, ValueNS][..],
2601                _ => &[TypeNS],
2602            };
2603            let report_error = |this: &Self, ns| {
2604                if this.should_report_errs() {
2605                    let what = if ns == TypeNS { "type parameters" } else { "local variables" };
2606                    this.r.dcx().emit_err(errors::ImportsCannotReferTo { span: ident.span, what });
2607                }
2608            };
2609
2610            for &ns in nss {
2611                match self.maybe_resolve_ident_in_lexical_scope(ident, ns) {
2612                    Some(LexicalScopeBinding::Res(..)) => {
2613                        report_error(self, ns);
2614                    }
2615                    Some(LexicalScopeBinding::Item(binding)) => {
2616                        if let Some(LexicalScopeBinding::Res(..)) =
2617                            self.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding))
2618                        {
2619                            report_error(self, ns);
2620                        }
2621                    }
2622                    None => {}
2623                }
2624            }
2625        } else if let UseTreeKind::Nested { items, .. } = &use_tree.kind {
2626            for (use_tree, _) in items {
2627                self.future_proof_import(use_tree);
2628            }
2629        }
2630    }
2631
2632    fn resolve_item(&mut self, item: &'ast Item) {
2633        let mod_inner_docs =
2634            matches!(item.kind, ItemKind::Mod(..)) && rustdoc::inner_docs(&item.attrs);
2635        if !mod_inner_docs && !matches!(item.kind, ItemKind::Impl(..) | ItemKind::Use(..)) {
2636            self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
2637        }
2638
2639        let name = item.ident.name;
2640        debug!("(resolving item) resolving {} ({:?})", name, item.kind);
2641
2642        let def_kind = self.r.local_def_kind(item.id);
2643        match item.kind {
2644            ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
2645                self.with_generic_param_rib(
2646                    &generics.params,
2647                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
2648                    LifetimeRibKind::Generics {
2649                        binder: item.id,
2650                        kind: LifetimeBinderKind::Item,
2651                        span: generics.span,
2652                    },
2653                    |this| visit::walk_item(this, item),
2654                );
2655            }
2656
2657            ItemKind::Fn(box Fn { ref generics, ref define_opaque, .. }) => {
2658                self.with_generic_param_rib(
2659                    &generics.params,
2660                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
2661                    LifetimeRibKind::Generics {
2662                        binder: item.id,
2663                        kind: LifetimeBinderKind::Function,
2664                        span: generics.span,
2665                    },
2666                    |this| visit::walk_item(this, item),
2667                );
2668
2669                for (id, path) in define_opaque.iter().flatten() {
2670                    self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
2671                }
2672            }
2673
2674            ItemKind::Enum(_, ref generics)
2675            | ItemKind::Struct(_, ref generics)
2676            | ItemKind::Union(_, ref generics) => {
2677                self.resolve_adt(item, generics);
2678            }
2679
2680            ItemKind::Impl(box Impl {
2681                ref generics,
2682                ref of_trait,
2683                ref self_ty,
2684                items: ref impl_items,
2685                ..
2686            }) => {
2687                self.diag_metadata.current_impl_items = Some(impl_items);
2688                self.resolve_implementation(
2689                    &item.attrs,
2690                    generics,
2691                    of_trait,
2692                    self_ty,
2693                    item.id,
2694                    impl_items,
2695                );
2696                self.diag_metadata.current_impl_items = None;
2697            }
2698
2699            ItemKind::Trait(box Trait { ref generics, ref bounds, ref items, .. }) => {
2700                // Create a new rib for the trait-wide type parameters.
2701                self.with_generic_param_rib(
2702                    &generics.params,
2703                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
2704                    LifetimeRibKind::Generics {
2705                        binder: item.id,
2706                        kind: LifetimeBinderKind::Item,
2707                        span: generics.span,
2708                    },
2709                    |this| {
2710                        let local_def_id = this.r.local_def_id(item.id).to_def_id();
2711                        this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| {
2712                            this.visit_generics(generics);
2713                            walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits);
2714                            this.resolve_trait_items(items);
2715                        });
2716                    },
2717                );
2718            }
2719
2720            ItemKind::TraitAlias(ref generics, ref bounds) => {
2721                // Create a new rib for the trait-wide type parameters.
2722                self.with_generic_param_rib(
2723                    &generics.params,
2724                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
2725                    LifetimeRibKind::Generics {
2726                        binder: item.id,
2727                        kind: LifetimeBinderKind::Item,
2728                        span: generics.span,
2729                    },
2730                    |this| {
2731                        let local_def_id = this.r.local_def_id(item.id).to_def_id();
2732                        this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| {
2733                            this.visit_generics(generics);
2734                            walk_list!(this, visit_param_bound, bounds, BoundKind::Bound);
2735                        });
2736                    },
2737                );
2738            }
2739
2740            ItemKind::Mod(..) => {
2741                self.with_scope(item.id, |this| {
2742                    if mod_inner_docs {
2743                        this.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
2744                    }
2745                    let old_macro_rules = this.parent_scope.macro_rules;
2746                    visit::walk_item(this, item);
2747                    // Maintain macro_rules scopes in the same way as during early resolution
2748                    // for diagnostics and doc links.
2749                    if item.attrs.iter().all(|attr| {
2750                        !attr.has_name(sym::macro_use) && !attr.has_name(sym::macro_escape)
2751                    }) {
2752                        this.parent_scope.macro_rules = old_macro_rules;
2753                    }
2754                });
2755            }
2756
2757            ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
2758                self.with_static_rib(def_kind, |this| {
2759                    this.with_lifetime_rib(
2760                        LifetimeRibKind::Elided(LifetimeRes::Static {
2761                            suppress_elision_warning: true,
2762                        }),
2763                        |this| {
2764                            this.visit_ty(ty);
2765                        },
2766                    );
2767                    if let Some(expr) = expr {
2768                        // We already forbid generic params because of the above item rib,
2769                        // so it doesn't matter whether this is a trivial constant.
2770                        this.resolve_const_body(expr, Some((item.ident, ConstantItemKind::Static)));
2771                    }
2772                });
2773            }
2774
2775            ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
2776                self.with_generic_param_rib(
2777                    &generics.params,
2778                    RibKind::Item(
2779                        if self.r.tcx.features().generic_const_items() {
2780                            HasGenericParams::Yes(generics.span)
2781                        } else {
2782                            HasGenericParams::No
2783                        },
2784                        def_kind,
2785                    ),
2786                    LifetimeRibKind::Generics {
2787                        binder: item.id,
2788                        kind: LifetimeBinderKind::ConstItem,
2789                        span: generics.span,
2790                    },
2791                    |this| {
2792                        this.visit_generics(generics);
2793
2794                        this.with_lifetime_rib(
2795                            LifetimeRibKind::Elided(LifetimeRes::Static {
2796                                suppress_elision_warning: true,
2797                            }),
2798                            |this| this.visit_ty(ty),
2799                        );
2800
2801                        if let Some(expr) = expr {
2802                            this.resolve_const_body(
2803                                expr,
2804                                Some((item.ident, ConstantItemKind::Const)),
2805                            );
2806                        }
2807                    },
2808                );
2809            }
2810
2811            ItemKind::Use(ref use_tree) => {
2812                let maybe_exported = match use_tree.kind {
2813                    UseTreeKind::Simple(_) | UseTreeKind::Glob => MaybeExported::Ok(item.id),
2814                    UseTreeKind::Nested { .. } => MaybeExported::NestedUse(&item.vis),
2815                };
2816                self.resolve_doc_links(&item.attrs, maybe_exported);
2817
2818                self.future_proof_import(use_tree);
2819            }
2820
2821            ItemKind::MacroDef(ref macro_def) => {
2822                // Maintain macro_rules scopes in the same way as during early resolution
2823                // for diagnostics and doc links.
2824                if macro_def.macro_rules {
2825                    let def_id = self.r.local_def_id(item.id);
2826                    self.parent_scope.macro_rules = self.r.macro_rules_scopes[&def_id];
2827                }
2828            }
2829
2830            ItemKind::ForeignMod(_) | ItemKind::GlobalAsm(_) => {
2831                visit::walk_item(self, item);
2832            }
2833
2834            ItemKind::Delegation(ref delegation) => {
2835                let span = delegation.path.segments.last().unwrap().ident.span;
2836                self.with_generic_param_rib(
2837                    &[],
2838                    RibKind::Item(HasGenericParams::Yes(span), def_kind),
2839                    LifetimeRibKind::Generics {
2840                        binder: item.id,
2841                        kind: LifetimeBinderKind::Function,
2842                        span,
2843                    },
2844                    |this| this.resolve_delegation(delegation),
2845                );
2846            }
2847
2848            ItemKind::ExternCrate(..) => {}
2849
2850            ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
2851                panic!("unexpanded macro in resolve!")
2852            }
2853        }
2854    }
2855
2856    fn with_generic_param_rib<'c, F>(
2857        &'c mut self,
2858        params: &'c [GenericParam],
2859        kind: RibKind<'ra>,
2860        lifetime_kind: LifetimeRibKind,
2861        f: F,
2862    ) where
2863        F: FnOnce(&mut Self),
2864    {
2865        debug!("with_generic_param_rib");
2866        let LifetimeRibKind::Generics { binder, span: generics_span, kind: generics_kind, .. } =
2867            lifetime_kind
2868        else {
2869            panic!()
2870        };
2871
2872        let mut function_type_rib = Rib::new(kind);
2873        let mut function_value_rib = Rib::new(kind);
2874        let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
2875
2876        // Only check for shadowed bindings if we're declaring new params.
2877        if !params.is_empty() {
2878            let mut seen_bindings = FxHashMap::default();
2879            // Store all seen lifetimes names from outer scopes.
2880            let mut seen_lifetimes = FxHashSet::default();
2881
2882            // We also can't shadow bindings from associated parent items.
2883            for ns in [ValueNS, TypeNS] {
2884                for parent_rib in self.ribs[ns].iter().rev() {
2885                    // Break at mod level, to account for nested items which are
2886                    // allowed to shadow generic param names.
2887                    if matches!(parent_rib.kind, RibKind::Module(..)) {
2888                        break;
2889                    }
2890
2891                    #[allow(rustc::potential_query_instability)] // FIXME
2892                    seen_bindings
2893                        .extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
2894                }
2895            }
2896
2897            // Forbid shadowing lifetime bindings
2898            for rib in self.lifetime_ribs.iter().rev() {
2899                seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| *ident));
2900                if let LifetimeRibKind::Item = rib.kind {
2901                    break;
2902                }
2903            }
2904
2905            for param in params {
2906                let ident = param.ident.normalize_to_macros_2_0();
2907                debug!("with_generic_param_rib: {}", param.id);
2908
2909                if let GenericParamKind::Lifetime = param.kind
2910                    && let Some(&original) = seen_lifetimes.get(&ident)
2911                {
2912                    diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident);
2913                    // Record lifetime res, so lowering knows there is something fishy.
2914                    self.record_lifetime_param(param.id, LifetimeRes::Error);
2915                    continue;
2916                }
2917
2918                match seen_bindings.entry(ident) {
2919                    Entry::Occupied(entry) => {
2920                        let span = *entry.get();
2921                        let err = ResolutionError::NameAlreadyUsedInParameterList(ident, span);
2922                        self.report_error(param.ident.span, err);
2923                        let rib = match param.kind {
2924                            GenericParamKind::Lifetime => {
2925                                // Record lifetime res, so lowering knows there is something fishy.
2926                                self.record_lifetime_param(param.id, LifetimeRes::Error);
2927                                continue;
2928                            }
2929                            GenericParamKind::Type { .. } => &mut function_type_rib,
2930                            GenericParamKind::Const { .. } => &mut function_value_rib,
2931                        };
2932
2933                        // Taint the resolution in case of errors to prevent follow up errors in typeck
2934                        self.r.record_partial_res(param.id, PartialRes::new(Res::Err));
2935                        rib.bindings.insert(ident, Res::Err);
2936                        continue;
2937                    }
2938                    Entry::Vacant(entry) => {
2939                        entry.insert(param.ident.span);
2940                    }
2941                }
2942
2943                if param.ident.name == kw::UnderscoreLifetime {
2944                    self.r
2945                        .dcx()
2946                        .emit_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span });
2947                    // Record lifetime res, so lowering knows there is something fishy.
2948                    self.record_lifetime_param(param.id, LifetimeRes::Error);
2949                    continue;
2950                }
2951
2952                if param.ident.name == kw::StaticLifetime {
2953                    self.r.dcx().emit_err(errors::StaticLifetimeIsReserved {
2954                        span: param.ident.span,
2955                        lifetime: param.ident,
2956                    });
2957                    // Record lifetime res, so lowering knows there is something fishy.
2958                    self.record_lifetime_param(param.id, LifetimeRes::Error);
2959                    continue;
2960                }
2961
2962                let def_id = self.r.local_def_id(param.id);
2963
2964                // Plain insert (no renaming).
2965                let (rib, def_kind) = match param.kind {
2966                    GenericParamKind::Type { .. } => (&mut function_type_rib, DefKind::TyParam),
2967                    GenericParamKind::Const { .. } => {
2968                        (&mut function_value_rib, DefKind::ConstParam)
2969                    }
2970                    GenericParamKind::Lifetime => {
2971                        let res = LifetimeRes::Param { param: def_id, binder };
2972                        self.record_lifetime_param(param.id, res);
2973                        function_lifetime_rib.bindings.insert(ident, (param.id, res));
2974                        continue;
2975                    }
2976                };
2977
2978                let res = match kind {
2979                    RibKind::Item(..) | RibKind::AssocItem => {
2980                        Res::Def(def_kind, def_id.to_def_id())
2981                    }
2982                    RibKind::Normal => {
2983                        // FIXME(non_lifetime_binders): Stop special-casing
2984                        // const params to error out here.
2985                        if self.r.tcx.features().non_lifetime_binders()
2986                            && matches!(param.kind, GenericParamKind::Type { .. })
2987                        {
2988                            Res::Def(def_kind, def_id.to_def_id())
2989                        } else {
2990                            Res::Err
2991                        }
2992                    }
2993                    _ => span_bug!(param.ident.span, "Unexpected rib kind {:?}", kind),
2994                };
2995                self.r.record_partial_res(param.id, PartialRes::new(res));
2996                rib.bindings.insert(ident, res);
2997            }
2998        }
2999
3000        self.lifetime_ribs.push(function_lifetime_rib);
3001        self.ribs[ValueNS].push(function_value_rib);
3002        self.ribs[TypeNS].push(function_type_rib);
3003
3004        f(self);
3005
3006        self.ribs[TypeNS].pop();
3007        self.ribs[ValueNS].pop();
3008        let function_lifetime_rib = self.lifetime_ribs.pop().unwrap();
3009
3010        // Do not account for the parameters we just bound for function lifetime elision.
3011        if let Some(ref mut candidates) = self.lifetime_elision_candidates {
3012            for (_, res) in function_lifetime_rib.bindings.values() {
3013                candidates.retain(|(r, _)| r != res);
3014            }
3015        }
3016
3017        if let LifetimeBinderKind::BareFnType
3018        | LifetimeBinderKind::WhereBound
3019        | LifetimeBinderKind::Function
3020        | LifetimeBinderKind::ImplBlock = generics_kind
3021        {
3022            self.maybe_report_lifetime_uses(generics_span, params)
3023        }
3024    }
3025
3026    fn with_label_rib(&mut self, kind: RibKind<'ra>, f: impl FnOnce(&mut Self)) {
3027        self.label_ribs.push(Rib::new(kind));
3028        f(self);
3029        self.label_ribs.pop();
3030    }
3031
3032    fn with_static_rib(&mut self, def_kind: DefKind, f: impl FnOnce(&mut Self)) {
3033        let kind = RibKind::Item(HasGenericParams::No, def_kind);
3034        self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
3035    }
3036
3037    // HACK(min_const_generics, generic_const_exprs): We
3038    // want to keep allowing `[0; size_of::<*mut T>()]`
3039    // with a future compat lint for now. We do this by adding an
3040    // additional special case for repeat expressions.
3041    //
3042    // Note that we intentionally still forbid `[0; N + 1]` during
3043    // name resolution so that we don't extend the future
3044    // compat lint to new cases.
3045    #[instrument(level = "debug", skip(self, f))]
3046    fn with_constant_rib(
3047        &mut self,
3048        is_repeat: IsRepeatExpr,
3049        may_use_generics: ConstantHasGenerics,
3050        item: Option<(Ident, ConstantItemKind)>,
3051        f: impl FnOnce(&mut Self),
3052    ) {
3053        let f = |this: &mut Self| {
3054            this.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
3055                this.with_rib(
3056                    TypeNS,
3057                    RibKind::ConstantItem(
3058                        may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
3059                        item,
3060                    ),
3061                    |this| {
3062                        this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
3063                    },
3064                )
3065            })
3066        };
3067
3068        if let ConstantHasGenerics::No(cause) = may_use_generics {
3069            self.with_lifetime_rib(LifetimeRibKind::ConcreteAnonConst(cause), f)
3070        } else {
3071            f(self)
3072        }
3073    }
3074
3075    fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
3076        // Handle nested impls (inside fn bodies)
3077        let previous_value =
3078            replace(&mut self.diag_metadata.current_self_type, Some(self_type.clone()));
3079        let result = f(self);
3080        self.diag_metadata.current_self_type = previous_value;
3081        result
3082    }
3083
3084    fn with_current_self_item<T>(&mut self, self_item: &Item, f: impl FnOnce(&mut Self) -> T) -> T {
3085        let previous_value = replace(&mut self.diag_metadata.current_self_item, Some(self_item.id));
3086        let result = f(self);
3087        self.diag_metadata.current_self_item = previous_value;
3088        result
3089    }
3090
3091    /// When evaluating a `trait` use its associated types' idents for suggestions in E0412.
3092    fn resolve_trait_items(&mut self, trait_items: &'ast [P<AssocItem>]) {
3093        let trait_assoc_items =
3094            replace(&mut self.diag_metadata.current_trait_assoc_items, Some(trait_items));
3095
3096        let walk_assoc_item =
3097            |this: &mut Self, generics: &Generics, kind, item: &'ast AssocItem| {
3098                this.with_generic_param_rib(
3099                    &generics.params,
3100                    RibKind::AssocItem,
3101                    LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind },
3102                    |this| visit::walk_assoc_item(this, item, AssocCtxt::Trait),
3103                );
3104            };
3105
3106        for item in trait_items {
3107            self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
3108            match &item.kind {
3109                AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
3110                    self.with_generic_param_rib(
3111                        &generics.params,
3112                        RibKind::AssocItem,
3113                        LifetimeRibKind::Generics {
3114                            binder: item.id,
3115                            span: generics.span,
3116                            kind: LifetimeBinderKind::ConstItem,
3117                        },
3118                        |this| {
3119                            this.with_lifetime_rib(
3120                                LifetimeRibKind::StaticIfNoLifetimeInScope {
3121                                    lint_id: item.id,
3122                                    emit_lint: false,
3123                                },
3124                                |this| {
3125                                    this.visit_generics(generics);
3126                                    this.visit_ty(ty);
3127
3128                                    // Only impose the restrictions of `ConstRibKind` for an
3129                                    // actual constant expression in a provided default.
3130                                    if let Some(expr) = expr {
3131                                        // We allow arbitrary const expressions inside of associated consts,
3132                                        // even if they are potentially not const evaluatable.
3133                                        //
3134                                        // Type parameters can already be used and as associated consts are
3135                                        // not used as part of the type system, this is far less surprising.
3136                                        this.resolve_const_body(expr, None);
3137                                    }
3138                                },
3139                            )
3140                        },
3141                    );
3142                }
3143                AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
3144                    walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
3145
3146                    for (id, path) in define_opaque.iter().flatten() {
3147                        self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
3148                    }
3149                }
3150                AssocItemKind::Delegation(delegation) => {
3151                    self.with_generic_param_rib(
3152                        &[],
3153                        RibKind::AssocItem,
3154                        LifetimeRibKind::Generics {
3155                            binder: item.id,
3156                            kind: LifetimeBinderKind::Function,
3157                            span: delegation.path.segments.last().unwrap().ident.span,
3158                        },
3159                        |this| this.resolve_delegation(delegation),
3160                    );
3161                }
3162                AssocItemKind::Type(box TyAlias { generics, .. }) => self
3163                    .with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
3164                        walk_assoc_item(this, generics, LifetimeBinderKind::Item, item)
3165                    }),
3166                AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => {
3167                    panic!("unexpanded macro in resolve!")
3168                }
3169            };
3170        }
3171
3172        self.diag_metadata.current_trait_assoc_items = trait_assoc_items;
3173    }
3174
3175    /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`).
3176    fn with_optional_trait_ref<T>(
3177        &mut self,
3178        opt_trait_ref: Option<&TraitRef>,
3179        self_type: &'ast Ty,
3180        f: impl FnOnce(&mut Self, Option<DefId>) -> T,
3181    ) -> T {
3182        let mut new_val = None;
3183        let mut new_id = None;
3184        if let Some(trait_ref) = opt_trait_ref {
3185            let path: Vec<_> = Segment::from_path(&trait_ref.path);
3186            self.diag_metadata.currently_processing_impl_trait =
3187                Some((trait_ref.clone(), self_type.clone()));
3188            let res = self.smart_resolve_path_fragment(
3189                &None,
3190                &path,
3191                PathSource::Trait(AliasPossibility::No),
3192                Finalize::new(trait_ref.ref_id, trait_ref.path.span),
3193                RecordPartialRes::Yes,
3194                None,
3195            );
3196            self.diag_metadata.currently_processing_impl_trait = None;
3197            if let Some(def_id) = res.expect_full_res().opt_def_id() {
3198                new_id = Some(def_id);
3199                new_val = Some((self.r.expect_module(def_id), trait_ref.clone()));
3200            }
3201        }
3202        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
3203        let result = f(self, new_id);
3204        self.current_trait_ref = original_trait_ref;
3205        result
3206    }
3207
3208    fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) {
3209        let mut self_type_rib = Rib::new(RibKind::Normal);
3210
3211        // Plain insert (no renaming, since types are not currently hygienic)
3212        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
3213        self.ribs[ns].push(self_type_rib);
3214        f(self);
3215        self.ribs[ns].pop();
3216    }
3217
3218    fn with_self_rib(&mut self, self_res: Res, f: impl FnOnce(&mut Self)) {
3219        self.with_self_rib_ns(TypeNS, self_res, f)
3220    }
3221
3222    fn resolve_implementation(
3223        &mut self,
3224        attrs: &[ast::Attribute],
3225        generics: &'ast Generics,
3226        opt_trait_reference: &'ast Option<TraitRef>,
3227        self_type: &'ast Ty,
3228        item_id: NodeId,
3229        impl_items: &'ast [P<AssocItem>],
3230    ) {
3231        debug!("resolve_implementation");
3232        // If applicable, create a rib for the type parameters.
3233        self.with_generic_param_rib(
3234            &generics.params,
3235            RibKind::Item(HasGenericParams::Yes(generics.span), self.r.local_def_kind(item_id)),
3236            LifetimeRibKind::Generics {
3237                span: generics.span,
3238                binder: item_id,
3239                kind: LifetimeBinderKind::ImplBlock,
3240            },
3241            |this| {
3242                // Dummy self type for better errors if `Self` is used in the trait path.
3243                this.with_self_rib(Res::SelfTyParam { trait_: LOCAL_CRATE.as_def_id() }, |this| {
3244                    this.with_lifetime_rib(
3245                        LifetimeRibKind::AnonymousCreateParameter {
3246                            binder: item_id,
3247                            report_in_path: true
3248                        },
3249                        |this| {
3250                            // Resolve the trait reference, if necessary.
3251                            this.with_optional_trait_ref(
3252                                opt_trait_reference.as_ref(),
3253                                self_type,
3254                                |this, trait_id| {
3255                                    this.resolve_doc_links(attrs, MaybeExported::Impl(trait_id));
3256
3257                                    let item_def_id = this.r.local_def_id(item_id);
3258
3259                                    // Register the trait definitions from here.
3260                                    if let Some(trait_id) = trait_id {
3261                                        this.r
3262                                            .trait_impls
3263                                            .entry(trait_id)
3264                                            .or_default()
3265                                            .push(item_def_id);
3266                                    }
3267
3268                                    let item_def_id = item_def_id.to_def_id();
3269                                    let res = Res::SelfTyAlias {
3270                                        alias_to: item_def_id,
3271                                        forbid_generic: false,
3272                                        is_trait_impl: trait_id.is_some()
3273                                    };
3274                                    this.with_self_rib(res, |this| {
3275                                        if let Some(trait_ref) = opt_trait_reference.as_ref() {
3276                                            // Resolve type arguments in the trait path.
3277                                            visit::walk_trait_ref(this, trait_ref);
3278                                        }
3279                                        // Resolve the self type.
3280                                        this.visit_ty(self_type);
3281                                        // Resolve the generic parameters.
3282                                        this.visit_generics(generics);
3283
3284                                        // Resolve the items within the impl.
3285                                        this.with_current_self_type(self_type, |this| {
3286                                            this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| {
3287                                                debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)");
3288                                                let mut seen_trait_items = Default::default();
3289                                                for item in impl_items {
3290                                                    this.resolve_impl_item(&**item, &mut seen_trait_items, trait_id);
3291                                                }
3292                                            });
3293                                        });
3294                                    });
3295                                },
3296                            )
3297                        },
3298                    );
3299                });
3300            },
3301        );
3302    }
3303
3304    fn resolve_impl_item(
3305        &mut self,
3306        item: &'ast AssocItem,
3307        seen_trait_items: &mut FxHashMap<DefId, Span>,
3308        trait_id: Option<DefId>,
3309    ) {
3310        use crate::ResolutionError::*;
3311        self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
3312        match &item.kind {
3313            AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
3314                debug!("resolve_implementation AssocItemKind::Const");
3315                self.with_generic_param_rib(
3316                    &generics.params,
3317                    RibKind::AssocItem,
3318                    LifetimeRibKind::Generics {
3319                        binder: item.id,
3320                        span: generics.span,
3321                        kind: LifetimeBinderKind::ConstItem,
3322                    },
3323                    |this| {
3324                        this.with_lifetime_rib(
3325                            LifetimeRibKind::StaticIfNoLifetimeInScope {
3326                                lint_id: item.id,
3327                                // In impls, it's not a hard error yet due to backcompat.
3328                                emit_lint: true,
3329                            },
3330                            |this| {
3331                                // If this is a trait impl, ensure the const
3332                                // exists in trait
3333                                this.check_trait_item(
3334                                    item.id,
3335                                    item.ident,
3336                                    &item.kind,
3337                                    ValueNS,
3338                                    item.span,
3339                                    seen_trait_items,
3340                                    |i, s, c| ConstNotMemberOfTrait(i, s, c),
3341                                );
3342
3343                                this.visit_generics(generics);
3344                                this.visit_ty(ty);
3345                                if let Some(expr) = expr {
3346                                    // We allow arbitrary const expressions inside of associated consts,
3347                                    // even if they are potentially not const evaluatable.
3348                                    //
3349                                    // Type parameters can already be used and as associated consts are
3350                                    // not used as part of the type system, this is far less surprising.
3351                                    this.resolve_const_body(expr, None);
3352                                }
3353                            },
3354                        );
3355                    },
3356                );
3357            }
3358            AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
3359                debug!("resolve_implementation AssocItemKind::Fn");
3360                // We also need a new scope for the impl item type parameters.
3361                self.with_generic_param_rib(
3362                    &generics.params,
3363                    RibKind::AssocItem,
3364                    LifetimeRibKind::Generics {
3365                        binder: item.id,
3366                        span: generics.span,
3367                        kind: LifetimeBinderKind::Function,
3368                    },
3369                    |this| {
3370                        // If this is a trait impl, ensure the method
3371                        // exists in trait
3372                        this.check_trait_item(
3373                            item.id,
3374                            item.ident,
3375                            &item.kind,
3376                            ValueNS,
3377                            item.span,
3378                            seen_trait_items,
3379                            |i, s, c| MethodNotMemberOfTrait(i, s, c),
3380                        );
3381
3382                        visit::walk_assoc_item(this, item, AssocCtxt::Impl)
3383                    },
3384                );
3385
3386                for (id, path) in define_opaque.iter().flatten() {
3387                    self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
3388                }
3389            }
3390            AssocItemKind::Type(box TyAlias { generics, .. }) => {
3391                self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
3392                debug!("resolve_implementation AssocItemKind::Type");
3393                // We also need a new scope for the impl item type parameters.
3394                self.with_generic_param_rib(
3395                    &generics.params,
3396                    RibKind::AssocItem,
3397                    LifetimeRibKind::Generics {
3398                        binder: item.id,
3399                        span: generics.span,
3400                        kind: LifetimeBinderKind::Item,
3401                    },
3402                    |this| {
3403                        this.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
3404                            // If this is a trait impl, ensure the type
3405                            // exists in trait
3406                            this.check_trait_item(
3407                                item.id,
3408                                item.ident,
3409                                &item.kind,
3410                                TypeNS,
3411                                item.span,
3412                                seen_trait_items,
3413                                |i, s, c| TypeNotMemberOfTrait(i, s, c),
3414                            );
3415
3416                            visit::walk_assoc_item(this, item, AssocCtxt::Impl)
3417                        });
3418                    },
3419                );
3420                self.diag_metadata.in_non_gat_assoc_type = None;
3421            }
3422            AssocItemKind::Delegation(box delegation) => {
3423                debug!("resolve_implementation AssocItemKind::Delegation");
3424                self.with_generic_param_rib(
3425                    &[],
3426                    RibKind::AssocItem,
3427                    LifetimeRibKind::Generics {
3428                        binder: item.id,
3429                        kind: LifetimeBinderKind::Function,
3430                        span: delegation.path.segments.last().unwrap().ident.span,
3431                    },
3432                    |this| {
3433                        this.check_trait_item(
3434                            item.id,
3435                            item.ident,
3436                            &item.kind,
3437                            ValueNS,
3438                            item.span,
3439                            seen_trait_items,
3440                            |i, s, c| MethodNotMemberOfTrait(i, s, c),
3441                        );
3442
3443                        this.resolve_delegation(delegation)
3444                    },
3445                );
3446            }
3447            AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => {
3448                panic!("unexpanded macro in resolve!")
3449            }
3450        }
3451    }
3452
3453    fn check_trait_item<F>(
3454        &mut self,
3455        id: NodeId,
3456        mut ident: Ident,
3457        kind: &AssocItemKind,
3458        ns: Namespace,
3459        span: Span,
3460        seen_trait_items: &mut FxHashMap<DefId, Span>,
3461        err: F,
3462    ) where
3463        F: FnOnce(Ident, String, Option<Symbol>) -> ResolutionError<'ra>,
3464    {
3465        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
3466        let Some((module, _)) = self.current_trait_ref else {
3467            return;
3468        };
3469        ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
3470        let key = BindingKey::new(ident, ns);
3471        let mut binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding);
3472        debug!(?binding);
3473        if binding.is_none() {
3474            // We could not find the trait item in the correct namespace.
3475            // Check the other namespace to report an error.
3476            let ns = match ns {
3477                ValueNS => TypeNS,
3478                TypeNS => ValueNS,
3479                _ => ns,
3480            };
3481            let key = BindingKey::new(ident, ns);
3482            binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding);
3483            debug!(?binding);
3484        }
3485
3486        let feed_visibility = |this: &mut Self, def_id| {
3487            let vis = this.r.tcx.visibility(def_id);
3488            let vis = if vis.is_visible_locally() {
3489                vis.expect_local()
3490            } else {
3491                this.r.dcx().span_delayed_bug(
3492                    span,
3493                    "error should be emitted when an unexpected trait item is used",
3494                );
3495                rustc_middle::ty::Visibility::Public
3496            };
3497            this.r.feed_visibility(this.r.feed(id), vis);
3498        };
3499
3500        let Some(binding) = binding else {
3501            // We could not find the method: report an error.
3502            let candidate = self.find_similarly_named_assoc_item(ident.name, kind);
3503            let path = &self.current_trait_ref.as_ref().unwrap().1.path;
3504            let path_names = path_names_to_string(path);
3505            self.report_error(span, err(ident, path_names, candidate));
3506            feed_visibility(self, module.def_id());
3507            return;
3508        };
3509
3510        let res = binding.res();
3511        let Res::Def(def_kind, id_in_trait) = res else { bug!() };
3512        feed_visibility(self, id_in_trait);
3513
3514        match seen_trait_items.entry(id_in_trait) {
3515            Entry::Occupied(entry) => {
3516                self.report_error(
3517                    span,
3518                    ResolutionError::TraitImplDuplicate {
3519                        name: ident,
3520                        old_span: *entry.get(),
3521                        trait_item_span: binding.span,
3522                    },
3523                );
3524                return;
3525            }
3526            Entry::Vacant(entry) => {
3527                entry.insert(span);
3528            }
3529        };
3530
3531        match (def_kind, kind) {
3532            (DefKind::AssocTy, AssocItemKind::Type(..))
3533            | (DefKind::AssocFn, AssocItemKind::Fn(..))
3534            | (DefKind::AssocConst, AssocItemKind::Const(..))
3535            | (DefKind::AssocFn, AssocItemKind::Delegation(..)) => {
3536                self.r.record_partial_res(id, PartialRes::new(res));
3537                return;
3538            }
3539            _ => {}
3540        }
3541
3542        // The method kind does not correspond to what appeared in the trait, report.
3543        let path = &self.current_trait_ref.as_ref().unwrap().1.path;
3544        let (code, kind) = match kind {
3545            AssocItemKind::Const(..) => (E0323, "const"),
3546            AssocItemKind::Fn(..) => (E0324, "method"),
3547            AssocItemKind::Type(..) => (E0325, "type"),
3548            AssocItemKind::Delegation(..) => (E0324, "method"),
3549            AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
3550                span_bug!(span, "unexpanded macro")
3551            }
3552        };
3553        let trait_path = path_names_to_string(path);
3554        self.report_error(
3555            span,
3556            ResolutionError::TraitImplMismatch {
3557                name: ident,
3558                kind,
3559                code,
3560                trait_path,
3561                trait_item_span: binding.span,
3562            },
3563        );
3564    }
3565
3566    fn resolve_const_body(&mut self, expr: &'ast Expr, item: Option<(Ident, ConstantItemKind)>) {
3567        self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
3568            this.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, item, |this| {
3569                this.visit_expr(expr)
3570            });
3571        })
3572    }
3573
3574    fn resolve_delegation(&mut self, delegation: &'ast Delegation) {
3575        self.smart_resolve_path(
3576            delegation.id,
3577            &delegation.qself,
3578            &delegation.path,
3579            PathSource::Delegation,
3580        );
3581        if let Some(qself) = &delegation.qself {
3582            self.visit_ty(&qself.ty);
3583        }
3584        self.visit_path(&delegation.path, delegation.id);
3585        let Some(body) = &delegation.body else { return };
3586        self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
3587            // `PatBoundCtx` is not necessary in this context
3588            let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
3589
3590            let span = delegation.path.segments.last().unwrap().ident.span;
3591            this.fresh_binding(
3592                Ident::new(kw::SelfLower, span),
3593                delegation.id,
3594                PatternSource::FnParam,
3595                &mut bindings,
3596            );
3597            this.visit_block(body);
3598        });
3599    }
3600
3601    fn resolve_params(&mut self, params: &'ast [Param]) {
3602        let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
3603        self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
3604            for Param { pat, .. } in params {
3605                this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
3606            }
3607        });
3608        for Param { ty, .. } in params {
3609            self.visit_ty(ty);
3610        }
3611    }
3612
3613    fn resolve_local(&mut self, local: &'ast Local) {
3614        debug!("resolving local ({:?})", local);
3615        // Resolve the type.
3616        visit_opt!(self, visit_ty, &local.ty);
3617
3618        // Resolve the initializer.
3619        if let Some((init, els)) = local.kind.init_else_opt() {
3620            self.visit_expr(init);
3621
3622            // Resolve the `else` block
3623            if let Some(els) = els {
3624                self.visit_block(els);
3625            }
3626        }
3627
3628        // Resolve the pattern.
3629        self.resolve_pattern_top(&local.pat, PatternSource::Let);
3630    }
3631
3632    /// Build a map from pattern identifiers to binding-info's, and check the bindings are
3633    /// consistent when encountering or-patterns and never patterns.
3634    /// This is done hygienically: this could arise for a macro that expands into an or-pattern
3635    /// where one 'x' was from the user and one 'x' came from the macro.
3636    ///
3637    /// A never pattern by definition indicates an unreachable case. For example, matching on
3638    /// `Result<T, &!>` could look like:
3639    /// ```rust
3640    /// # #![feature(never_type)]
3641    /// # #![feature(never_patterns)]
3642    /// # fn bar(_x: u32) {}
3643    /// let foo: Result<u32, &!> = Ok(0);
3644    /// match foo {
3645    ///     Ok(x) => bar(x),
3646    ///     Err(&!),
3647    /// }
3648    /// ```
3649    /// This extends to product types: `(x, !)` is likewise unreachable. So it doesn't make sense to
3650    /// have a binding here, and we tell the user to use `_` instead.
3651    fn compute_and_check_binding_map(
3652        &mut self,
3653        pat: &Pat,
3654    ) -> Result<FxIndexMap<Ident, BindingInfo>, IsNeverPattern> {
3655        let mut binding_map = FxIndexMap::default();
3656        let mut is_never_pat = false;
3657
3658        pat.walk(&mut |pat| {
3659            match pat.kind {
3660                PatKind::Ident(annotation, ident, ref sub_pat)
3661                    if sub_pat.is_some() || self.is_base_res_local(pat.id) =>
3662                {
3663                    binding_map.insert(ident, BindingInfo { span: ident.span, annotation });
3664                }
3665                PatKind::Or(ref ps) => {
3666                    // Check the consistency of this or-pattern and
3667                    // then add all bindings to the larger map.
3668                    match self.compute_and_check_or_pat_binding_map(ps) {
3669                        Ok(bm) => binding_map.extend(bm),
3670                        Err(IsNeverPattern) => is_never_pat = true,
3671                    }
3672                    return false;
3673                }
3674                PatKind::Never => is_never_pat = true,
3675                _ => {}
3676            }
3677
3678            true
3679        });
3680
3681        if is_never_pat {
3682            for (_, binding) in binding_map {
3683                self.report_error(binding.span, ResolutionError::BindingInNeverPattern);
3684            }
3685            Err(IsNeverPattern)
3686        } else {
3687            Ok(binding_map)
3688        }
3689    }
3690
3691    fn is_base_res_local(&self, nid: NodeId) -> bool {
3692        matches!(
3693            self.r.partial_res_map.get(&nid).map(|res| res.expect_full_res()),
3694            Some(Res::Local(..))
3695        )
3696    }
3697
3698    /// Compute the binding map for an or-pattern. Checks that all of the arms in the or-pattern
3699    /// have exactly the same set of bindings, with the same binding modes for each.
3700    /// Returns the computed binding map and a boolean indicating whether the pattern is a never
3701    /// pattern.
3702    ///
3703    /// A never pattern by definition indicates an unreachable case. For example, destructuring a
3704    /// `Result<T, &!>` could look like:
3705    /// ```rust
3706    /// # #![feature(never_type)]
3707    /// # #![feature(never_patterns)]
3708    /// # fn foo() -> Result<bool, &'static !> { Ok(true) }
3709    /// let (Ok(x) | Err(&!)) = foo();
3710    /// # let _ = x;
3711    /// ```
3712    /// Because the `Err(&!)` branch is never reached, it does not need to have the same bindings as
3713    /// the other branches of the or-pattern. So we must ignore never pattern when checking the
3714    /// bindings of an or-pattern.
3715    /// Moreover, if all the subpatterns are never patterns (e.g. `Ok(!) | Err(!)`), then the
3716    /// pattern as a whole counts as a never pattern (since it's definitionallly unreachable).
3717    fn compute_and_check_or_pat_binding_map(
3718        &mut self,
3719        pats: &[P<Pat>],
3720    ) -> Result<FxIndexMap<Ident, BindingInfo>, IsNeverPattern> {
3721        let mut missing_vars = FxIndexMap::default();
3722        let mut inconsistent_vars = FxIndexMap::default();
3723
3724        // 1) Compute the binding maps of all arms; we must ignore never patterns here.
3725        let not_never_pats = pats
3726            .iter()
3727            .filter_map(|pat| {
3728                let binding_map = self.compute_and_check_binding_map(pat).ok()?;
3729                Some((binding_map, pat))
3730            })
3731            .collect::<Vec<_>>();
3732
3733        // 2) Record any missing bindings or binding mode inconsistencies.
3734        for (map_outer, pat_outer) in not_never_pats.iter() {
3735            // Check against all arms except for the same pattern which is always self-consistent.
3736            let inners = not_never_pats
3737                .iter()
3738                .filter(|(_, pat)| pat.id != pat_outer.id)
3739                .flat_map(|(map, _)| map);
3740
3741            for (&name, binding_inner) in inners {
3742                match map_outer.get(&name) {
3743                    None => {
3744                        // The inner binding is missing in the outer.
3745                        let binding_error =
3746                            missing_vars.entry(name).or_insert_with(|| BindingError {
3747                                name,
3748                                origin: BTreeSet::new(),
3749                                target: BTreeSet::new(),
3750                                could_be_path: name.as_str().starts_with(char::is_uppercase),
3751                            });
3752                        binding_error.origin.insert(binding_inner.span);
3753                        binding_error.target.insert(pat_outer.span);
3754                    }
3755                    Some(binding_outer) => {
3756                        if binding_outer.annotation != binding_inner.annotation {
3757                            // The binding modes in the outer and inner bindings differ.
3758                            inconsistent_vars
3759                                .entry(name)
3760                                .or_insert((binding_inner.span, binding_outer.span));
3761                        }
3762                    }
3763                }
3764            }
3765        }
3766
3767        // 3) Report all missing variables we found.
3768        for (name, mut v) in missing_vars {
3769            if inconsistent_vars.contains_key(&name) {
3770                v.could_be_path = false;
3771            }
3772            self.report_error(
3773                *v.origin.iter().next().unwrap(),
3774                ResolutionError::VariableNotBoundInPattern(v, self.parent_scope),
3775            );
3776        }
3777
3778        // 4) Report all inconsistencies in binding modes we found.
3779        for (name, v) in inconsistent_vars {
3780            self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1));
3781        }
3782
3783        // 5) Bubble up the final binding map.
3784        if not_never_pats.is_empty() {
3785            // All the patterns are never patterns, so the whole or-pattern is one too.
3786            Err(IsNeverPattern)
3787        } else {
3788            let mut binding_map = FxIndexMap::default();
3789            for (bm, _) in not_never_pats {
3790                binding_map.extend(bm);
3791            }
3792            Ok(binding_map)
3793        }
3794    }
3795
3796    /// Check the consistency of bindings wrt or-patterns and never patterns.
3797    fn check_consistent_bindings(&mut self, pat: &'ast Pat) {
3798        let mut is_or_or_never = false;
3799        pat.walk(&mut |pat| match pat.kind {
3800            PatKind::Or(..) | PatKind::Never => {
3801                is_or_or_never = true;
3802                false
3803            }
3804            _ => true,
3805        });
3806        if is_or_or_never {
3807            let _ = self.compute_and_check_binding_map(pat);
3808        }
3809    }
3810
3811    fn resolve_arm(&mut self, arm: &'ast Arm) {
3812        self.with_rib(ValueNS, RibKind::Normal, |this| {
3813            this.resolve_pattern_top(&arm.pat, PatternSource::Match);
3814            visit_opt!(this, visit_expr, &arm.guard);
3815            visit_opt!(this, visit_expr, &arm.body);
3816        });
3817    }
3818
3819    /// Arising from `source`, resolve a top level pattern.
3820    fn resolve_pattern_top(&mut self, pat: &'ast Pat, pat_src: PatternSource) {
3821        let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
3822        self.resolve_pattern(pat, pat_src, &mut bindings);
3823    }
3824
3825    fn resolve_pattern(
3826        &mut self,
3827        pat: &'ast Pat,
3828        pat_src: PatternSource,
3829        bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
3830    ) {
3831        // We walk the pattern before declaring the pattern's inner bindings,
3832        // so that we avoid resolving a literal expression to a binding defined
3833        // by the pattern.
3834        visit::walk_pat(self, pat);
3835        self.resolve_pattern_inner(pat, pat_src, bindings);
3836        // This has to happen *after* we determine which pat_idents are variants:
3837        self.check_consistent_bindings(pat);
3838    }
3839
3840    /// Resolve bindings in a pattern. This is a helper to `resolve_pattern`.
3841    ///
3842    /// ### `bindings`
3843    ///
3844    /// A stack of sets of bindings accumulated.
3845    ///
3846    /// In each set, `PatBoundCtx::Product` denotes that a found binding in it should
3847    /// be interpreted as re-binding an already bound binding. This results in an error.
3848    /// Meanwhile, `PatBound::Or` denotes that a found binding in the set should result
3849    /// in reusing this binding rather than creating a fresh one.
3850    ///
3851    /// When called at the top level, the stack must have a single element
3852    /// with `PatBound::Product`. Otherwise, pushing to the stack happens as
3853    /// or-patterns (`p_0 | ... | p_n`) are encountered and the context needs
3854    /// to be switched to `PatBoundCtx::Or` and then `PatBoundCtx::Product` for each `p_i`.
3855    /// When each `p_i` has been dealt with, the top set is merged with its parent.
3856    /// When a whole or-pattern has been dealt with, the thing happens.
3857    ///
3858    /// See the implementation and `fresh_binding` for more details.
3859    #[tracing::instrument(skip(self, bindings), level = "debug")]
3860    fn resolve_pattern_inner(
3861        &mut self,
3862        pat: &Pat,
3863        pat_src: PatternSource,
3864        bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
3865    ) {
3866        // Visit all direct subpatterns of this pattern.
3867        pat.walk(&mut |pat| {
3868            match pat.kind {
3869                PatKind::Ident(bmode, ident, ref sub) => {
3870                    // First try to resolve the identifier as some existing entity,
3871                    // then fall back to a fresh binding.
3872                    let has_sub = sub.is_some();
3873                    let res = self
3874                        .try_resolve_as_non_binding(pat_src, bmode, ident, has_sub)
3875                        .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings));
3876                    self.r.record_partial_res(pat.id, PartialRes::new(res));
3877                    self.r.record_pat_span(pat.id, pat.span);
3878                }
3879                PatKind::TupleStruct(ref qself, ref path, ref sub_patterns) => {
3880                    self.smart_resolve_path(
3881                        pat.id,
3882                        qself,
3883                        path,
3884                        PathSource::TupleStruct(
3885                            pat.span,
3886                            self.r.arenas.alloc_pattern_spans(sub_patterns.iter().map(|p| p.span)),
3887                        ),
3888                    );
3889                }
3890                PatKind::Path(ref qself, ref path) => {
3891                    self.smart_resolve_path(pat.id, qself, path, PathSource::Pat);
3892                }
3893                PatKind::Struct(ref qself, ref path, ref _fields, ref rest) => {
3894                    self.smart_resolve_path(pat.id, qself, path, PathSource::Struct);
3895                    self.record_patterns_with_skipped_bindings(pat, rest);
3896                }
3897                PatKind::Or(ref ps) => {
3898                    // Add a new set of bindings to the stack. `Or` here records that when a
3899                    // binding already exists in this set, it should not result in an error because
3900                    // `V1(a) | V2(a)` must be allowed and are checked for consistency later.
3901                    bindings.push((PatBoundCtx::Or, Default::default()));
3902                    for p in ps {
3903                        // Now we need to switch back to a product context so that each
3904                        // part of the or-pattern internally rejects already bound names.
3905                        // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
3906                        bindings.push((PatBoundCtx::Product, Default::default()));
3907                        self.resolve_pattern_inner(p, pat_src, bindings);
3908                        // Move up the non-overlapping bindings to the or-pattern.
3909                        // Existing bindings just get "merged".
3910                        let collected = bindings.pop().unwrap().1;
3911                        bindings.last_mut().unwrap().1.extend(collected);
3912                    }
3913                    // This or-pattern itself can itself be part of a product,
3914                    // e.g. `(V1(a) | V2(a), a)` or `(a, V1(a) | V2(a))`.
3915                    // Both cases bind `a` again in a product pattern and must be rejected.
3916                    let collected = bindings.pop().unwrap().1;
3917                    bindings.last_mut().unwrap().1.extend(collected);
3918
3919                    // Prevent visiting `ps` as we've already done so above.
3920                    return false;
3921                }
3922                _ => {}
3923            }
3924            true
3925        });
3926    }
3927
3928    fn record_patterns_with_skipped_bindings(&mut self, pat: &Pat, rest: &ast::PatFieldsRest) {
3929        match rest {
3930            ast::PatFieldsRest::Rest | ast::PatFieldsRest::Recovered(_) => {
3931                // Record that the pattern doesn't introduce all the bindings it could.
3932                if let Some(partial_res) = self.r.partial_res_map.get(&pat.id)
3933                    && let Some(res) = partial_res.full_res()
3934                    && let Some(def_id) = res.opt_def_id()
3935                {
3936                    self.ribs[ValueNS]
3937                        .last_mut()
3938                        .unwrap()
3939                        .patterns_with_skipped_bindings
3940                        .entry(def_id)
3941                        .or_default()
3942                        .push((
3943                            pat.span,
3944                            match rest {
3945                                ast::PatFieldsRest::Recovered(guar) => Err(*guar),
3946                                _ => Ok(()),
3947                            },
3948                        ));
3949                }
3950            }
3951            ast::PatFieldsRest::None => {}
3952        }
3953    }
3954
3955    fn fresh_binding(
3956        &mut self,
3957        ident: Ident,
3958        pat_id: NodeId,
3959        pat_src: PatternSource,
3960        bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
3961    ) -> Res {
3962        // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
3963        // (We must not add it if it's in the bindings map because that breaks the assumptions
3964        // later passes make about or-patterns.)
3965        let ident = ident.normalize_to_macro_rules();
3966
3967        let mut bound_iter = bindings.iter().filter(|(_, set)| set.contains(&ident));
3968        // Already bound in a product pattern? e.g. `(a, a)` which is not allowed.
3969        let already_bound_and = bound_iter.clone().any(|(ctx, _)| *ctx == PatBoundCtx::Product);
3970        // Already bound in an or-pattern? e.g. `V1(a) | V2(a)`.
3971        // This is *required* for consistency which is checked later.
3972        let already_bound_or = bound_iter.any(|(ctx, _)| *ctx == PatBoundCtx::Or);
3973
3974        if already_bound_and {
3975            // Overlap in a product pattern somewhere; report an error.
3976            use ResolutionError::*;
3977            let error = match pat_src {
3978                // `fn f(a: u8, a: u8)`:
3979                PatternSource::FnParam => IdentifierBoundMoreThanOnceInParameterList,
3980                // `Variant(a, a)`:
3981                _ => IdentifierBoundMoreThanOnceInSamePattern,
3982            };
3983            self.report_error(ident.span, error(ident));
3984        }
3985
3986        // Record as bound if it's valid:
3987        let ident_valid = ident.name != kw::Empty;
3988        if ident_valid {
3989            bindings.last_mut().unwrap().1.insert(ident);
3990        }
3991
3992        if already_bound_or {
3993            // `Variant1(a) | Variant2(a)`, ok
3994            // Reuse definition from the first `a`.
3995            self.innermost_rib_bindings(ValueNS)[&ident]
3996        } else {
3997            let res = Res::Local(pat_id);
3998            if ident_valid {
3999                // A completely fresh binding add to the set if it's valid.
4000                self.innermost_rib_bindings(ValueNS).insert(ident, res);
4001            }
4002            res
4003        }
4004    }
4005
4006    fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxHashMap<Ident, Res> {
4007        &mut self.ribs[ns].last_mut().unwrap().bindings
4008    }
4009
4010    fn try_resolve_as_non_binding(
4011        &mut self,
4012        pat_src: PatternSource,
4013        ann: BindingMode,
4014        ident: Ident,
4015        has_sub: bool,
4016    ) -> Option<Res> {
4017        // An immutable (no `mut`) by-value (no `ref`) binding pattern without
4018        // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
4019        // also be interpreted as a path to e.g. a constant, variant, etc.
4020        let is_syntactic_ambiguity = !has_sub && ann == BindingMode::NONE;
4021
4022        let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
4023        let (res, binding) = match ls_binding {
4024            LexicalScopeBinding::Item(binding)
4025                if is_syntactic_ambiguity && binding.is_ambiguity_recursive() =>
4026            {
4027                // For ambiguous bindings we don't know all their definitions and cannot check
4028                // whether they can be shadowed by fresh bindings or not, so force an error.
4029                // issues/33118#issuecomment-233962221 (see below) still applies here,
4030                // but we have to ignore it for backward compatibility.
4031                self.r.record_use(ident, binding, Used::Other);
4032                return None;
4033            }
4034            LexicalScopeBinding::Item(binding) => (binding.res(), Some(binding)),
4035            LexicalScopeBinding::Res(res) => (res, None),
4036        };
4037
4038        match res {
4039            Res::SelfCtor(_) // See #70549.
4040            | Res::Def(
4041                DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst | DefKind::ConstParam,
4042                _,
4043            ) if is_syntactic_ambiguity => {
4044                // Disambiguate in favor of a unit struct/variant or constant pattern.
4045                if let Some(binding) = binding {
4046                    self.r.record_use(ident, binding, Used::Other);
4047                }
4048                Some(res)
4049            }
4050            Res::Def(DefKind::Ctor(..) | DefKind::Const | DefKind::AssocConst | DefKind::Static { .. }, _) => {
4051                // This is unambiguously a fresh binding, either syntactically
4052                // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
4053                // to something unusable as a pattern (e.g., constructor function),
4054                // but we still conservatively report an error, see
4055                // issues/33118#issuecomment-233962221 for one reason why.
4056                let binding = binding.expect("no binding for a ctor or static");
4057                self.report_error(
4058                    ident.span,
4059                    ResolutionError::BindingShadowsSomethingUnacceptable {
4060                        shadowing_binding: pat_src,
4061                        name: ident.name,
4062                        participle: if binding.is_import() { "imported" } else { "defined" },
4063                        article: binding.res().article(),
4064                        shadowed_binding: binding.res(),
4065                        shadowed_binding_span: binding.span,
4066                    },
4067                );
4068                None
4069            }
4070            Res::Def(DefKind::ConstParam, def_id) => {
4071                // Same as for DefKind::Const above, but here, `binding` is `None`, so we
4072                // have to construct the error differently
4073                self.report_error(
4074                    ident.span,
4075                    ResolutionError::BindingShadowsSomethingUnacceptable {
4076                        shadowing_binding: pat_src,
4077                        name: ident.name,
4078                        participle: "defined",
4079                        article: res.article(),
4080                        shadowed_binding: res,
4081                        shadowed_binding_span: self.r.def_span(def_id),
4082                    }
4083                );
4084                None
4085            }
4086            Res::Def(DefKind::Fn | DefKind::AssocFn, _) | Res::Local(..) | Res::Err => {
4087                // These entities are explicitly allowed to be shadowed by fresh bindings.
4088                None
4089            }
4090            Res::SelfCtor(_) => {
4091                // We resolve `Self` in pattern position as an ident sometimes during recovery,
4092                // so delay a bug instead of ICEing.
4093                self.r.dcx().span_delayed_bug(
4094                    ident.span,
4095                    "unexpected `SelfCtor` in pattern, expected identifier"
4096                );
4097                None
4098            }
4099            _ => span_bug!(
4100                ident.span,
4101                "unexpected resolution for an identifier in pattern: {:?}",
4102                res,
4103            ),
4104        }
4105    }
4106
4107    // High-level and context dependent path resolution routine.
4108    // Resolves the path and records the resolution into definition map.
4109    // If resolution fails tries several techniques to find likely
4110    // resolution candidates, suggest imports or other help, and report
4111    // errors in user friendly way.
4112    fn smart_resolve_path(
4113        &mut self,
4114        id: NodeId,
4115        qself: &Option<P<QSelf>>,
4116        path: &Path,
4117        source: PathSource<'ast>,
4118    ) {
4119        self.smart_resolve_path_fragment(
4120            qself,
4121            &Segment::from_path(path),
4122            source,
4123            Finalize::new(id, path.span),
4124            RecordPartialRes::Yes,
4125            None,
4126        );
4127    }
4128
4129    #[instrument(level = "debug", skip(self))]
4130    fn smart_resolve_path_fragment(
4131        &mut self,
4132        qself: &Option<P<QSelf>>,
4133        path: &[Segment],
4134        source: PathSource<'ast>,
4135        finalize: Finalize,
4136        record_partial_res: RecordPartialRes,
4137        parent_qself: Option<&QSelf>,
4138    ) -> PartialRes {
4139        let ns = source.namespace();
4140
4141        let Finalize { node_id, path_span, .. } = finalize;
4142        let report_errors = |this: &mut Self, res: Option<Res>| {
4143            if this.should_report_errs() {
4144                let (err, candidates) = this.smart_resolve_report_errors(
4145                    path,
4146                    None,
4147                    path_span,
4148                    source,
4149                    res,
4150                    parent_qself,
4151                );
4152
4153                let def_id = this.parent_scope.module.nearest_parent_mod();
4154                let instead = res.is_some();
4155                let suggestion = if let Some((start, end)) = this.diag_metadata.in_range
4156                    && path[0].ident.span.lo() == end.span.lo()
4157                    && !matches!(start.kind, ExprKind::Lit(_))
4158                {
4159                    let mut sugg = ".";
4160                    let mut span = start.span.between(end.span);
4161                    if span.lo() + BytePos(2) == span.hi() {
4162                        // There's no space between the start, the range op and the end, suggest
4163                        // removal which will look better.
4164                        span = span.with_lo(span.lo() + BytePos(1));
4165                        sugg = "";
4166                    }
4167                    Some((
4168                        span,
4169                        "you might have meant to write `.` instead of `..`",
4170                        sugg.to_string(),
4171                        Applicability::MaybeIncorrect,
4172                    ))
4173                } else if res.is_none()
4174                    && let PathSource::Type
4175                    | PathSource::Expr(_)
4176                    | PathSource::PreciseCapturingArg(..) = source
4177                {
4178                    this.suggest_adding_generic_parameter(path, source)
4179                } else {
4180                    None
4181                };
4182
4183                let ue = UseError {
4184                    err,
4185                    candidates,
4186                    def_id,
4187                    instead,
4188                    suggestion,
4189                    path: path.into(),
4190                    is_call: source.is_call(),
4191                };
4192
4193                this.r.use_injections.push(ue);
4194            }
4195
4196            PartialRes::new(Res::Err)
4197        };
4198
4199        // For paths originating from calls (like in `HashMap::new()`), tries
4200        // to enrich the plain `failed to resolve: ...` message with hints
4201        // about possible missing imports.
4202        //
4203        // Similar thing, for types, happens in `report_errors` above.
4204        let report_errors_for_call =
4205            |this: &mut Self, parent_err: Spanned<ResolutionError<'ra>>| {
4206                // Before we start looking for candidates, we have to get our hands
4207                // on the type user is trying to perform invocation on; basically:
4208                // we're transforming `HashMap::new` into just `HashMap`.
4209                let (following_seg, prefix_path) = match path.split_last() {
4210                    Some((last, path)) if !path.is_empty() => (Some(last), path),
4211                    _ => return Some(parent_err),
4212                };
4213
4214                let (mut err, candidates) = this.smart_resolve_report_errors(
4215                    prefix_path,
4216                    following_seg,
4217                    path_span,
4218                    PathSource::Type,
4219                    None,
4220                    parent_qself,
4221                );
4222
4223                // There are two different error messages user might receive at
4224                // this point:
4225                // - E0412 cannot find type `{}` in this scope
4226                // - E0433 failed to resolve: use of undeclared type or module `{}`
4227                //
4228                // The first one is emitted for paths in type-position, and the
4229                // latter one - for paths in expression-position.
4230                //
4231                // Thus (since we're in expression-position at this point), not to
4232                // confuse the user, we want to keep the *message* from E0433 (so
4233                // `parent_err`), but we want *hints* from E0412 (so `err`).
4234                //
4235                // And that's what happens below - we're just mixing both messages
4236                // into a single one.
4237                let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
4238
4239                // overwrite all properties with the parent's error message
4240                err.messages = take(&mut parent_err.messages);
4241                err.code = take(&mut parent_err.code);
4242                swap(&mut err.span, &mut parent_err.span);
4243                err.children = take(&mut parent_err.children);
4244                err.sort_span = parent_err.sort_span;
4245                err.is_lint = parent_err.is_lint.clone();
4246
4247                // merge the parent_err's suggestions with the typo (err's) suggestions
4248                match &mut err.suggestions {
4249                    Suggestions::Enabled(typo_suggestions) => match &mut parent_err.suggestions {
4250                        Suggestions::Enabled(parent_suggestions) => {
4251                            // If both suggestions are enabled, append parent_err's suggestions to err's suggestions.
4252                            typo_suggestions.append(parent_suggestions)
4253                        }
4254                        Suggestions::Sealed(_) | Suggestions::Disabled => {
4255                            // If the parent's suggestions are either sealed or disabled, it signifies that
4256                            // new suggestions cannot be added or removed from the diagnostic. Therefore,
4257                            // we assign both types of suggestions to err's suggestions and discard the
4258                            // existing suggestions in err.
4259                            err.suggestions = std::mem::take(&mut parent_err.suggestions);
4260                        }
4261                    },
4262                    Suggestions::Sealed(_) | Suggestions::Disabled => (),
4263                }
4264
4265                parent_err.cancel();
4266
4267                let def_id = this.parent_scope.module.nearest_parent_mod();
4268
4269                if this.should_report_errs() {
4270                    if candidates.is_empty() {
4271                        if path.len() == 2
4272                            && let [segment] = prefix_path
4273                        {
4274                            // Delay to check whether methond name is an associated function or not
4275                            // ```
4276                            // let foo = Foo {};
4277                            // foo::bar(); // possibly suggest to foo.bar();
4278                            //```
4279                            err.stash(segment.ident.span, rustc_errors::StashKey::CallAssocMethod);
4280                        } else {
4281                            // When there is no suggested imports, we can just emit the error
4282                            // and suggestions immediately. Note that we bypass the usually error
4283                            // reporting routine (ie via `self.r.report_error`) because we need
4284                            // to post-process the `ResolutionError` above.
4285                            err.emit();
4286                        }
4287                    } else {
4288                        // If there are suggested imports, the error reporting is delayed
4289                        this.r.use_injections.push(UseError {
4290                            err,
4291                            candidates,
4292                            def_id,
4293                            instead: false,
4294                            suggestion: None,
4295                            path: prefix_path.into(),
4296                            is_call: source.is_call(),
4297                        });
4298                    }
4299                } else {
4300                    err.cancel();
4301                }
4302
4303                // We don't return `Some(parent_err)` here, because the error will
4304                // be already printed either immediately or as part of the `use` injections
4305                None
4306            };
4307
4308        let partial_res = match self.resolve_qpath_anywhere(
4309            qself,
4310            path,
4311            ns,
4312            path_span,
4313            source.defer_to_typeck(),
4314            finalize,
4315        ) {
4316            Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => {
4317                // if we also have an associated type that matches the ident, stash a suggestion
4318                if let Some(items) = self.diag_metadata.current_trait_assoc_items
4319                    && let [Segment { ident, .. }] = path
4320                    && items.iter().any(|item| {
4321                        item.ident == *ident && matches!(item.kind, AssocItemKind::Type(_))
4322                    })
4323                {
4324                    let mut diag = self.r.tcx.dcx().struct_allow("");
4325                    diag.span_suggestion_verbose(
4326                        path_span.shrink_to_lo(),
4327                        "there is an associated type with the same name",
4328                        "Self::",
4329                        Applicability::MaybeIncorrect,
4330                    );
4331                    diag.stash(path_span, StashKey::AssociatedTypeSuggestion);
4332                }
4333
4334                if source.is_expected(res) || res == Res::Err {
4335                    partial_res
4336                } else {
4337                    report_errors(self, Some(res))
4338                }
4339            }
4340
4341            Ok(Some(partial_res)) if source.defer_to_typeck() => {
4342                // Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B`
4343                // or `<T>::A::B`. If `B` should be resolved in value namespace then
4344                // it needs to be added to the trait map.
4345                if ns == ValueNS {
4346                    let item_name = path.last().unwrap().ident;
4347                    let traits = self.traits_in_scope(item_name, ns);
4348                    self.r.trait_map.insert(node_id, traits);
4349                }
4350
4351                if PrimTy::from_name(path[0].ident.name).is_some() {
4352                    let mut std_path = Vec::with_capacity(1 + path.len());
4353
4354                    std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std)));
4355                    std_path.extend(path);
4356                    if let PathResult::Module(_) | PathResult::NonModule(_) =
4357                        self.resolve_path(&std_path, Some(ns), None)
4358                    {
4359                        // Check if we wrote `str::from_utf8` instead of `std::str::from_utf8`
4360                        let item_span =
4361                            path.iter().last().map_or(path_span, |segment| segment.ident.span);
4362
4363                        self.r.confused_type_with_std_module.insert(item_span, path_span);
4364                        self.r.confused_type_with_std_module.insert(path_span, path_span);
4365                    }
4366                }
4367
4368                partial_res
4369            }
4370
4371            Err(err) => {
4372                if let Some(err) = report_errors_for_call(self, err) {
4373                    self.report_error(err.span, err.node);
4374                }
4375
4376                PartialRes::new(Res::Err)
4377            }
4378
4379            _ => report_errors(self, None),
4380        };
4381
4382        if record_partial_res == RecordPartialRes::Yes {
4383            // Avoid recording definition of `A::B` in `<T as A>::B::C`.
4384            self.r.record_partial_res(node_id, partial_res);
4385            self.resolve_elided_lifetimes_in_path(partial_res, path, source, path_span);
4386            self.lint_unused_qualifications(path, ns, finalize);
4387        }
4388
4389        partial_res
4390    }
4391
4392    fn self_type_is_available(&mut self) -> bool {
4393        let binding = self
4394            .maybe_resolve_ident_in_lexical_scope(Ident::with_dummy_span(kw::SelfUpper), TypeNS);
4395        if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
4396    }
4397
4398    fn self_value_is_available(&mut self, self_span: Span) -> bool {
4399        let ident = Ident::new(kw::SelfLower, self_span);
4400        let binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS);
4401        if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
4402    }
4403
4404    /// A wrapper around [`Resolver::report_error`].
4405    ///
4406    /// This doesn't emit errors for function bodies if this is rustdoc.
4407    fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'ra>) {
4408        if self.should_report_errs() {
4409            self.r.report_error(span, resolution_error);
4410        }
4411    }
4412
4413    #[inline]
4414    /// If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items or
4415    // an invalid `use foo::*;` was found, which can cause unbounded amounts of "item not found"
4416    // errors. We silence them all.
4417    fn should_report_errs(&self) -> bool {
4418        !(self.r.tcx.sess.opts.actually_rustdoc && self.in_func_body)
4419            && !self.r.glob_error.is_some()
4420    }
4421
4422    // Resolve in alternative namespaces if resolution in the primary namespace fails.
4423    fn resolve_qpath_anywhere(
4424        &mut self,
4425        qself: &Option<P<QSelf>>,
4426        path: &[Segment],
4427        primary_ns: Namespace,
4428        span: Span,
4429        defer_to_typeck: bool,
4430        finalize: Finalize,
4431    ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
4432        let mut fin_res = None;
4433
4434        for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() {
4435            if i == 0 || ns != primary_ns {
4436                match self.resolve_qpath(qself, path, ns, finalize)? {
4437                    Some(partial_res)
4438                        if partial_res.unresolved_segments() == 0 || defer_to_typeck =>
4439                    {
4440                        return Ok(Some(partial_res));
4441                    }
4442                    partial_res => {
4443                        if fin_res.is_none() {
4444                            fin_res = partial_res;
4445                        }
4446                    }
4447                }
4448            }
4449        }
4450
4451        assert!(primary_ns != MacroNS);
4452
4453        if qself.is_none() {
4454            let path_seg = |seg: &Segment| PathSegment::from_ident(seg.ident);
4455            let path = Path { segments: path.iter().map(path_seg).collect(), span, tokens: None };
4456            if let Ok((_, res)) =
4457                self.r.resolve_macro_path(&path, None, &self.parent_scope, false, false, None)
4458            {
4459                return Ok(Some(PartialRes::new(res)));
4460            }
4461        }
4462
4463        Ok(fin_res)
4464    }
4465
4466    /// Handles paths that may refer to associated items.
4467    fn resolve_qpath(
4468        &mut self,
4469        qself: &Option<P<QSelf>>,
4470        path: &[Segment],
4471        ns: Namespace,
4472        finalize: Finalize,
4473    ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
4474        debug!(
4475            "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",
4476            qself, path, ns, finalize,
4477        );
4478
4479        if let Some(qself) = qself {
4480            if qself.position == 0 {
4481                // This is a case like `<T>::B`, where there is no
4482                // trait to resolve. In that case, we leave the `B`
4483                // segment to be resolved by type-check.
4484                return Ok(Some(PartialRes::with_unresolved_segments(
4485                    Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id()),
4486                    path.len(),
4487                )));
4488            }
4489
4490            let num_privacy_errors = self.r.privacy_errors.len();
4491            // Make sure that `A` in `<T as A>::B::C` is a trait.
4492            let trait_res = self.smart_resolve_path_fragment(
4493                &None,
4494                &path[..qself.position],
4495                PathSource::Trait(AliasPossibility::No),
4496                Finalize::new(finalize.node_id, qself.path_span),
4497                RecordPartialRes::No,
4498                Some(&qself),
4499            );
4500
4501            if trait_res.expect_full_res() == Res::Err {
4502                return Ok(Some(trait_res));
4503            }
4504
4505            // Truncate additional privacy errors reported above,
4506            // because they'll be recomputed below.
4507            self.r.privacy_errors.truncate(num_privacy_errors);
4508
4509            // Make sure `A::B` in `<T as A>::B::C` is a trait item.
4510            //
4511            // Currently, `path` names the full item (`A::B::C`, in
4512            // our example). so we extract the prefix of that that is
4513            // the trait (the slice upto and including
4514            // `qself.position`). And then we recursively resolve that,
4515            // but with `qself` set to `None`.
4516            let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
4517            let partial_res = self.smart_resolve_path_fragment(
4518                &None,
4519                &path[..=qself.position],
4520                PathSource::TraitItem(ns),
4521                Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
4522                RecordPartialRes::No,
4523                Some(&qself),
4524            );
4525
4526            // The remaining segments (the `C` in our example) will
4527            // have to be resolved by type-check, since that requires doing
4528            // trait resolution.
4529            return Ok(Some(PartialRes::with_unresolved_segments(
4530                partial_res.base_res(),
4531                partial_res.unresolved_segments() + path.len() - qself.position - 1,
4532            )));
4533        }
4534
4535        let result = match self.resolve_path(path, Some(ns), Some(finalize)) {
4536            PathResult::NonModule(path_res) => path_res,
4537            PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => {
4538                PartialRes::new(module.res().unwrap())
4539            }
4540            // A part of this path references a `mod` that had a parse error. To avoid resolution
4541            // errors for each reference to that module, we don't emit an error for them until the
4542            // `mod` is fixed. this can have a significant cascade effect.
4543            PathResult::Failed { error_implied_by_parse_error: true, .. } => {
4544                PartialRes::new(Res::Err)
4545            }
4546            // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
4547            // don't report an error right away, but try to fallback to a primitive type.
4548            // So, we are still able to successfully resolve something like
4549            //
4550            // use std::u8; // bring module u8 in scope
4551            // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
4552            //     u8::max_value() // OK, resolves to associated function <u8>::max_value,
4553            //                     // not to nonexistent std::u8::max_value
4554            // }
4555            //
4556            // Such behavior is required for backward compatibility.
4557            // The same fallback is used when `a` resolves to nothing.
4558            PathResult::Module(ModuleOrUniformRoot::Module(_)) | PathResult::Failed { .. }
4559                if (ns == TypeNS || path.len() > 1)
4560                    && PrimTy::from_name(path[0].ident.name).is_some() =>
4561            {
4562                let prim = PrimTy::from_name(path[0].ident.name).unwrap();
4563                let tcx = self.r.tcx();
4564
4565                let gate_err_sym_msg = match prim {
4566                    PrimTy::Float(FloatTy::F16) if !tcx.features().f16() => {
4567                        Some((sym::f16, "the type `f16` is unstable"))
4568                    }
4569                    PrimTy::Float(FloatTy::F128) if !tcx.features().f128() => {
4570                        Some((sym::f128, "the type `f128` is unstable"))
4571                    }
4572                    _ => None,
4573                };
4574
4575                if let Some((sym, msg)) = gate_err_sym_msg {
4576                    let span = path[0].ident.span;
4577                    if !span.allows_unstable(sym) {
4578                        feature_err(tcx.sess, sym, span, msg).emit();
4579                    }
4580                };
4581
4582                PartialRes::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1)
4583            }
4584            PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
4585                PartialRes::new(module.res().unwrap())
4586            }
4587            PathResult::Failed {
4588                is_error_from_last_segment: false,
4589                span,
4590                label,
4591                suggestion,
4592                module,
4593                segment_name,
4594                error_implied_by_parse_error: _,
4595            } => {
4596                return Err(respan(
4597                    span,
4598                    ResolutionError::FailedToResolve {
4599                        segment: Some(segment_name),
4600                        label,
4601                        suggestion,
4602                        module,
4603                    },
4604                ));
4605            }
4606            PathResult::Module(..) | PathResult::Failed { .. } => return Ok(None),
4607            PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"),
4608        };
4609
4610        Ok(Some(result))
4611    }
4612
4613    fn with_resolved_label(&mut self, label: Option<Label>, id: NodeId, f: impl FnOnce(&mut Self)) {
4614        if let Some(label) = label {
4615            if label.ident.as_str().as_bytes()[1] != b'_' {
4616                self.diag_metadata.unused_labels.insert(id, label.ident.span);
4617            }
4618
4619            if let Ok((_, orig_span)) = self.resolve_label(label.ident) {
4620                diagnostics::signal_label_shadowing(self.r.tcx.sess, orig_span, label.ident)
4621            }
4622
4623            self.with_label_rib(RibKind::Normal, |this| {
4624                let ident = label.ident.normalize_to_macro_rules();
4625                this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
4626                f(this);
4627            });
4628        } else {
4629            f(self);
4630        }
4631    }
4632
4633    fn resolve_labeled_block(&mut self, label: Option<Label>, id: NodeId, block: &'ast Block) {
4634        self.with_resolved_label(label, id, |this| this.visit_block(block));
4635    }
4636
4637    fn resolve_block(&mut self, block: &'ast Block) {
4638        debug!("(resolving block) entering block");
4639        // Move down in the graph, if there's an anonymous module rooted here.
4640        let orig_module = self.parent_scope.module;
4641        let anonymous_module = self.r.block_map.get(&block.id).cloned(); // clones a reference
4642
4643        let mut num_macro_definition_ribs = 0;
4644        if let Some(anonymous_module) = anonymous_module {
4645            debug!("(resolving block) found anonymous module, moving down");
4646            self.ribs[ValueNS].push(Rib::new(RibKind::Module(anonymous_module)));
4647            self.ribs[TypeNS].push(Rib::new(RibKind::Module(anonymous_module)));
4648            self.parent_scope.module = anonymous_module;
4649        } else {
4650            self.ribs[ValueNS].push(Rib::new(RibKind::Normal));
4651        }
4652
4653        let prev = self.diag_metadata.current_block_could_be_bare_struct_literal.take();
4654        if let (true, [Stmt { kind: StmtKind::Expr(expr), .. }]) =
4655            (block.could_be_bare_literal, &block.stmts[..])
4656            && let ExprKind::Type(..) = expr.kind
4657        {
4658            self.diag_metadata.current_block_could_be_bare_struct_literal = Some(block.span);
4659        }
4660        // Descend into the block.
4661        for stmt in &block.stmts {
4662            if let StmtKind::Item(ref item) = stmt.kind
4663                && let ItemKind::MacroDef(..) = item.kind
4664            {
4665                num_macro_definition_ribs += 1;
4666                let res = self.r.local_def_id(item.id).to_def_id();
4667                self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res)));
4668                self.label_ribs.push(Rib::new(RibKind::MacroDefinition(res)));
4669            }
4670
4671            self.visit_stmt(stmt);
4672        }
4673        self.diag_metadata.current_block_could_be_bare_struct_literal = prev;
4674
4675        // Move back up.
4676        self.parent_scope.module = orig_module;
4677        for _ in 0..num_macro_definition_ribs {
4678            self.ribs[ValueNS].pop();
4679            self.label_ribs.pop();
4680        }
4681        self.last_block_rib = self.ribs[ValueNS].pop();
4682        if anonymous_module.is_some() {
4683            self.ribs[TypeNS].pop();
4684        }
4685        debug!("(resolving block) leaving block");
4686    }
4687
4688    fn resolve_anon_const(&mut self, constant: &'ast AnonConst, anon_const_kind: AnonConstKind) {
4689        debug!(
4690            "resolve_anon_const(constant: {:?}, anon_const_kind: {:?})",
4691            constant, anon_const_kind
4692        );
4693
4694        let is_trivial_const_arg = constant
4695            .value
4696            .is_potential_trivial_const_arg(self.r.tcx.features().min_generic_const_args());
4697        self.resolve_anon_const_manual(is_trivial_const_arg, anon_const_kind, |this| {
4698            this.resolve_expr(&constant.value, None)
4699        })
4700    }
4701
4702    /// There are a few places that we need to resolve an anon const but we did not parse an
4703    /// anon const so cannot provide an `&'ast AnonConst`. Right now this is just unbraced
4704    /// const arguments that were parsed as type arguments, and `legacy_const_generics` which
4705    /// parse as normal function argument expressions. To avoid duplicating the code for resolving
4706    /// an anon const we have this function which lets the caller manually call `resolve_expr` or
4707    /// `smart_resolve_path`.
4708    fn resolve_anon_const_manual(
4709        &mut self,
4710        is_trivial_const_arg: bool,
4711        anon_const_kind: AnonConstKind,
4712        resolve_expr: impl FnOnce(&mut Self),
4713    ) {
4714        let is_repeat_expr = match anon_const_kind {
4715            AnonConstKind::ConstArg(is_repeat_expr) => is_repeat_expr,
4716            _ => IsRepeatExpr::No,
4717        };
4718
4719        let may_use_generics = match anon_const_kind {
4720            AnonConstKind::EnumDiscriminant => {
4721                ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
4722            }
4723            AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes,
4724            AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
4725            AnonConstKind::ConstArg(_) => {
4726                if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg {
4727                    ConstantHasGenerics::Yes
4728                } else {
4729                    ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg)
4730                }
4731            }
4732        };
4733
4734        self.with_constant_rib(is_repeat_expr, may_use_generics, None, |this| {
4735            this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
4736                resolve_expr(this);
4737            });
4738        });
4739    }
4740
4741    fn resolve_expr_field(&mut self, f: &'ast ExprField, e: &'ast Expr) {
4742        self.resolve_expr(&f.expr, Some(e));
4743        self.visit_ident(&f.ident);
4744        walk_list!(self, visit_attribute, f.attrs.iter());
4745    }
4746
4747    fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
4748        // First, record candidate traits for this expression if it could
4749        // result in the invocation of a method call.
4750
4751        self.record_candidate_traits_for_expr_if_necessary(expr);
4752
4753        // Next, resolve the node.
4754        match expr.kind {
4755            ExprKind::Path(ref qself, ref path) => {
4756                self.smart_resolve_path(expr.id, qself, path, PathSource::Expr(parent));
4757                visit::walk_expr(self, expr);
4758            }
4759
4760            ExprKind::Struct(ref se) => {
4761                self.smart_resolve_path(expr.id, &se.qself, &se.path, PathSource::Struct);
4762                // This is the same as `visit::walk_expr(self, expr);`, but we want to pass the
4763                // parent in for accurate suggestions when encountering `Foo { bar }` that should
4764                // have been `Foo { bar: self.bar }`.
4765                if let Some(qself) = &se.qself {
4766                    self.visit_ty(&qself.ty);
4767                }
4768                self.visit_path(&se.path, expr.id);
4769                walk_list!(self, resolve_expr_field, &se.fields, expr);
4770                match &se.rest {
4771                    StructRest::Base(expr) => self.visit_expr(expr),
4772                    StructRest::Rest(_span) => {}
4773                    StructRest::None => {}
4774                }
4775            }
4776
4777            ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
4778                match self.resolve_label(label.ident) {
4779                    Ok((node_id, _)) => {
4780                        // Since this res is a label, it is never read.
4781                        self.r.label_res_map.insert(expr.id, node_id);
4782                        self.diag_metadata.unused_labels.remove(&node_id);
4783                    }
4784                    Err(error) => {
4785                        self.report_error(label.ident.span, error);
4786                    }
4787                }
4788
4789                // visit `break` argument if any
4790                visit::walk_expr(self, expr);
4791            }
4792
4793            ExprKind::Break(None, Some(ref e)) => {
4794                // We use this instead of `visit::walk_expr` to keep the parent expr around for
4795                // better diagnostics.
4796                self.resolve_expr(e, Some(expr));
4797            }
4798
4799            ExprKind::Let(ref pat, ref scrutinee, _, _) => {
4800                self.visit_expr(scrutinee);
4801                self.resolve_pattern_top(pat, PatternSource::Let);
4802            }
4803
4804            ExprKind::If(ref cond, ref then, ref opt_else) => {
4805                self.with_rib(ValueNS, RibKind::Normal, |this| {
4806                    let old = this.diag_metadata.in_if_condition.replace(cond);
4807                    this.visit_expr(cond);
4808                    this.diag_metadata.in_if_condition = old;
4809                    this.visit_block(then);
4810                });
4811                if let Some(expr) = opt_else {
4812                    self.visit_expr(expr);
4813                }
4814            }
4815
4816            ExprKind::Loop(ref block, label, _) => {
4817                self.resolve_labeled_block(label, expr.id, block)
4818            }
4819
4820            ExprKind::While(ref cond, ref block, label) => {
4821                self.with_resolved_label(label, expr.id, |this| {
4822                    this.with_rib(ValueNS, RibKind::Normal, |this| {
4823                        let old = this.diag_metadata.in_if_condition.replace(cond);
4824                        this.visit_expr(cond);
4825                        this.diag_metadata.in_if_condition = old;
4826                        this.visit_block(block);
4827                    })
4828                });
4829            }
4830
4831            ExprKind::ForLoop { ref pat, ref iter, ref body, label, kind: _ } => {
4832                self.visit_expr(iter);
4833                self.with_rib(ValueNS, RibKind::Normal, |this| {
4834                    this.resolve_pattern_top(pat, PatternSource::For);
4835                    this.resolve_labeled_block(label, expr.id, body);
4836                });
4837            }
4838
4839            ExprKind::Block(ref block, label) => self.resolve_labeled_block(label, block.id, block),
4840
4841            // Equivalent to `visit::walk_expr` + passing some context to children.
4842            ExprKind::Field(ref subexpression, _) => {
4843                self.resolve_expr(subexpression, Some(expr));
4844            }
4845            ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, .. }) => {
4846                self.resolve_expr(receiver, Some(expr));
4847                for arg in args {
4848                    self.resolve_expr(arg, None);
4849                }
4850                self.visit_path_segment(seg);
4851            }
4852
4853            ExprKind::Call(ref callee, ref arguments) => {
4854                self.resolve_expr(callee, Some(expr));
4855                let const_args = self.r.legacy_const_generic_args(callee).unwrap_or_default();
4856                for (idx, argument) in arguments.iter().enumerate() {
4857                    // Constant arguments need to be treated as AnonConst since
4858                    // that is how they will be later lowered to HIR.
4859                    if const_args.contains(&idx) {
4860                        let is_trivial_const_arg = argument.is_potential_trivial_const_arg(
4861                            self.r.tcx.features().min_generic_const_args(),
4862                        );
4863                        self.resolve_anon_const_manual(
4864                            is_trivial_const_arg,
4865                            AnonConstKind::ConstArg(IsRepeatExpr::No),
4866                            |this| this.resolve_expr(argument, None),
4867                        );
4868                    } else {
4869                        self.resolve_expr(argument, None);
4870                    }
4871                }
4872            }
4873            ExprKind::Type(ref _type_expr, ref _ty) => {
4874                visit::walk_expr(self, expr);
4875            }
4876            // For closures, RibKind::FnOrCoroutine is added in visit_fn
4877            ExprKind::Closure(box ast::Closure {
4878                binder: ClosureBinder::For { ref generic_params, span },
4879                ..
4880            }) => {
4881                self.with_generic_param_rib(
4882                    generic_params,
4883                    RibKind::Normal,
4884                    LifetimeRibKind::Generics {
4885                        binder: expr.id,
4886                        kind: LifetimeBinderKind::Closure,
4887                        span,
4888                    },
4889                    |this| visit::walk_expr(this, expr),
4890                );
4891            }
4892            ExprKind::Closure(..) => visit::walk_expr(self, expr),
4893            ExprKind::Gen(..) => {
4894                self.with_label_rib(RibKind::FnOrCoroutine, |this| visit::walk_expr(this, expr));
4895            }
4896            ExprKind::Repeat(ref elem, ref ct) => {
4897                self.visit_expr(elem);
4898                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
4899            }
4900            ExprKind::ConstBlock(ref ct) => {
4901                self.resolve_anon_const(ct, AnonConstKind::InlineConst);
4902            }
4903            ExprKind::Index(ref elem, ref idx, _) => {
4904                self.resolve_expr(elem, Some(expr));
4905                self.visit_expr(idx);
4906            }
4907            ExprKind::Assign(ref lhs, ref rhs, _) => {
4908                if !self.diag_metadata.is_assign_rhs {
4909                    self.diag_metadata.in_assignment = Some(expr);
4910                }
4911                self.visit_expr(lhs);
4912                self.diag_metadata.is_assign_rhs = true;
4913                self.diag_metadata.in_assignment = None;
4914                self.visit_expr(rhs);
4915                self.diag_metadata.is_assign_rhs = false;
4916            }
4917            ExprKind::Range(Some(ref start), Some(ref end), RangeLimits::HalfOpen) => {
4918                self.diag_metadata.in_range = Some((start, end));
4919                self.resolve_expr(start, Some(expr));
4920                self.resolve_expr(end, Some(expr));
4921                self.diag_metadata.in_range = None;
4922            }
4923            _ => {
4924                visit::walk_expr(self, expr);
4925            }
4926        }
4927    }
4928
4929    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &'ast Expr) {
4930        match expr.kind {
4931            ExprKind::Field(_, ident) => {
4932                // #6890: Even though you can't treat a method like a field,
4933                // we need to add any trait methods we find that match the
4934                // field name so that we can do some nice error reporting
4935                // later on in typeck.
4936                let traits = self.traits_in_scope(ident, ValueNS);
4937                self.r.trait_map.insert(expr.id, traits);
4938            }
4939            ExprKind::MethodCall(ref call) => {
4940                debug!("(recording candidate traits for expr) recording traits for {}", expr.id);
4941                let traits = self.traits_in_scope(call.seg.ident, ValueNS);
4942                self.r.trait_map.insert(expr.id, traits);
4943            }
4944            _ => {
4945                // Nothing to do.
4946            }
4947        }
4948    }
4949
4950    fn traits_in_scope(&mut self, ident: Ident, ns: Namespace) -> Vec<TraitCandidate> {
4951        self.r.traits_in_scope(
4952            self.current_trait_ref.as_ref().map(|(module, _)| *module),
4953            &self.parent_scope,
4954            ident.span.ctxt(),
4955            Some((ident.name, ns)),
4956        )
4957    }
4958
4959    fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option<Res> {
4960        // FIXME: This caching may be incorrect in case of multiple `macro_rules`
4961        // items with the same name in the same module.
4962        // Also hygiene is not considered.
4963        let mut doc_link_resolutions = std::mem::take(&mut self.r.doc_link_resolutions);
4964        let res = *doc_link_resolutions
4965            .entry(self.parent_scope.module.nearest_parent_mod().expect_local())
4966            .or_default()
4967            .entry((Symbol::intern(path_str), ns))
4968            .or_insert_with_key(|(path, ns)| {
4969                let res = self.r.resolve_rustdoc_path(path.as_str(), *ns, self.parent_scope);
4970                if let Some(res) = res
4971                    && let Some(def_id) = res.opt_def_id()
4972                    && self.is_invalid_proc_macro_item_for_doc(def_id)
4973                {
4974                    // Encoding def ids in proc macro crate metadata will ICE,
4975                    // because it will only store proc macros for it.
4976                    return None;
4977                }
4978                res
4979            });
4980        self.r.doc_link_resolutions = doc_link_resolutions;
4981        res
4982    }
4983
4984    fn is_invalid_proc_macro_item_for_doc(&self, did: DefId) -> bool {
4985        if !matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata)
4986            || !self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
4987        {
4988            return false;
4989        }
4990        let Some(local_did) = did.as_local() else { return true };
4991        let Some(node_id) = self.r.def_id_to_node_id.get(local_did) else { return true };
4992        !self.r.proc_macros.contains(node_id)
4993    }
4994
4995    fn resolve_doc_links(&mut self, attrs: &[Attribute], maybe_exported: MaybeExported<'_>) {
4996        match self.r.tcx.sess.opts.resolve_doc_links {
4997            ResolveDocLinks::None => return,
4998            ResolveDocLinks::ExportedMetadata
4999                if !self.r.tcx.crate_types().iter().copied().any(CrateType::has_metadata)
5000                    || !maybe_exported.eval(self.r) =>
5001            {
5002                return;
5003            }
5004            ResolveDocLinks::Exported
5005                if !maybe_exported.eval(self.r)
5006                    && !rustdoc::has_primitive_or_keyword_docs(attrs) =>
5007            {
5008                return;
5009            }
5010            ResolveDocLinks::ExportedMetadata
5011            | ResolveDocLinks::Exported
5012            | ResolveDocLinks::All => {}
5013        }
5014
5015        if !attrs.iter().any(|attr| attr.may_have_doc_links()) {
5016            return;
5017        }
5018
5019        let mut need_traits_in_scope = false;
5020        for path_str in rustdoc::attrs_to_preprocessed_links(attrs) {
5021            // Resolve all namespaces due to no disambiguator or for diagnostics.
5022            let mut any_resolved = false;
5023            let mut need_assoc = false;
5024            for ns in [TypeNS, ValueNS, MacroNS] {
5025                if let Some(res) = self.resolve_and_cache_rustdoc_path(&path_str, ns) {
5026                    // Rustdoc ignores tool attribute resolutions and attempts
5027                    // to resolve their prefixes for diagnostics.
5028                    any_resolved = !matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Tool));
5029                } else if ns != MacroNS {
5030                    need_assoc = true;
5031                }
5032            }
5033
5034            // Resolve all prefixes for type-relative resolution or for diagnostics.
5035            if need_assoc || !any_resolved {
5036                let mut path = &path_str[..];
5037                while let Some(idx) = path.rfind("::") {
5038                    path = &path[..idx];
5039                    need_traits_in_scope = true;
5040                    for ns in [TypeNS, ValueNS, MacroNS] {
5041                        self.resolve_and_cache_rustdoc_path(path, ns);
5042                    }
5043                }
5044            }
5045        }
5046
5047        if need_traits_in_scope {
5048            // FIXME: hygiene is not considered.
5049            let mut doc_link_traits_in_scope = std::mem::take(&mut self.r.doc_link_traits_in_scope);
5050            doc_link_traits_in_scope
5051                .entry(self.parent_scope.module.nearest_parent_mod().expect_local())
5052                .or_insert_with(|| {
5053                    self.r
5054                        .traits_in_scope(None, &self.parent_scope, SyntaxContext::root(), None)
5055                        .into_iter()
5056                        .filter_map(|tr| {
5057                            if self.is_invalid_proc_macro_item_for_doc(tr.def_id) {
5058                                // Encoding def ids in proc macro crate metadata will ICE.
5059                                // because it will only store proc macros for it.
5060                                return None;
5061                            }
5062                            Some(tr.def_id)
5063                        })
5064                        .collect()
5065                });
5066            self.r.doc_link_traits_in_scope = doc_link_traits_in_scope;
5067        }
5068    }
5069
5070    fn lint_unused_qualifications(&mut self, path: &[Segment], ns: Namespace, finalize: Finalize) {
5071        // Don't lint on global paths because the user explicitly wrote out the full path.
5072        if let Some(seg) = path.first()
5073            && seg.ident.name == kw::PathRoot
5074        {
5075            return;
5076        }
5077
5078        if finalize.path_span.from_expansion()
5079            || path.iter().any(|seg| seg.ident.span.from_expansion())
5080        {
5081            return;
5082        }
5083
5084        let end_pos =
5085            path.iter().position(|seg| seg.has_generic_args).map_or(path.len(), |pos| pos + 1);
5086        let unqualified = path[..end_pos].iter().enumerate().skip(1).rev().find_map(|(i, seg)| {
5087            // Preserve the current namespace for the final path segment, but use the type
5088            // namespace for all preceding segments
5089            //
5090            // e.g. for `std::env::args` check the `ValueNS` for `args` but the `TypeNS` for
5091            // `std` and `env`
5092            //
5093            // If the final path segment is beyond `end_pos` all the segments to check will
5094            // use the type namespace
5095            let ns = if i + 1 == path.len() { ns } else { TypeNS };
5096            let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?;
5097            let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?;
5098            (res == binding.res()).then_some((seg, binding))
5099        });
5100
5101        if let Some((seg, binding)) = unqualified {
5102            self.r.potentially_unnecessary_qualifications.push(UnnecessaryQualification {
5103                binding,
5104                node_id: finalize.node_id,
5105                path_span: finalize.path_span,
5106                removal_span: path[0].ident.span.until(seg.ident.span),
5107            });
5108        }
5109    }
5110}
5111
5112/// Walks the whole crate in DFS order, visiting each item, counting the declared number of
5113/// lifetime generic parameters and function parameters.
5114struct ItemInfoCollector<'a, 'ra, 'tcx> {
5115    r: &'a mut Resolver<'ra, 'tcx>,
5116}
5117
5118impl ItemInfoCollector<'_, '_, '_> {
5119    fn collect_fn_info(
5120        &mut self,
5121        header: FnHeader,
5122        decl: &FnDecl,
5123        id: NodeId,
5124        attrs: &[Attribute],
5125    ) {
5126        let sig = DelegationFnSig {
5127            header,
5128            param_count: decl.inputs.len(),
5129            has_self: decl.has_self(),
5130            c_variadic: decl.c_variadic(),
5131            target_feature: attrs.iter().any(|attr| attr.has_name(sym::target_feature)),
5132        };
5133        self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig);
5134    }
5135}
5136
5137impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
5138    fn visit_item(&mut self, item: &'ast Item) {
5139        match &item.kind {
5140            ItemKind::TyAlias(box TyAlias { generics, .. })
5141            | ItemKind::Const(box ConstItem { generics, .. })
5142            | ItemKind::Fn(box Fn { generics, .. })
5143            | ItemKind::Enum(_, generics)
5144            | ItemKind::Struct(_, generics)
5145            | ItemKind::Union(_, generics)
5146            | ItemKind::Impl(box Impl { generics, .. })
5147            | ItemKind::Trait(box Trait { generics, .. })
5148            | ItemKind::TraitAlias(generics, _) => {
5149                if let ItemKind::Fn(box Fn { sig, .. }) = &item.kind {
5150                    self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs);
5151                }
5152
5153                let def_id = self.r.local_def_id(item.id);
5154                let count = generics
5155                    .params
5156                    .iter()
5157                    .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime { .. }))
5158                    .count();
5159                self.r.item_generics_num_lifetimes.insert(def_id, count);
5160            }
5161
5162            ItemKind::ForeignMod(ForeignMod { extern_span, safety: _, abi, items }) => {
5163                for foreign_item in items {
5164                    if let ForeignItemKind::Fn(box Fn { sig, .. }) = &foreign_item.kind {
5165                        let new_header =
5166                            FnHeader { ext: Extern::from_abi(*abi, *extern_span), ..sig.header };
5167                        self.collect_fn_info(new_header, &sig.decl, foreign_item.id, &item.attrs);
5168                    }
5169                }
5170            }
5171
5172            ItemKind::Mod(..)
5173            | ItemKind::Static(..)
5174            | ItemKind::Use(..)
5175            | ItemKind::ExternCrate(..)
5176            | ItemKind::MacroDef(..)
5177            | ItemKind::GlobalAsm(..)
5178            | ItemKind::MacCall(..)
5179            | ItemKind::DelegationMac(..) => {}
5180            ItemKind::Delegation(..) => {
5181                // Delegated functions have lifetimes, their count is not necessarily zero.
5182                // But skipping the delegation items here doesn't mean that the count will be considered zero,
5183                // it means there will be a panic when retrieving the count,
5184                // but for delegation items we are never actually retrieving that count in practice.
5185            }
5186        }
5187        visit::walk_item(self, item)
5188    }
5189
5190    fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: AssocCtxt) {
5191        if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
5192            self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs);
5193        }
5194        visit::walk_assoc_item(self, item, ctxt);
5195    }
5196}
5197
5198impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
5199    pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
5200        visit::walk_crate(&mut ItemInfoCollector { r: self }, krate);
5201        let mut late_resolution_visitor = LateResolutionVisitor::new(self);
5202        late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
5203        visit::walk_crate(&mut late_resolution_visitor, krate);
5204        #[allow(rustc::potential_query_instability)] // FIXME
5205        for (id, span) in late_resolution_visitor.diag_metadata.unused_labels.iter() {
5206            self.lint_buffer.buffer_lint(
5207                lint::builtin::UNUSED_LABELS,
5208                *id,
5209                *span,
5210                BuiltinLintDiag::UnusedLabel,
5211            );
5212        }
5213    }
5214}
5215
5216/// Check if definition matches a path
5217fn def_id_matches_path(tcx: TyCtxt<'_>, mut def_id: DefId, expected_path: &[&str]) -> bool {
5218    let mut path = expected_path.iter().rev();
5219    while let (Some(parent), Some(next_step)) = (tcx.opt_parent(def_id), path.next()) {
5220        if !tcx.opt_item_name(def_id).is_some_and(|n| n.as_str() == *next_step) {
5221            return false;
5222        }
5223        def_id = parent;
5224    }
5225    true
5226}