compiler/rustc_resolve/src/late.rs RUST 5,692 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 5,692.
1// ignore-tidy-file-filelength2//! "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`.89use std::borrow::Cow;10use std::collections::hash_map::Entry;11use std::debug_assert_matches;12use std::mem::{replace, swap, take};13use std::ops::{ControlFlow, Range};1415use rustc_ast::visit::{16    AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, try_visit, visit_opt, walk_list,17};18use rustc_ast::*;19use rustc_data_structures::either::Either;20use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};21use rustc_data_structures::unord::{UnordMap, UnordSet};22use rustc_errors::codes::*;23use rustc_errors::{24    Applicability, Diag, DiagArgValue, Diagnostic, ErrorGuaranteed, IntoDiagArg, MultiSpan,25    StashKey, Suggestions, elided_lifetime_in_path_suggestion, pluralize,26};27use rustc_hir::def::Namespace::{self, *};28use rustc_hir::def::{CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};29use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId};30use rustc_hir::{MissingLifetimeKind, PrimTy};31use rustc_lint_defs::builtin::{ELIDED_LIFETIMES_IN_PATHS, UNUSED_LABELS};32use rustc_middle::middle::resolve_bound_vars::Set1;33use rustc_middle::ty::{AssocTag, DelegationInfo, Visibility};34use rustc_middle::{bug, span_bug};35use rustc_session::config::ResolveDocLinks;36use rustc_session::diagnostics::feature_err;37use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Spanned, Symbol, kw, respan, sym};38use rustc_structures::CrateType;39use smallvec::{SmallVec, smallvec};40use thin_vec::ThinVec;41use tracing::{debug, instrument, trace};4243use crate::{44    BindingError, BindingKey, Decl, DelegationFnSig, Finalize, IdentKey, LateDecl, LocalModule,45    Module, ModuleOrUniformRoot, ParentScope, PathResult, Res, ResolutionError, Resolver, Segment,46    Stage, TyCtxt, UseError, Used, path_names_to_string, rustdoc, with_owner,47};4849mod diagnostics;5051use diagnostics::{ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime};5253#[derive(Copy, Clone, Debug)]54struct BindingInfo {55    span: Span,56    annotation: BindingMode,57}5859#[derive(Copy, Clone, PartialEq, Eq, Debug)]60pub(crate) enum PatternSource {61    Match,62    Let,63    For,64    FnParam,65}6667#[derive(Copy, Clone, Debug, PartialEq, Eq)]68enum IsRepeatExpr {69    No,70    Yes,71}7273struct IsNeverPattern;7475/// Describes whether an `AnonConst` is a type level const arg or76/// 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}8485impl 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}9596impl IntoDiagArg for PatternSource {97    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {98        DiagArgValue::Str(Cow::Borrowed(self.descr()))99    }100}101102/// 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}112113/// Tracks bindings resolved within a pattern. This serves two purposes:114///115/// - This tracks when identifiers are bound multiple times within a pattern. In a product context,116///   this is an error. In an or-pattern, this lets us reuse the same resolution for each instance.117///   See `fresh_binding` and `resolve_pattern_inner` for more information.118///119/// - The guard expression of a guard pattern may use bindings from within the guard pattern, but120///   not from elsewhere in the pattern containing it. This allows us to isolate the bindings in the121///   subpattern to construct the scope for the guard.122///123/// Each identifier must map to at most one distinct [`Res`].124type PatternBindings = SmallVec<[(PatBoundCtx, FxIndexMap<Ident, Res>); 1]>;125126/// Does this the item (from the item rib scope) allow generic parameters?127#[derive(Copy, Clone, Debug)]128pub(crate) enum HasGenericParams {129    Yes(Span),130    No,131}132133/// May this constant have generics?134#[derive(Copy, Clone, Debug, Eq, PartialEq)]135pub(crate) enum ConstantHasGenerics {136    Yes,137    No(NoConstantGenericsReason),138}139140impl ConstantHasGenerics {141    fn force_yes_if(self, b: bool) -> Self {142        if b { Self::Yes } else { self }143    }144}145146/// Reason for why an anon const is not allowed to reference generic parameters147#[derive(Copy, Clone, Debug, Eq, PartialEq)]148pub(crate) enum NoConstantGenericsReason {149    /// Const arguments are only allowed to use generic parameters when:150    /// - `feature(generic_const_exprs)` is enabled151    /// or152    /// - the const argument is a sole const generic parameter, i.e. `foo::<{ N }>()`153    ///154    /// If neither of the above are true then this is used as the cause.155    NonTrivialConstArg,156    /// Enum discriminants are not allowed to reference generic parameters ever, this157    /// is used when an anon const is in the following position:158    ///159    /// ```rust,compile_fail160    /// enum Foo<const N: isize> {161    ///     Variant = { N }, // this anon const is not allowed to use generics162    /// }163    /// ```164    IsEnumDiscriminant,165}166167#[derive(Copy, Clone, Debug, Eq, PartialEq)]168pub(crate) enum ConstantItemKind {169    Const,170    Static,171}172173impl ConstantItemKind {174    pub(crate) fn as_str(&self) -> &'static str {175        match self {176            Self::Const => "const",177            Self::Static => "static",178        }179    }180}181182#[derive(Debug, Copy, Clone, PartialEq, Eq)]183enum RecordPartialRes {184    Yes,185    No,186}187188/// The rib kind restricts certain accesses,189/// e.g. to a `Res::Local` of an outer item.190#[derive(Copy, Clone, Debug)]191pub(crate) enum RibKind<'ra> {192    /// No restriction needs to be applied.193    Normal,194195    /// We passed through an `ast::Block`.196    /// Behaves like `Normal`, but also partially like `Module` if the block contains items.197    /// `Block(None)` must be always processed in the same way as `Block(Some(module))`198    /// with empty `module`. The module can be `None` only because creation of some definitely199    /// empty modules is skipped as an optimization.200    Block(Option<LocalModule<'ra>>),201202    /// We passed through an impl or trait and are now in one of its203    /// methods or associated types. Allow references to ty params that impl or trait204    /// binds. Disallow any other upvars (including other ty params that are205    /// upvars).206    AssocItem,207208    /// We passed through a function, closure or coroutine signature. Disallow labels.209    FnOrCoroutine,210211    /// We passed through an item scope. Disallow upvars.212    Item(HasGenericParams, DefKind),213214    /// We're in a constant item. Can't refer to dynamic stuff.215    ///216    /// The item may reference generic parameters in trivial constant expressions.217    /// All other constants aren't allowed to use generic params at all.218    ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),219220    /// We passed through a module item.221    Module(LocalModule<'ra>),222223    /// We passed through a `macro_rules!` statement224    MacroDefinition(DefId),225226    /// All bindings in this rib are generic parameters that can't be used227    /// from the default of a generic parameter because they're not declared228    /// before said generic parameter. Also see the `visit_generics` override.229    ForwardGenericParamBan(ForwardGenericParamBanReason),230231    /// We are inside of the type of a const parameter. Can't refer to any232    /// parameters.233    ConstParamTy,234235    /// We are inside a `sym` inline assembly operand. Can only refer to236    /// globals.237    InlineAsmSym,238}239240#[derive(Copy, Clone, PartialEq, Eq, Debug)]241pub(crate) enum ForwardGenericParamBanReason {242    Default,243    ConstParamTy,244}245246impl RibKind<'_> {247    /// Whether this rib kind contains generic parameters, as opposed to local248    /// variables.249    pub(crate) fn contains_params(&self) -> bool {250        match self {251            RibKind::Normal252            | RibKind::Block(..)253            | RibKind::FnOrCoroutine254            | RibKind::ConstantItem(..)255            | RibKind::Module(_)256            | RibKind::MacroDefinition(_)257            | RibKind::InlineAsmSym => false,258            RibKind::ConstParamTy259            | RibKind::AssocItem260            | RibKind::Item(..)261            | RibKind::ForwardGenericParamBan(_) => true,262        }263    }264265    /// This rib forbids referring to labels defined in upwards ribs.266    fn is_label_barrier(self) -> bool {267        match self {268            RibKind::Normal | RibKind::MacroDefinition(..) => false,269            RibKind::FnOrCoroutine | RibKind::ConstantItem(..) => true,270            kind => bug!("unexpected rib kind: {kind:?}"),271        }272    }273}274275/// A single local scope.276///277/// A rib represents a scope names can live in. Note that these appear in many places, not just278/// around braces. At any place where the list of accessible names (of the given namespace)279/// changes or a new restrictions on the name accessibility are introduced, a new rib is put onto a280/// stack. This may be, for example, a `let` statement (because it introduces variables), a macro,281/// etc.282///283/// Different [rib kinds](enum@RibKind) are transparent for different names.284///285/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When286/// resolving, the name is looked up from inside out.287#[derive(Debug)]288pub(crate) struct Rib<'ra, R = Res> {289    pub bindings: FxIndexMap<Ident, R>,290    pub patterns_with_skipped_bindings: UnordMap<DefId, Vec<(Span, Result<(), ErrorGuaranteed>)>>,291    pub kind: RibKind<'ra>,292}293294impl<'ra, R> Rib<'ra, R> {295    fn new(kind: RibKind<'ra>) -> Rib<'ra, R> {296        Rib {297            bindings: Default::default(),298            patterns_with_skipped_bindings: Default::default(),299            kind,300        }301    }302}303304#[derive(Clone, Copy, Debug)]305enum LifetimeUseSet {306    One { use_span: Span, use_ctxt: visit::LifetimeCtxt },307    Many,308}309310#[derive(Copy, Clone, Debug)]311enum LifetimeRibKind {312    // -- Ribs introducing named lifetimes313    //314    /// This rib declares generic parameters.315    /// Only for this kind the `LifetimeRib::bindings` field can be non-empty.316    Generics { binder: NodeId, span: Span, kind: LifetimeBinderKind },317318    // -- Ribs introducing unnamed lifetimes319    //320    /// Create a new anonymous lifetime parameter and reference it.321    ///322    /// If `report_in_path`, report an error when encountering lifetime elision in a path:323    /// ```compile_fail324    /// struct Foo<'a> { x: &'a () }325    /// async fn foo(x: Foo) {}326    /// ```327    ///328    /// Note: the error should not trigger when the elided lifetime is in a pattern or329    /// expression-position path:330    /// ```331    /// struct Foo<'a> { x: &'a () }332    /// async fn foo(Foo { x: _ }: Foo<'_>) {}333    /// ```334    AnonymousCreateParameter { binder: NodeId, report_in_path: bool },335336    /// Replace all anonymous lifetimes by provided lifetime.337    Elided {338        res: LifetimeRes,339        /// Always report those lifetimes as an error if in a path340        error_in_path: bool,341    },342343    // -- Barrier ribs that stop lifetime lookup, or continue it but produce an error later.344    //345    /// Give a hard error when either `&` or `'_` is written. Used to346    /// rule out things like `where T: Foo<'_>`. Does not imply an347    /// error on default object bounds (e.g., `Box<dyn Foo>`).348    AnonymousReportError,349350    /// Signal we cannot find which should be the anonymous lifetime.351    ElisionFailure,352353    /// This rib forbids usage of generic parameters inside of const parameter types.354    ///355    /// While this is desirable to support eventually, it is difficult to do and so is356    /// currently forbidden. See rust-lang/project-const-generics#28 for more info.357    ConstParamTy,358359    /// Usage of generic parameters is forbidden in various positions for anon consts:360    /// - const arguments when `generic_const_exprs` is not enabled361    /// - enum discriminant values362    ///363    /// This rib emits an error when a lifetime would resolve to a lifetime parameter.364    ConcreteAnonConst(NoConstantGenericsReason),365366    /// This rib acts as a barrier to forbid reference to lifetimes of a parent item.367    Item,368369    /// Lifetimes cannot be elided in `impl Trait` types without `#![feature(anonymous_lifetime_in_impl_trait)]`.370    ImplTrait,371}372impl LifetimeRibKind {373    /// Convenience function for creating non-erroring `Elided` variants.374    fn elided(res: LifetimeRes) -> LifetimeRibKind {375        LifetimeRibKind::Elided { res, error_in_path: false }376    }377}378379#[derive(Copy, Clone, Debug)]380enum LifetimeBinderKind {381    FnPtrType,382    PolyTrait,383    WhereBound,384    // Item covers foreign items, ADTs, type aliases, trait associated items and385    // trait alias associated items.386    Item,387    ConstItem,388    Function,389    Closure,390    ImplBlock,391    // Covers only `impl` associated types.392    ImplAssocType,393}394395impl LifetimeBinderKind {396    fn descr(self) -> &'static str {397        use LifetimeBinderKind::*;398        match self {399            FnPtrType => "type",400            PolyTrait => "bound",401            WhereBound => "bound",402            Item | ConstItem => "item",403            ImplAssocType => "associated type",404            ImplBlock => "impl block",405            Function => "function",406            Closure => "closure",407        }408    }409}410411#[derive(Debug)]412struct LifetimeRib {413    kind: LifetimeRibKind,414    // We need to preserve insertion order for async fns.415    bindings: FxIndexMap<Ident, (NodeId, LifetimeRes)>,416}417418impl LifetimeRib {419    fn new(kind: LifetimeRibKind) -> LifetimeRib {420        LifetimeRib { bindings: Default::default(), kind }421    }422}423424#[derive(Copy, Clone, PartialEq, Eq, Debug)]425pub(crate) enum AliasPossibility {426    No,427    Maybe,428}429430#[derive(Copy, Clone, Debug)]431pub(crate) enum PathSource<'a, 'ast, 'ra> {432    /// Type paths `Path`.433    Type,434    /// Trait paths in bounds or impls.435    Trait(AliasPossibility),436    /// Expression paths `path`, with optional parent context.437    Expr(Option<&'ast Expr>),438    /// Paths in path patterns `Path`.439    Pat,440    /// Paths in struct expressions and patterns `Path { .. }`.441    Struct(Option<&'a Expr>),442    /// Paths in tuple struct patterns `Path(..)`.443    TupleStruct(Span, &'ra [Span]),444    /// `m::A::B` in `<T as m::A>::B::C`.445    ///446    /// Second field holds the "cause" of this one, i.e. the context within447    /// which the trait item is resolved. Used for diagnostics.448    TraitItem(Namespace, &'a PathSource<'a, 'ast, 'ra>),449    /// Paths in delegation item450    Delegation,451    /// Paths in externally implementable item declarations.452    ExternItemImpl,453    /// An arg in a `use<'a, N>` precise-capturing bound.454    PreciseCapturingArg(Namespace),455    /// Paths that end with `(..)`, for return type notation.456    ReturnTypeNotation,457    /// Paths from `#[define_opaque]` attributes458    DefineOpaques,459    /// Resolving a macro460    Macro,461    /// Paths for module or crate root. Used for restrictions.462    Module,463}464465impl PathSource<'_, '_, '_> {466    fn namespace(self) -> Namespace {467        match self {468            PathSource::Type469            | PathSource::Trait(_)470            | PathSource::Struct(_)471            | PathSource::DefineOpaques472            | PathSource::Module => TypeNS,473            PathSource::Expr(..)474            | PathSource::Pat475            | PathSource::TupleStruct(..)476            | PathSource::Delegation477            | PathSource::ExternItemImpl478            | PathSource::ReturnTypeNotation => ValueNS,479            PathSource::TraitItem(ns, _) => ns,480            PathSource::PreciseCapturingArg(ns) => ns,481            PathSource::Macro => MacroNS,482        }483    }484485    fn defer_to_typeck(self) -> bool {486        match self {487            PathSource::Type488            | PathSource::Expr(..)489            | PathSource::Pat490            | PathSource::Struct(_)491            | PathSource::TupleStruct(..)492            | PathSource::ReturnTypeNotation => true,493            PathSource::Trait(_)494            | PathSource::TraitItem(..)495            | PathSource::DefineOpaques496            | PathSource::Delegation497            | PathSource::ExternItemImpl498            | PathSource::PreciseCapturingArg(..)499            | PathSource::Macro500            | PathSource::Module => false,501        }502    }503504    fn descr_expected(self) -> &'static str {505        match &self {506            PathSource::DefineOpaques => "type alias or associated type with opaqaue types",507            PathSource::Type => "type",508            PathSource::Trait(_) => "trait",509            PathSource::Pat => "unit struct, unit variant or constant",510            PathSource::Struct(_) => "struct, variant or union type",511            PathSource::TraitItem(ValueNS, PathSource::TupleStruct(..))512            | PathSource::TupleStruct(..) => "tuple struct or tuple variant",513            PathSource::TraitItem(ns, _) => match ns {514                TypeNS => "associated type",515                ValueNS => "method or associated constant",516                MacroNS => bug!("associated macro"),517            },518            PathSource::Expr(parent) => match parent.as_ref().map(|p| &p.kind) {519                // "function" here means "anything callable" rather than `DefKind::Fn`,520                // this is not precise but usually more helpful than just "value".521                Some(ExprKind::Call(call_expr, _)) => match &call_expr.kind {522                    // the case of `::some_crate()`523                    ExprKind::Path(_, path)524                        if let [segment, _] = path.segments.as_slice()525                            && segment.ident.name == kw::PathRoot =>526                    {527                        "external crate"528                    }529                    ExprKind::Path(_, path)530                        if let Some(segment) = path.segments.last()531                            && let Some(c) = segment.ident.to_string().chars().next()532                            && c.is_uppercase() =>533                    {534                        "function, tuple struct or tuple variant"535                    }536                    _ => "function",537                },538                _ => "value",539            },540            PathSource::ReturnTypeNotation | PathSource::Delegation => "function",541            PathSource::ExternItemImpl => "function or static",542            PathSource::PreciseCapturingArg(..) => "type or const parameter",543            PathSource::Macro => "macro",544            PathSource::Module => "module",545        }546    }547548    fn is_call(self) -> bool {549        matches!(self, PathSource::Expr(Some(&Expr { kind: ExprKind::Call(..), .. })))550    }551552    pub(crate) fn is_expected(self, res: Res) -> bool {553        match self {554            PathSource::DefineOpaques => {555                matches!(556                    res,557                    Res::Def(558                        DefKind::Struct559                            | DefKind::Union560                            | DefKind::Enum561                            | DefKind::TyAlias562                            | DefKind::AssocTy,563                        _564                    ) | Res::SelfTyAlias { .. }565                )566            }567            PathSource::Type => matches!(568                res,569                Res::Def(570                    DefKind::Struct571                        | DefKind::Union572                        | DefKind::Enum573                        | DefKind::Trait574                        | DefKind::TraitAlias575                        | DefKind::TyAlias576                        | DefKind::AssocTy577                        | DefKind::TyParam578                        | DefKind::OpaqueTy579                        | DefKind::ForeignTy,580                    _,581                ) | Res::PrimTy(..)582                    | Res::SelfTyParam { .. }583                    | Res::SelfTyAlias { .. }584            ),585            PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),586            PathSource::Trait(AliasPossibility::Maybe) => {587                matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))588            }589            PathSource::Expr(..) => matches!(590                res,591                Res::Def(592                    DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn)593                        | DefKind::Const { .. }594                        | DefKind::Static { .. }595                        | DefKind::Fn596                        | DefKind::AssocFn597                        | DefKind::AssocConst { .. }598                        | DefKind::ConstParam,599                    _,600                ) | Res::Local(..)601                    | Res::SelfCtor(..)602            ),603            PathSource::Pat => {604                res.expected_in_unit_struct_pat()605                    || matches!(606                        res,607                        Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, _)608                    )609            }610            PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),611            PathSource::Struct(_) => matches!(612                res,613                Res::Def(614                    DefKind::Struct615                        | DefKind::Union616                        | DefKind::Variant617                        | DefKind::TyAlias618                        | DefKind::AssocTy,619                    _,620                ) | Res::SelfTyParam { .. }621                    | Res::SelfTyAlias { .. }622            ),623            PathSource::TraitItem(ns, _) => match res {624                Res::Def(DefKind::AssocConst { .. } | DefKind::AssocFn, _) if ns == ValueNS => true,625                Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,626                _ => false,627            },628            PathSource::ReturnTypeNotation => match res {629                Res::Def(DefKind::AssocFn, _) => true,630                _ => false,631            },632            PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),633            PathSource::ExternItemImpl => {634                matches!(635                    res,636                    Res::Def(637                        DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Static { .. },638                        _639                    )640                )641            }642            PathSource::PreciseCapturingArg(ValueNS) => {643                matches!(res, Res::Def(DefKind::ConstParam, _))644            }645            // We allow `SelfTyAlias` here so we can give a more descriptive error later.646            PathSource::PreciseCapturingArg(TypeNS) => matches!(647                res,648                Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }649            ),650            PathSource::PreciseCapturingArg(MacroNS) => false,651            PathSource::Macro => matches!(res, Res::Def(DefKind::Macro(_), _)),652            PathSource::Module => matches!(res, Res::Def(DefKind::Mod, _)),653        }654    }655656    fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {657        match (self, has_unexpected_resolution) {658            (PathSource::Trait(_), true) => E0404,659            (PathSource::Trait(_), false) => E0405,660            (PathSource::Type | PathSource::DefineOpaques, true) => E0573,661            (PathSource::Type | PathSource::DefineOpaques, false) => E0425,662            (PathSource::Struct(_), true) => E0574,663            (PathSource::Struct(_), false) => E0422,664            (PathSource::Expr(..), true)665            | (PathSource::Delegation, true)666            | (PathSource::ExternItemImpl, true) => E0423,667            (PathSource::Expr(..), false)668            | (PathSource::Delegation, false)669            | (PathSource::ExternItemImpl, false) => E0425,670            (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,671            (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,672            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, true) => E0575,673            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, false) => E0576,674            (PathSource::PreciseCapturingArg(..), true) => E0799,675            (PathSource::PreciseCapturingArg(..), false) => E0800,676            (PathSource::Macro, _) => E0425,677            // FIXME: There is no dedicated error code for this case yet.678            // E0577 already covers the same situation for visibilities,679            // so we reuse it here for now. It may make sense to generalize680            // it for restrictions in the future.681            (PathSource::Module, true) => E0577,682            (PathSource::Module, false) => E0433,683        }684    }685}686687/// At this point for most items we can answer whether that item is exported or not,688/// but some items like impls require type information to determine exported-ness, so we make a689/// conservative estimate for them (e.g. based on nominal visibility).690#[derive(Clone, Copy)]691enum MaybeExported<'a> {692    Ok(NodeId),693    Impl(Option<DefId>),694    ImplItem(Result<DefId, &'a ast::Visibility>),695    NestedUse(&'a ast::Visibility),696}697698impl MaybeExported<'_> {699    fn eval(self, r: &Resolver<'_, '_>) -> bool {700        let def_id = match self {701            MaybeExported::Ok(node_id) => Some(if r.current_owner.id == node_id {702                r.current_owner.def_id703            } else {704                r.current_owner.node_id_to_def_id[&node_id]705            }),706            MaybeExported::Impl(Some(trait_def_id)) | MaybeExported::ImplItem(Ok(trait_def_id)) => {707                trait_def_id.as_local()708            }709            MaybeExported::Impl(None) => return true,710            MaybeExported::ImplItem(Err(vis)) | MaybeExported::NestedUse(vis) => {711                return vis.kind.is_pub();712            }713        };714        def_id.is_none_or(|def_id| r.effective_visibilities.is_exported(def_id))715    }716}717718/// Used for recording UnnecessaryQualification.719#[derive(Debug)]720pub(crate) struct UnnecessaryQualification<'ra> {721    pub decl: LateDecl<'ra>,722    pub node_id: NodeId,723    pub path_span: Span,724    pub removal_span: Span,725}726727#[derive(Default, Debug)]728pub(crate) struct DiagMetadata<'ast> {729    /// The current trait's associated items' ident, used for diagnostic suggestions.730    current_trait_assoc_items: Option<&'ast [Box<AssocItem>]>,731732    /// The current self type if inside an impl (used for better errors).733    pub(crate) current_self_type: Option<&'ast Ty>,734735    /// The current self item if inside an ADT (used for better errors).736    current_self_item: Option<NodeId>,737738    /// The current item being evaluated (used for suggestions and more detail in errors).739    pub(crate) current_item: Option<&'ast Item>,740741    /// When processing generic arguments and encountering an unresolved ident not found,742    /// suggest introducing a type or const param depending on the context.743    currently_processing_generic_args: bool,744745    /// The current enclosing (non-closure) function (used for better errors).746    current_function: Option<(FnKind<'ast>, Span)>,747748    /// A list of labels as of yet unused. Labels will be removed from this map when749    /// they are used (in a `break` or `continue` statement)750    unused_labels: FxIndexMap<NodeId, Span>,751752    /// Only used for better errors on `let <pat>: <expr, not type>;`.753    current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,754755    current_pat: Option<&'ast Pat>,756757    /// Used to detect possible `if let` written without `let` and to provide structured suggestion.758    in_if_condition: Option<&'ast Expr>,759760    /// Used to detect possible new binding written without `let` and to provide structured suggestion.761    in_assignment: Option<&'ast Expr>,762    is_assign_rhs: bool,763764    /// If we are setting an associated type in trait impl, is it a non-GAT type?765    in_non_gat_assoc_type: Option<bool>,766767    /// Used to detect possible `.` -> `..` typo when calling methods.768    in_range: Option<(&'ast Expr, &'ast Expr)>,769770    /// If we are currently in a trait object definition. Used to point at the bounds when771    /// encountering a struct or enum.772    current_trait_object: Option<&'ast [ast::GenericBound]>,773774    /// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.775    current_where_predicate: Option<&'ast WherePredicate>,776777    /// Whether we are visiting an associated type equality binding like `Trait<Assoc = &T>`.778    in_assoc_ty_binding: bool,779780    current_type_path: Option<&'ast Ty>,781782    /// The current impl items (used to suggest).783    current_impl_items: Option<&'ast [Box<AssocItem>]>,784785    /// The current impl items (used to suggest).786    current_impl_item: Option<&'ast AssocItem>,787788    /// When processing impl trait789    currently_processing_impl_trait: Option<(TraitRef, Ty)>,790791    /// Accumulate the errors due to missed lifetime elision,792    /// and report them all at once for each function.793    current_elision_failures: Vec<(MissingLifetime, Either<NodeId, Range<NodeId>>)>,794}795796struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {797    r: &'a mut Resolver<'ra, 'tcx>,798799    /// The module that represents the current item scope.800    parent_scope: ParentScope<'ra>,801802    /// The current set of local scopes for types and values.803    ribs: PerNS<Vec<Rib<'ra>>>,804805    /// Previous popped `rib`, only used for diagnostic.806    last_block_rib: Option<Rib<'ra>>,807808    /// The current set of local scopes, for labels.809    label_ribs: Vec<Rib<'ra, NodeId>>,810811    /// The current set of local scopes for lifetimes.812    lifetime_ribs: Vec<LifetimeRib>,813814    /// We are looking for lifetimes in an elision context.815    /// The set contains all the resolutions that we encountered so far.816    /// They will be used to determine the correct lifetime for the fn return type.817    /// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named818    /// lifetimes.819    lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,820821    /// The trait that the current context can refer to.822    current_trait_ref: Option<(Module<'ra>, TraitRef)>,823824    /// Fields used to add information to diagnostic errors.825    diag_metadata: Box<DiagMetadata<'ast>>,826827    /// State used to know whether to ignore resolution errors for function bodies.828    ///829    /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items.830    /// In most cases this will be `None`, in which case errors will always be reported.831    /// If it is `true`, then it will be updated when entering a nested function or trait body.832    in_func_body: bool,833834    /// Count the number of places a lifetime is used.835    lifetime_uses: FxHashMap<LocalDefId, LifetimeUseSet>,836837    /// `use` injections are delayed for better placement and deduplication.838    use_injections: Vec<UseError<'tcx>>,839}840841impl<'ra, 'tcx> AsRef<Resolver<'ra, 'tcx>> for LateResolutionVisitor<'_, '_, 'ra, 'tcx> {842    fn as_ref(&self) -> &Resolver<'ra, 'tcx> {843        &self.r844    }845}846impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for LateResolutionVisitor<'_, '_, 'ra, 'tcx> {847    fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {848        &mut self.r849    }850}851852/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.853impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {854    fn visit_attribute(&mut self, _: &'ast Attribute) {855        // We do not want to resolve expressions that appear in attributes,856        // as they do not correspond to actual code.857    }858    fn visit_item(&mut self, item: &'ast Item) {859        let prev = replace(&mut self.diag_metadata.current_item, Some(item));860        // Always report errors in items we just entered.861        let old_ignore = replace(&mut self.in_func_body, false);862        with_owner(self, item.id, |this| {863            this.with_lifetime_rib(LifetimeRibKind::Item, |this| this.resolve_item(item))864        });865        self.in_func_body = old_ignore;866        self.diag_metadata.current_item = prev;867    }868    fn visit_arm(&mut self, arm: &'ast Arm) {869        self.resolve_arm(arm);870    }871    fn visit_block(&mut self, block: &'ast Block) {872        let old_macro_rules = self.parent_scope.macro_rules;873        self.resolve_block(block);874        self.parent_scope.macro_rules = old_macro_rules;875    }876    fn visit_anon_const(&mut self, constant: &'ast AnonConst) {877        bug!("encountered anon const without a manual call to `resolve_anon_const`: {constant:#?}");878    }879    fn visit_expr(&mut self, expr: &'ast Expr) {880        self.resolve_expr(expr, None);881    }882    fn visit_pat(&mut self, p: &'ast Pat) {883        let prev = self.diag_metadata.current_pat;884        self.diag_metadata.current_pat = Some(p);885886        if let PatKind::Guard(subpat, _) = &p.kind {887            // We walk the guard expression in `resolve_pattern_inner`. Don't resolve it twice.888            self.visit_pat(subpat);889        } else {890            visit::walk_pat(self, p);891        }892893        self.diag_metadata.current_pat = prev;894    }895    fn visit_local(&mut self, local: &'ast Local) {896        let local_spans = match local.pat.kind {897            // We check for this to avoid tuple struct fields.898            PatKind::Wild => None,899            _ => Some((900                local.pat.span,901                local.ty.as_ref().map(|ty| ty.span),902                local.kind.init().map(|init| init.span),903            )),904        };905        let original = replace(&mut self.diag_metadata.current_let_binding, local_spans);906        self.resolve_local(local);907        self.diag_metadata.current_let_binding = original;908    }909    fn visit_ty(&mut self, ty: &'ast Ty) {910        let prev = self.diag_metadata.current_trait_object;911        let prev_ty = self.diag_metadata.current_type_path;912        match &ty.kind {913            TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => {914                // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with915                // NodeId `ty.id`.916                // This span will be used in case of elision failure.917                let span = self.r.tcx.sess.source_map().start_point(ty.span);918                self.resolve_elided_lifetime(ty.id, span);919                visit::walk_ty(self, ty);920            }921            TyKind::Path(qself, path) => {922                self.diag_metadata.current_type_path = Some(ty);923924                // If we have a path that ends with `(..)`, then it must be925                // return type notation. Resolve that path in the *value*926                // namespace.927                let source = if let Some(seg) = path.segments.last()928                    && let Some(args) = &seg.args929                    && matches!(**args, GenericArgs::ParenthesizedElided(..))930                {931                    PathSource::ReturnTypeNotation932                } else {933                    PathSource::Type934                };935936                self.smart_resolve_path(ty.id, qself, path, source);937938                // Check whether we should interpret this as a bare trait object.939                if qself.is_none()940                    && let Some(partial_res) = self.r.partial_res_map.get(&ty.id)941                    && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) =942                        partial_res.full_res()943                {944                    // This path is actually a bare trait object. In case of a bare `Fn`-trait945                    // object with anonymous lifetimes, we need this rib to correctly place the946                    // synthetic lifetimes.947                    let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo());948                    self.with_generic_param_rib(949                        &[],950                        RibKind::Normal,951                        ty.id,952                        LifetimeBinderKind::PolyTrait,953                        span,954                        |this| this.visit_path(path),955                    );956                } else {957                    visit::walk_ty(self, ty)958                }959            }960            TyKind::ImplicitSelf => {961                let self_ty = Ident::with_dummy_span(kw::SelfUpper);962                let res = self963                    .resolve_ident_in_lexical_scope(964                        self_ty,965                        TypeNS,966                        Some(Finalize::new(ty.id, ty.span)),967                        None,968                    )969                    .map_or(Res::Err, |d| d.res());970                self.r.record_partial_res(ty.id, PartialRes::new(res));971                visit::walk_ty(self, ty)972            }973            TyKind::ImplTrait(..) => {974                let candidates = self.lifetime_elision_candidates.take();975                self.with_lifetime_rib(LifetimeRibKind::ImplTrait, |this| visit::walk_ty(this, ty));976                self.lifetime_elision_candidates = candidates;977            }978            TyKind::TraitObject(bounds, ..) => {979                self.diag_metadata.current_trait_object = Some(&bounds[..]);980                visit::walk_ty(self, ty)981            }982            TyKind::FnPtr(fn_ptr) => {983                let span = ty.span.shrink_to_lo().to(fn_ptr.decl_span.shrink_to_lo());984                self.with_generic_param_rib(985                    &fn_ptr.generic_params,986                    RibKind::Normal,987                    ty.id,988                    LifetimeBinderKind::FnPtrType,989                    span,990                    |this| {991                        this.visit_generic_params(&fn_ptr.generic_params, false);992                        this.resolve_fn_signature(993                            ty.id,994                            false,995                            // We don't need to deal with patterns in parameters, because996                            // they are not possible for foreign or bodiless functions.997                            fn_ptr.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),998                            &fn_ptr.decl.output,999                            false,1000                        )1001                    },1002                )1003            }1004            TyKind::UnsafeBinder(unsafe_binder) => {1005                let span = ty.span.shrink_to_lo().to(unsafe_binder.inner_ty.span.shrink_to_lo());1006                self.with_generic_param_rib(1007                    &unsafe_binder.generic_params,1008                    RibKind::Normal,1009                    ty.id,1010                    LifetimeBinderKind::FnPtrType,1011                    span,1012                    |this| {1013                        this.visit_generic_params(&unsafe_binder.generic_params, false);1014                        this.with_lifetime_rib(1015                            // We don't allow anonymous `unsafe &'_ ()` binders,1016                            // although I guess we could.1017                            LifetimeRibKind::AnonymousReportError,1018                            |this| this.visit_ty(&unsafe_binder.inner_ty),1019                        );1020                    },1021                )1022            }1023            TyKind::Array(element_ty, length) => {1024                self.visit_ty(element_ty);1025                self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));1026            }1027            TyKind::DirectConstArg(expr) => self.resolve_anon_const_manual(1028                true,1029                AnonConstKind::ConstArg(IsRepeatExpr::No),1030                |this| this.resolve_expr(expr, None),1031            ),1032            _ => visit::walk_ty(self, ty),1033        }1034        self.diag_metadata.current_trait_object = prev;1035        self.diag_metadata.current_type_path = prev_ty;1036    }10371038    fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {1039        match &t.kind {1040            TyPatKind::Range(start, end, _) => {1041                if let Some(start) = start {1042                    self.resolve_anon_const(start, AnonConstKind::ConstArg(IsRepeatExpr::No));1043                }1044                if let Some(end) = end {1045                    self.resolve_anon_const(end, AnonConstKind::ConstArg(IsRepeatExpr::No));1046                }1047            }1048            TyPatKind::Or(patterns) => {1049                for pat in patterns {1050                    self.visit_ty_pat(pat)1051                }1052            }1053            TyPatKind::NotNull | TyPatKind::Err(_) => {}1054        }1055    }10561057    fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {1058        let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());1059        self.with_generic_param_rib(1060            &tref.bound_generic_params,1061            RibKind::Normal,1062            tref.trait_ref.ref_id,1063            LifetimeBinderKind::PolyTrait,1064            span,1065            |this| {1066                this.visit_generic_params(&tref.bound_generic_params, false);1067                this.smart_resolve_path(1068                    tref.trait_ref.ref_id,1069                    &None,1070                    &tref.trait_ref.path,1071                    PathSource::Trait(AliasPossibility::Maybe),1072                );1073                this.visit_trait_ref(&tref.trait_ref);1074            },1075        );1076    }1077    fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {1078        with_owner(self, foreign_item.id, |this| {1079            this.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id));1080            let def_kind = this.r.tcx.def_kind(this.r.current_owner.def_id);1081            match foreign_item.kind {1082                ForeignItemKind::TyAlias(TyAlias { ref generics, .. }) => {1083                    this.with_generic_param_rib(1084                        &generics.params,1085                        RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),1086                        foreign_item.id,1087                        LifetimeBinderKind::Item,1088                        generics.span,1089                        |this| visit::walk_item(this, foreign_item),1090                    );1091                }1092                ForeignItemKind::Fn(Fn { ref generics, .. }) => {1093                    this.with_generic_param_rib(1094                        &generics.params,1095                        RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),1096                        foreign_item.id,1097                        LifetimeBinderKind::Function,1098                        generics.span,1099                        |this| visit::walk_item(this, foreign_item),1100                    );1101                }1102                ForeignItemKind::Static(..) => {1103                    this.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item))1104                }1105                ForeignItemKind::MacCall(..) => {1106                    panic!("unexpanded macro in resolve!")1107                }1108            }1109        })1110    }1111    fn visit_fn(&mut self, fn_kind: FnKind<'ast>, _: &AttrVec, sp: Span, fn_id: NodeId) {1112        let previous_value = self.diag_metadata.current_function;1113        match fn_kind {1114            // Bail if the function is foreign, and thus cannot validly have1115            // a body, or if there's no body for some other reason.1116            FnKind::Fn(FnCtxt::Foreign, _, Fn { sig, ident, generics, .. })1117            | FnKind::Fn(_, _, Fn { sig, ident, generics, body: None, .. }) => {1118                self.visit_fn_header(&sig.header);1119                self.visit_ident(ident);1120                self.visit_generics(generics);1121                self.resolve_fn_signature(1122                    fn_id,1123                    sig.decl.has_self(),1124                    sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),1125                    &sig.decl.output,1126                    false,1127                );1128                return;1129            }1130            FnKind::Fn(..) => {1131                self.diag_metadata.current_function = Some((fn_kind, sp));1132            }1133            // Do not update `current_function` for closures: it suggests `self` parameters.1134            FnKind::Closure(..) => {}1135        };1136        debug!("(resolving function) entering function");11371138        if let FnKind::Fn(_, _, f) = fn_kind {1139            self.resolve_eii(f.eii_impl.as_deref());1140        }11411142        // Create a value rib for the function.1143        self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {1144            // Create a label rib for the function.1145            this.with_label_rib(RibKind::FnOrCoroutine, |this| {1146                match fn_kind {1147                    FnKind::Fn(_, _, Fn { sig, generics, contract, body, .. }) => {1148                        this.visit_generics(generics);11491150                        let declaration = &sig.decl;1151                        this.resolve_fn_signature(1152                            fn_id,1153                            declaration.has_self(),1154                            declaration1155                                .inputs1156                                .iter()1157                                .map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)),1158                            &declaration.output,1159                            sig.header.coroutine_marker.is_some(),1160                        );11611162                        if let Some(contract) = contract {1163                            this.visit_contract(contract);1164                        }11651166                        if let Some(body) = body {1167                            // Ignore errors in function bodies if this is rustdoc. Be sure not to1168                            // set this until the function signature has been resolved.1169                            let previous_state = replace(&mut this.in_func_body, true);1170                            // We only care block in the same function1171                            this.last_block_rib = None;1172                            // Resolve the function body, potentially inside the body of an async1173                            // closure.1174                            this.with_lifetime_rib(1175                                LifetimeRibKind::elided(LifetimeRes::Infer),1176                                |this| this.visit_block(body),1177                            );11781179                            debug!("(resolving function) leaving function");1180                            this.in_func_body = previous_state;1181                        }1182                    }1183                    FnKind::Closure(binder, _, declaration, body) => {1184                        this.visit_closure_binder(binder);11851186                        this.with_lifetime_rib(1187                            match binder {1188                                // We do not have any explicit generic lifetime parameter.1189                                ClosureBinder::NotPresent => {1190                                    LifetimeRibKind::AnonymousCreateParameter {1191                                        binder: fn_id,1192                                        report_in_path: false,1193                                    }1194                                }1195                                ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,1196                            },1197                            // Add each argument to the rib.1198                            |this| this.resolve_params(&declaration.inputs),1199                        );1200                        this.with_lifetime_rib(1201                            match binder {1202                                ClosureBinder::NotPresent => {1203                                    LifetimeRibKind::elided(LifetimeRes::Infer)1204                                }1205                                ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,1206                            },1207                            |this| visit::walk_fn_ret_ty(this, &declaration.output),1208                        );12091210                        // Ignore errors in function bodies if this is rustdoc1211                        // Be sure not to set this until the function signature has been resolved.1212                        let previous_state = replace(&mut this.in_func_body, true);1213                        // Resolve the function body, potentially inside the body of an async closure1214                        this.with_lifetime_rib(1215                            LifetimeRibKind::elided(LifetimeRes::Infer),1216                            |this| this.visit_expr(body),1217                        );12181219                        debug!("(resolving function) leaving function");1220                        this.in_func_body = previous_state;1221                    }1222                }1223            })1224        });1225        self.diag_metadata.current_function = previous_value;1226    }12271228    fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {1229        self.resolve_lifetime(lifetime, use_ctxt)1230    }12311232    fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {1233        match arg {1234            // Lower the lifetime regularly; we'll resolve the lifetime and check1235            // it's a parameter later on in HIR lowering.1236            PreciseCapturingArg::Lifetime(_) => {}12371238            PreciseCapturingArg::Arg(path, id) => {1239                // we want `impl use<C>` to try to resolve `C` as both a type parameter or1240                // a const parameter. Since the resolver specifically doesn't allow having1241                // two generic params with the same name, even if they're a different namespace,1242                // it doesn't really matter which we try resolving first, but just like1243                // `Ty::Param` we just fall back to the value namespace only if it's missing1244                // from the type namespace.1245                let mut check_ns = |ns| {1246                    self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some()1247                };1248                // Like `Ty::Param`, we try resolving this as both a const and a type.1249                if !check_ns(TypeNS) && check_ns(ValueNS) {1250                    self.smart_resolve_path(1251                        *id,1252                        &None,1253                        path,1254                        PathSource::PreciseCapturingArg(ValueNS),1255                    );1256                } else {1257                    self.smart_resolve_path(1258                        *id,1259                        &None,1260                        path,1261                        PathSource::PreciseCapturingArg(TypeNS),1262                    );1263                }1264            }1265        }12661267        visit::walk_precise_capturing_arg(self, arg)1268    }12691270    fn visit_generics(&mut self, generics: &'ast Generics) {1271        self.visit_generic_params(&generics.params, self.diag_metadata.current_self_item.is_some());1272        for p in &generics.where_clause.predicates {1273            self.visit_where_predicate(p);1274        }1275    }12761277    fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) {1278        match b {1279            ClosureBinder::NotPresent => {}1280            ClosureBinder::For { generic_params, .. } => {1281                self.visit_generic_params(1282                    generic_params,1283                    self.diag_metadata.current_self_item.is_some(),1284                );1285            }1286        }1287    }12881289    #[instrument(level = "debug", skip(self))]1290    fn visit_generic_arg(&mut self, arg: &'ast GenericArg) {1291        let prev = replace(&mut self.diag_metadata.currently_processing_generic_args, true);1292        match arg {1293            GenericArg::Type(ty) => {1294                // We parse const arguments as path types as we cannot distinguish them during1295                // parsing. We try to resolve that ambiguity by attempting resolution the type1296                // namespace first, and if that fails we try again in the value namespace. If1297                // resolution in the value namespace succeeds, we have an generic const argument on1298                // our hands.1299                //1300                // We cannot disambiguate multi-segment paths right now as that requires type1301                // checking.1302                if let TyKind::Path(None, ref path) = ty.kind1303                    && let Some(ident) = path.as_single_argless_ident()1304                    && self.maybe_resolve_ident_in_lexical_scope(ident, TypeNS).is_none()1305                    && self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS).is_some()1306                {1307                    self.resolve_anon_const_manual(1308                        true,1309                        AnonConstKind::ConstArg(IsRepeatExpr::No),1310                        |this| {1311                            this.smart_resolve_path(ty.id, &None, path, PathSource::Expr(None));1312                            this.visit_path(path);1313                        },1314                    )1315                } else {1316                    self.visit_ty(ty)1317                }1318            }1319            GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg),1320            GenericArg::Const(ct) => {1321                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))1322            }1323        }1324        self.diag_metadata.currently_processing_generic_args = prev;1325    }13261327    fn visit_assoc_item_constraint(&mut self, constraint: &'ast AssocItemConstraint) {1328        self.visit_ident(&constraint.ident);1329        if let Some(ref gen_args) = constraint.gen_args {1330            // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.1331            self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {1332                this.visit_generic_args(gen_args)1333            });1334        }1335        match constraint.kind {1336            AssocItemConstraintKind::Equality { ref term } => match term {1337                Term::Ty(ty) => {1338                    let prev = replace(&mut self.diag_metadata.in_assoc_ty_binding, true);1339                    self.visit_ty(ty);1340                    self.diag_metadata.in_assoc_ty_binding = prev;1341                }1342                Term::Const(c) => {1343                    self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))1344                }1345            },1346            AssocItemConstraintKind::Bound { ref bounds } => {1347                walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);1348            }1349        }1350    }13511352    fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {1353        let Some(ref args) = path_segment.args else {1354            return;1355        };13561357        match &**args {1358            GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),1359            GenericArgs::Parenthesized(p_args) => {1360                // Probe the lifetime ribs to know how to behave.1361                for rib in self.lifetime_ribs.iter().rev() {1362                    match rib.kind {1363                        // We are inside a `PolyTraitRef`. The lifetimes are1364                        // to be introduced in that (maybe implicit) `for<>` binder.1365                        LifetimeRibKind::Generics {1366                            binder,1367                            kind: LifetimeBinderKind::PolyTrait,1368                            ..1369                        } => {1370                            self.resolve_fn_signature(1371                                binder,1372                                false,1373                                p_args.inputs.iter().map(|param| (None, &*param.ty)),1374                                &p_args.output,1375                                false,1376                            );1377                            break;1378                        }1379                        // We have nowhere to introduce generics. Code is malformed,1380                        // so use regular lifetime resolution to avoid spurious errors.1381                        LifetimeRibKind::Item | LifetimeRibKind::Generics { .. } => {1382                            visit::walk_generic_args(self, args);1383                            break;1384                        }1385                        LifetimeRibKind::AnonymousCreateParameter { .. }1386                        | LifetimeRibKind::AnonymousReportError1387                        | LifetimeRibKind::ImplTrait1388                        | LifetimeRibKind::Elided { .. }1389                        | LifetimeRibKind::ElisionFailure1390                        | LifetimeRibKind::ConcreteAnonConst(_)1391                        | LifetimeRibKind::ConstParamTy => {}1392                    }1393                }1394            }1395            GenericArgs::ParenthesizedElided(_) => {}1396        }1397    }13981399    fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {1400        debug!("visit_where_predicate {:?}", p);1401        let previous_value = replace(&mut self.diag_metadata.current_where_predicate, Some(p));1402        self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {1403            if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {1404                bounded_ty,1405                bounds,1406                bound_generic_params,1407                ..1408            }) = &p.kind1409            {1410                let span = p.span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());1411                this.with_generic_param_rib(1412                    bound_generic_params,1413                    RibKind::Normal,1414                    bounded_ty.id,1415                    LifetimeBinderKind::WhereBound,1416                    span,1417                    |this| {1418                        this.visit_generic_params(bound_generic_params, false);1419                        this.visit_ty(bounded_ty);1420                        for bound in bounds {1421                            this.visit_param_bound(bound, BoundKind::Bound)1422                        }1423                    },1424                );1425            } else {1426                visit::walk_where_predicate(this, p);1427            }1428        });1429        self.diag_metadata.current_where_predicate = previous_value;1430    }14311432    fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) {1433        for (op, _) in &asm.operands {1434            match op {1435                InlineAsmOperand::In { expr, .. }1436                | InlineAsmOperand::Out { expr: Some(expr), .. }1437                | InlineAsmOperand::InOut { expr, .. } => self.visit_expr(expr),1438                InlineAsmOperand::Out { expr: None, .. } => {}1439                InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {1440                    self.visit_expr(in_expr);1441                    if let Some(out_expr) = out_expr {1442                        self.visit_expr(out_expr);1443                    }1444                }1445                InlineAsmOperand::Const { anon_const, .. } => {1446                    // Although this is `DefKind::AnonConst`, it is allowed to reference outer1447                    // generic parameters like an inline const.1448                    self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);1449                }1450                InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),1451                InlineAsmOperand::Label { block } => self.visit_block(block),1452            }1453        }1454    }14551456    fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {1457        // This is similar to the code for AnonConst.1458        self.with_rib(ValueNS, RibKind::InlineAsmSym, |this| {1459            this.with_rib(TypeNS, RibKind::InlineAsmSym, |this| {1460                this.with_label_rib(RibKind::InlineAsmSym, |this| {1461                    this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));1462                    visit::walk_inline_asm_sym(this, sym);1463                });1464            })1465        });1466    }14671468    fn visit_variant(&mut self, v: &'ast Variant) {1469        self.resolve_doc_links(&v.attrs, MaybeExported::Ok(v.id));1470        self.visit_id(v.id);1471        walk_list!(self, visit_attribute, &v.attrs);1472        self.visit_vis(&v.vis);1473        self.visit_ident(&v.ident);1474        self.visit_variant_data(&v.data);1475        if let Some(discr) = &v.disr_expr {1476            self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant);1477        }1478    }14791480    fn visit_field_def(&mut self, f: &'ast FieldDef) {1481        self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));1482        let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _, extras: _ } = f;1483        walk_list!(self, visit_attribute, attrs);1484        try_visit!(self.visit_vis(vis));1485        self.resolve_restriction_path(&f.mut_restriction().kind);1486        visit_opt!(self, visit_ident, ident);1487        try_visit!(self.visit_ty(ty));1488        if let Some(v) = f.default_value() {1489            self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue);1490        }1491    }1492}14931494impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {1495    fn new(resolver: &'a mut Resolver<'ra, 'tcx>) -> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {1496        // During late resolution we only track the module component of the parent scope,1497        // although it may be useful to track other components as well for diagnostics.1498        let graph_root = resolver.graph_root;1499        let parent_scope = ParentScope::module(graph_root, resolver.arenas);1500        let start_rib_kind = RibKind::Module(graph_root);1501        LateResolutionVisitor {1502            r: resolver,1503            parent_scope,1504            ribs: PerNS {1505                value_ns: vec![Rib::new(start_rib_kind)],1506                type_ns: vec![Rib::new(start_rib_kind)],1507                macro_ns: vec![Rib::new(start_rib_kind)],1508            },1509            last_block_rib: None,1510            label_ribs: Vec::new(),1511            lifetime_ribs: Vec::new(),1512            lifetime_elision_candidates: None,1513            current_trait_ref: None,1514            diag_metadata: Default::default(),1515            // errors at module scope should always be reported1516            in_func_body: false,1517            lifetime_uses: Default::default(),1518            use_injections: Vec::new(),1519        }1520    }15211522    fn maybe_resolve_ident_in_lexical_scope(1523        &mut self,1524        ident: Ident,1525        ns: Namespace,1526    ) -> Option<LateDecl<'ra>> {1527        self.r.resolve_ident_in_lexical_scope(1528            ident,1529            ns,1530            &self.parent_scope,1531            None,1532            &self.ribs[ns],1533            None,1534            Some(&self.diag_metadata),1535        )1536    }15371538    fn resolve_ident_in_lexical_scope(1539        &mut self,1540        ident: Ident,1541        ns: Namespace,1542        finalize: Option<Finalize>,1543        ignore_decl: Option<Decl<'ra>>,1544    ) -> Option<LateDecl<'ra>> {1545        self.r.resolve_ident_in_lexical_scope(1546            ident,1547            ns,1548            &self.parent_scope,1549            finalize,1550            &self.ribs[ns],1551            ignore_decl,1552            Some(&self.diag_metadata),1553        )1554    }15551556    fn resolve_path(1557        &mut self,1558        path: &[Segment],1559        opt_ns: Option<Namespace>, // `None` indicates a module path in import1560        finalize: Option<Finalize>,1561        source: PathSource<'_, 'ast, 'ra>,1562    ) -> PathResult<'ra> {1563        self.r.cm_mut().resolve_path_with_ribs(1564            path,1565            opt_ns,1566            &self.parent_scope,1567            Some(source),1568            finalize.map(|finalize| Finalize { stage: Stage::Late, ..finalize }),1569            Some(&self.ribs),1570            None,1571            None,1572            Some(&self.diag_metadata),1573        )1574    }15751576    // AST resolution1577    //1578    // We maintain a list of value ribs and type ribs.1579    //1580    // Simultaneously, we keep track of the current position in the module1581    // graph in the `parent_scope.module` pointer. When we go to resolve a name in1582    // the value or type namespaces, we first look through all the ribs and1583    // then query the module graph. When we resolve a name in the module1584    // namespace, we can skip all the ribs (since nested modules are not1585    // allowed within blocks in Rust) and jump straight to the current module1586    // graph node.1587    //1588    // Named implementations are handled separately. When we find a method1589    // call, we consult the module node to find all of the implementations in1590    // scope. This information is lazily cached in the module node. We then1591    // generate a fake "implementation scope" containing all the1592    // implementations thus found, for compatibility with old resolve pass.15931594    /// Do some `work` within a new innermost rib of the given `kind` in the given namespace (`ns`).1595    fn with_rib<T>(1596        &mut self,1597        ns: Namespace,1598        kind: RibKind<'ra>,1599        work: impl FnOnce(&mut Self) -> T,1600    ) -> T {1601        self.ribs[ns].push(Rib::new(kind));1602        let ret = work(self);1603        self.ribs[ns].pop();1604        ret1605    }16061607    fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper: bool) {1608        // For type parameter defaults, we have to ban access1609        // to following type parameters, as the GenericArgs can only1610        // provide previous type parameters as they're built. We1611        // put all the parameters on the ban list and then remove1612        // them one by one as they are processed and become available.1613        let mut forward_ty_ban_rib =1614            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));1615        let mut forward_const_ban_rib =1616            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));1617        for param in params.iter() {1618            match param.kind {1619                GenericParamKind::Type { .. } => {1620                    forward_ty_ban_rib1621                        .bindings1622                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);1623                }1624                GenericParamKind::Const { .. } => {1625                    forward_const_ban_rib1626                        .bindings1627                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);1628                }1629                GenericParamKind::Lifetime => {}1630            }1631        }16321633        // rust-lang/rust#61631: The type `Self` is essentially1634        // another type parameter. For ADTs, we consider it1635        // well-defined only after all of the ADT type parameters have1636        // been provided. Therefore, we do not allow use of `Self`1637        // anywhere in ADT type parameter defaults.1638        //1639        // (We however cannot ban `Self` for defaults on *all* generic1640        // lists; e.g. trait generics can usefully refer to `Self`,1641        // such as in the case of `trait Add<Rhs = Self>`.)1642        if add_self_upper {1643            // (`Some` if + only if we are in ADT's generics.)1644            forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);1645        }16461647        // NOTE: We use different ribs here not for a technical reason, but just1648        // for better diagnostics.1649        let mut forward_ty_ban_rib_const_param_ty = Rib {1650            bindings: forward_ty_ban_rib.bindings.clone(),1651            patterns_with_skipped_bindings: Default::default(),1652            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),1653        };1654        let mut forward_const_ban_rib_const_param_ty = Rib {1655            bindings: forward_const_ban_rib.bindings.clone(),1656            patterns_with_skipped_bindings: Default::default(),1657            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),1658        };1659        // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better1660        // diagnostics, so we don't mention anything about const param tys having generics at all.1661        if !self.r.features.generic_const_parameter_types() {1662            forward_ty_ban_rib_const_param_ty.bindings.clear();1663            forward_const_ban_rib_const_param_ty.bindings.clear();1664        }16651666        self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {1667            for param in params {1668                match param.kind {1669                    GenericParamKind::Lifetime => {1670                        for bound in &param.bounds {1671                            this.visit_param_bound(bound, BoundKind::Bound);1672                        }1673                    }1674                    GenericParamKind::Type { ref default } => {1675                        for bound in &param.bounds {1676                            this.visit_param_bound(bound, BoundKind::Bound);1677                        }16781679                        if let Some(ty) = default {1680                            this.ribs[TypeNS].push(forward_ty_ban_rib);1681                            this.ribs[ValueNS].push(forward_const_ban_rib);1682                            this.visit_ty(ty);1683                            forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();1684                            forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();1685                        }16861687                        // Allow all following defaults to refer to this type parameter.1688                        let i = &Ident::with_dummy_span(param.ident.name);1689                        forward_ty_ban_rib.bindings.swap_remove(i);1690                        forward_ty_ban_rib_const_param_ty.bindings.swap_remove(i);1691                    }1692                    GenericParamKind::Const { ref ty, span: _, ref default } => {1693                        // Const parameters can't have param bounds.1694                        assert!(param.bounds.is_empty());16951696                        this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty);1697                        this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty);1698                        if this.r.features.generic_const_parameter_types() {1699                            this.visit_ty(ty)1700                        } else {1701                            this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));1702                            this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));1703                            this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {1704                                this.visit_ty(ty)1705                            });1706                            this.ribs[TypeNS].pop().unwrap();1707                            this.ribs[ValueNS].pop().unwrap();1708                        }1709                        forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();1710                        forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();17111712                        if let Some(expr) = default {1713                            this.ribs[TypeNS].push(forward_ty_ban_rib);1714                            this.ribs[ValueNS].push(forward_const_ban_rib);1715                            this.resolve_anon_const(1716                                expr,1717                                AnonConstKind::ConstArg(IsRepeatExpr::No),1718                            );1719                            forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();1720                            forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();1721                        }17221723                        // Allow all following defaults to refer to this const parameter.1724                        let i = &Ident::with_dummy_span(param.ident.name);1725                        forward_const_ban_rib.bindings.swap_remove(i);1726                        forward_const_ban_rib_const_param_ty.bindings.swap_remove(i);1727                    }1728                }1729            }1730        })1731    }17321733    #[instrument(level = "debug", skip(self, work))]1734    fn with_lifetime_rib<T>(1735        &mut self,1736        kind: LifetimeRibKind,1737        work: impl FnOnce(&mut Self) -> T,1738    ) -> T {1739        self.lifetime_ribs.push(LifetimeRib::new(kind));1740        let outer_elision_candidates = self.lifetime_elision_candidates.take();1741        let ret = work(self);1742        self.lifetime_elision_candidates = outer_elision_candidates;1743        self.lifetime_ribs.pop();1744        ret1745    }17461747    #[instrument(level = "debug", skip(self))]1748    fn resolve_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {1749        let ident = lifetime.ident;17501751        if ident.name == kw::StaticLifetime {1752            self.record_lifetime_use(1753                lifetime.id,1754                LifetimeRes::Static,1755                LifetimeElisionCandidate::Ignore,1756            );1757            return;1758        }17591760        if ident.name == kw::UnderscoreLifetime {1761            return self.resolve_anonymous_lifetime(lifetime, lifetime.id, false);1762        }17631764        let mut lifetime_rib_iter = self.lifetime_ribs.iter().rev();1765        while let Some(rib) = lifetime_rib_iter.next() {1766            let normalized_ident = ident.normalize_to_macros_2_0();1767            if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) {1768                self.record_lifetime_use(lifetime.id, res, LifetimeElisionCandidate::Ignore);17691770                if let LifetimeRes::Param { param, binder } = res {1771                    match self.lifetime_uses.entry(param) {1772                        Entry::Vacant(v) => {1773                            debug!("First use of {:?} at {:?}", res, ident.span);1774                            let use_set = self1775                                .lifetime_ribs1776                                .iter()1777                                .rev()1778                                .find_map(|rib| match rib.kind {1779                                    // Do not suggest eliding a lifetime where an anonymous1780                                    // lifetime would be illegal.1781                                    LifetimeRibKind::Item1782                                    | LifetimeRibKind::AnonymousReportError1783                                    | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),1784                                    // An anonymous lifetime is legal here, and bound to the right1785                                    // place, go ahead.1786                                    LifetimeRibKind::AnonymousCreateParameter {1787                                        binder: anon_binder,1788                                        ..1789                                    } => Some(if binder == anon_binder {1790                                        LifetimeUseSet::One { use_span: ident.span, use_ctxt }1791                                    } else {1792                                        LifetimeUseSet::Many1793                                    }),1794                                    // Only report if eliding the lifetime would have the same1795                                    // semantics.1796                                    LifetimeRibKind::Elided { res: r, error_in_path } => {1797                                        Some(if res == r && !error_in_path {1798                                            LifetimeUseSet::One { use_span: ident.span, use_ctxt }1799                                        } else {1800                                            LifetimeUseSet::Many1801                                        })1802                                    }1803                                    LifetimeRibKind::Generics { .. }1804                                    | LifetimeRibKind::ConstParamTy => None,1805                                    LifetimeRibKind::ConcreteAnonConst(_) => {1806                                        span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)1807                                    }18081809                                    LifetimeRibKind::ImplTrait => {1810                                        if self.r.features.anonymous_lifetime_in_impl_trait() {1811                                            None1812                                        } else {1813                                            Some(LifetimeUseSet::Many)1814                                        }1815                                    }1816                                })1817                                .unwrap_or(LifetimeUseSet::Many);1818                            debug!(?use_ctxt, ?use_set);1819                            v.insert(use_set);1820                        }1821                        Entry::Occupied(mut o) => {1822                            debug!("Many uses of {:?} at {:?}", res, ident.span);1823                            *o.get_mut() = LifetimeUseSet::Many;1824                        }1825                    }1826                }1827                return;1828            }18291830            match rib.kind {1831                LifetimeRibKind::Item => break,1832                LifetimeRibKind::ConstParamTy => {1833                    let guar = self.emit_non_static_lt_in_const_param_ty_error(lifetime);1834                    self.record_lifetime_err(lifetime.id, guar);1835                    return;1836                }1837                LifetimeRibKind::ConcreteAnonConst(cause) => {1838                    let guar = self.emit_forbidden_non_static_lifetime_error(cause, lifetime);1839                    self.record_lifetime_err(lifetime.id, guar);1840                    return;1841                }1842                LifetimeRibKind::AnonymousCreateParameter { .. }1843                | LifetimeRibKind::Elided { .. }1844                | LifetimeRibKind::Generics { .. }1845                | LifetimeRibKind::ElisionFailure1846                | LifetimeRibKind::AnonymousReportError1847                | LifetimeRibKind::ImplTrait => {}1848            }1849        }18501851        let normalized_ident = ident.normalize_to_macros_2_0();1852        let outer_res = lifetime_rib_iter1853            .find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer));18541855        let guar = self.emit_undeclared_lifetime_error(lifetime, outer_res);1856        self.record_lifetime_err(lifetime.id, guar);1857    }18581859    #[instrument(level = "debug", skip(self))]1860    fn resolve_anonymous_lifetime(1861        &mut self,1862        lifetime: &Lifetime,1863        id_for_lint: NodeId,1864        elided: bool,1865    ) {1866        debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);18671868        let kind =1869            if elided { MissingLifetimeKind::Ampersand } else { MissingLifetimeKind::Underscore };1870        let missing_lifetime = MissingLifetime {1871            id: lifetime.id,1872            span: lifetime.ident.span,1873            kind,1874            count: 1,1875            id_for_lint,1876        };1877        let elision_candidate = LifetimeElisionCandidate::Missing(missing_lifetime);1878        for (i, rib) in self.lifetime_ribs.iter().enumerate().rev() {1879            debug!(?rib.kind);1880            match rib.kind {1881                LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {1882                    let res = self.create_fresh_lifetime(lifetime.ident, binder, kind);1883                    self.record_lifetime_use(lifetime.id, res, elision_candidate);1884                    return;1885                }1886                LifetimeRibKind::AnonymousReportError => {1887                    let guar = if elided {1888                        let suggestion = if self.diag_metadata.in_assoc_ty_binding {1889                            // In an associated type binding like `I: IntoIterator<Item = &T>`,1890                            // introducing the lifetime on the trait ref would produce1891                            // `I: for<'a> IntoIterator<Item = &'a T>`. Prefer a named lifetime1892                            // from an enclosing item instead, so the assoc-ty-binding-specific path1893                            // below builds that suggestion.1894                            None1895                        } else {1896                            self.lifetime_ribs[i..].iter().rev().find_map(|rib| {1897                                // Look for a `Generics` rib that represents a trait or where-bound1898                                // binder (`T: Trait<&U>` or `where T: Trait<&U>`), since that is1899                                // where the generic E0637 diagnostic can insert `for<'a>`.1900                                if let LifetimeRibKind::Generics {1901                                    span,1902                                    kind:1903                                        LifetimeBinderKind::PolyTrait1904                                        | LifetimeBinderKind::WhereBound,1905                                    ..1906                                } = rib.kind1907                                {1908                                    Some(crate::diagnostics::ElidedAnonymousLifetimeReportErrorSuggestion {1909                                        lo: span.shrink_to_lo(),1910                                        hi: lifetime.ident.span.shrink_to_hi(),1911                                    })1912                                } else {1913                                    None1914                                }1915                            })1916                        };1917                        // are we trying to use an anonymous lifetime1918                        // on a non GAT associated trait type?1919                        if !self.in_func_body1920                            && let Some((module, _)) = &self.current_trait_ref1921                            && let Some(ty) = &self.diag_metadata.current_self_type1922                            && Some(true) == self.diag_metadata.in_non_gat_assoc_type1923                            && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _, _) =1924                                module.kind1925                        {1926                            if def_id_matches_path(1927                                self.r.tcx,1928                                trait_id,1929                                &["core", "iter", "traits", "iterator", "Iterator"],1930                            ) {1931                                self.r.dcx().emit_err(1932                                    crate::diagnostics::LendingIteratorReportError {1933                                        lifetime: lifetime.ident.span,1934                                        ty: ty.span,1935                                    },1936                                )1937                            } else {1938                                let decl = if !trait_id.is_local()1939                                    && let Some(assoc) = self.diag_metadata.current_impl_item1940                                    && let AssocItemKind::Type(_) = assoc.kind1941                                    && let assocs = self.r.tcx.associated_items(trait_id)1942                                    && let Some(ident) = assoc.kind.ident()1943                                    && let Some(assoc) = assocs.find_by_ident_and_kind(1944                                        self.r.tcx,1945                                        ident,1946                                        AssocTag::Type,1947                                        trait_id,1948                                    ) {1949                                    let mut decl: MultiSpan =1950                                        self.r.tcx.def_span(assoc.def_id).into();1951                                    decl.push_span_label(1952                                        self.r.tcx.def_span(trait_id),1953                                        String::new(),1954                                    );1955                                    decl1956                                } else {1957                                    DUMMY_SP.into()1958                                };1959                                let mut err = self.r.dcx().create_err(1960                                    crate::diagnostics::AnonymousLifetimeNonGatReportError {1961                                        lifetime: lifetime.ident.span,1962                                        decl,1963                                    },1964                                );1965                                self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span);1966                                err.emit()1967                            }1968                        } else if self.diag_metadata.in_assoc_ty_binding {1969                            // For associated type bindings, e.g.1970                            // `fn f<I: IntoIterator<Item = &T>>()`, introduce a named lifetime1971                            // on an enclosing generics binder instead:1972                            // `fn f<'a, I: IntoIterator<Item = &'a T>>()`.1973                            let mut err = self.r.dcx().create_err(1974                                crate::diagnostics::ElidedAnonymousLifetimeReportError {1975                                    span: lifetime.ident.span,1976                                    suggestion,1977                                },1978                            );1979                            self.suggest_introducing_lifetime_for_assoc_ty_binding(1980                                &mut err,1981                                lifetime.ident.span,1982                            );1983                            err.emit()1984                        } else {1985                            self.r.dcx().emit_err(1986                                crate::diagnostics::ElidedAnonymousLifetimeReportError {1987                                    span: lifetime.ident.span,1988                                    suggestion,1989                                },1990                            )1991                        }1992                    } else {1993                        self.r.dcx().emit_err(1994                            crate::diagnostics::ExplicitAnonymousLifetimeReportError {1995                                span: lifetime.ident.span,1996                            },1997                        )1998                    };1999                    self.record_lifetime_err(lifetime.id, guar);2000                    return;

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.