compiler/rustc_resolve/src/late.rs RUST 5,672 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 5,672.
1// ignore-tidy-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, TraitCandidate};31use rustc_middle::middle::resolve_bound_vars::Set1;32use rustc_middle::ty::{AssocTag, DelegationInfo, Visibility};33use rustc_middle::{bug, span_bug};34use rustc_session::config::{CrateType, ResolveDocLinks};35use rustc_session::errors::feature_err;36use rustc_session::lint;37use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Spanned, Symbol, kw, respan, sym};38use smallvec::{SmallVec, smallvec};39use thin_vec::ThinVec;40use tracing::{debug, instrument, trace};4142use crate::{43    BindingError, BindingKey, Decl, DelegationFnSig, Finalize, IdentKey, LateDecl, LocalModule,44    Module, ModuleOrUniformRoot, ParentScope, PathResult, Res, ResolutionError, Resolver, Segment,45    Stage, TyCtxt, UseError, Used, errors, path_names_to_string, rustdoc,46};4748mod diagnostics;4950use diagnostics::{ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime};5152#[derive(Copy, Clone, Debug)]53struct BindingInfo {54    span: Span,55    annotation: BindingMode,56}5758#[derive(Copy, Clone, PartialEq, Eq, Debug)]59pub(crate) enum PatternSource {60    Match,61    Let,62    For,63    FnParam,64}6566#[derive(Copy, Clone, Debug, PartialEq, Eq)]67enum IsRepeatExpr {68    No,69    Yes,70}7172struct IsNeverPattern;7374/// Describes whether an `AnonConst` is a type level const arg or75/// some other form of anon const (i.e. inline consts or enum discriminants)76#[derive(Copy, Clone, Debug, PartialEq, Eq)]77enum AnonConstKind {78    EnumDiscriminant,79    FieldDefaultValue,80    InlineConst,81    ConstArg(IsRepeatExpr),82}8384impl PatternSource {85    fn descr(self) -> &'static str {86        match self {87            PatternSource::Match => "match binding",88            PatternSource::Let => "let binding",89            PatternSource::For => "for binding",90            PatternSource::FnParam => "function parameter",91        }92    }93}9495impl IntoDiagArg for PatternSource {96    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {97        DiagArgValue::Str(Cow::Borrowed(self.descr()))98    }99}100101/// Denotes whether the context for the set of already bound bindings is a `Product`102/// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.103/// See those functions for more information.104#[derive(PartialEq)]105enum PatBoundCtx {106    /// A product pattern context, e.g., `Variant(a, b)`.107    Product,108    /// An or-pattern context, e.g., `p_0 | ... | p_n`.109    Or,110}111112/// Tracks bindings resolved within a pattern. This serves two purposes:113///114/// - This tracks when identifiers are bound multiple times within a pattern. In a product context,115///   this is an error. In an or-pattern, this lets us reuse the same resolution for each instance.116///   See `fresh_binding` and `resolve_pattern_inner` for more information.117///118/// - The guard expression of a guard pattern may use bindings from within the guard pattern, but119///   not from elsewhere in the pattern containing it. This allows us to isolate the bindings in the120///   subpattern to construct the scope for the guard.121///122/// Each identifier must map to at most one distinct [`Res`].123type PatternBindings = SmallVec<[(PatBoundCtx, FxIndexMap<Ident, Res>); 1]>;124125/// Does this the item (from the item rib scope) allow generic parameters?126#[derive(Copy, Clone, Debug)]127pub(crate) enum HasGenericParams {128    Yes(Span),129    No,130}131132/// May this constant have generics?133#[derive(Copy, Clone, Debug, Eq, PartialEq)]134pub(crate) enum ConstantHasGenerics {135    Yes,136    No(NoConstantGenericsReason),137}138139impl ConstantHasGenerics {140    fn force_yes_if(self, b: bool) -> Self {141        if b { Self::Yes } else { self }142    }143}144145/// Reason for why an anon const is not allowed to reference generic parameters146#[derive(Copy, Clone, Debug, Eq, PartialEq)]147pub(crate) enum NoConstantGenericsReason {148    /// Const arguments are only allowed to use generic parameters when:149    /// - `feature(generic_const_exprs)` is enabled150    /// or151    /// - the const argument is a sole const generic parameter, i.e. `foo::<{ N }>()`152    ///153    /// If neither of the above are true then this is used as the cause.154    NonTrivialConstArg,155    /// Enum discriminants are not allowed to reference generic parameters ever, this156    /// is used when an anon const is in the following position:157    ///158    /// ```rust,compile_fail159    /// enum Foo<const N: isize> {160    ///     Variant = { N }, // this anon const is not allowed to use generics161    /// }162    /// ```163    IsEnumDiscriminant,164}165166#[derive(Copy, Clone, Debug, Eq, PartialEq)]167pub(crate) enum ConstantItemKind {168    Const,169    Static,170}171172impl ConstantItemKind {173    pub(crate) fn as_str(&self) -> &'static str {174        match self {175            Self::Const => "const",176            Self::Static => "static",177        }178    }179}180181#[derive(Debug, Copy, Clone, PartialEq, Eq)]182enum RecordPartialRes {183    Yes,184    No,185}186187/// The rib kind restricts certain accesses,188/// e.g. to a `Res::Local` of an outer item.189#[derive(Copy, Clone, Debug)]190pub(crate) enum RibKind<'ra> {191    /// No restriction needs to be applied.192    Normal,193194    /// We passed through an `ast::Block`.195    /// Behaves like `Normal`, but also partially like `Module` if the block contains items.196    /// `Block(None)` must be always processed in the same way as `Block(Some(module))`197    /// with empty `module`. The module can be `None` only because creation of some definitely198    /// empty modules is skipped as an optimization.199    Block(Option<LocalModule<'ra>>),200201    /// We passed through an impl or trait and are now in one of its202    /// methods or associated types. Allow references to ty params that impl or trait203    /// binds. Disallow any other upvars (including other ty params that are204    /// upvars).205    AssocItem,206207    /// We passed through a function, closure or coroutine signature. Disallow labels.208    FnOrCoroutine,209210    /// We passed through an item scope. Disallow upvars.211    Item(HasGenericParams, DefKind),212213    /// We're in a constant item. Can't refer to dynamic stuff.214    ///215    /// The item may reference generic parameters in trivial constant expressions.216    /// All other constants aren't allowed to use generic params at all.217    ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),218219    /// We passed through a module item.220    Module(LocalModule<'ra>),221222    /// We passed through a `macro_rules!` statement223    MacroDefinition(DefId),224225    /// All bindings in this rib are generic parameters that can't be used226    /// from the default of a generic parameter because they're not declared227    /// before said generic parameter. Also see the `visit_generics` override.228    ForwardGenericParamBan(ForwardGenericParamBanReason),229230    /// We are inside of the type of a const parameter. Can't refer to any231    /// parameters.232    ConstParamTy,233234    /// We are inside a `sym` inline assembly operand. Can only refer to235    /// globals.236    InlineAsmSym,237}238239#[derive(Copy, Clone, PartialEq, Eq, Debug)]240pub(crate) enum ForwardGenericParamBanReason {241    Default,242    ConstParamTy,243}244245impl RibKind<'_> {246    /// Whether this rib kind contains generic parameters, as opposed to local247    /// variables.248    pub(crate) fn contains_params(&self) -> bool {249        match self {250            RibKind::Normal251            | RibKind::Block(..)252            | RibKind::FnOrCoroutine253            | RibKind::ConstantItem(..)254            | RibKind::Module(_)255            | RibKind::MacroDefinition(_)256            | RibKind::InlineAsmSym => false,257            RibKind::ConstParamTy258            | RibKind::AssocItem259            | RibKind::Item(..)260            | RibKind::ForwardGenericParamBan(_) => true,261        }262    }263264    /// This rib forbids referring to labels defined in upwards ribs.265    fn is_label_barrier(self) -> bool {266        match self {267            RibKind::Normal | RibKind::MacroDefinition(..) => false,268            RibKind::FnOrCoroutine | RibKind::ConstantItem(..) => true,269            kind => bug!("unexpected rib kind: {kind:?}"),270        }271    }272}273274/// A single local scope.275///276/// A rib represents a scope names can live in. Note that these appear in many places, not just277/// around braces. At any place where the list of accessible names (of the given namespace)278/// changes or a new restrictions on the name accessibility are introduced, a new rib is put onto a279/// stack. This may be, for example, a `let` statement (because it introduces variables), a macro,280/// etc.281///282/// Different [rib kinds](enum@RibKind) are transparent for different names.283///284/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When285/// resolving, the name is looked up from inside out.286#[derive(Debug)]287pub(crate) struct Rib<'ra, R = Res> {288    pub bindings: FxIndexMap<Ident, R>,289    pub patterns_with_skipped_bindings: UnordMap<DefId, Vec<(Span, Result<(), ErrorGuaranteed>)>>,290    pub kind: RibKind<'ra>,291}292293impl<'ra, R> Rib<'ra, R> {294    fn new(kind: RibKind<'ra>) -> Rib<'ra, R> {295        Rib {296            bindings: Default::default(),297            patterns_with_skipped_bindings: Default::default(),298            kind,299        }300    }301}302303#[derive(Clone, Copy, Debug)]304enum LifetimeUseSet {305    One { use_span: Span, use_ctxt: visit::LifetimeCtxt },306    Many,307}308309#[derive(Copy, Clone, Debug)]310enum LifetimeRibKind {311    // -- Ribs introducing named lifetimes312    //313    /// This rib declares generic parameters.314    /// Only for this kind the `LifetimeRib::bindings` field can be non-empty.315    Generics { binder: NodeId, span: Span, kind: LifetimeBinderKind },316317    // -- Ribs introducing unnamed lifetimes318    //319    /// Create a new anonymous lifetime parameter and reference it.320    ///321    /// If `report_in_path`, report an error when encountering lifetime elision in a path:322    /// ```compile_fail323    /// struct Foo<'a> { x: &'a () }324    /// async fn foo(x: Foo) {}325    /// ```326    ///327    /// Note: the error should not trigger when the elided lifetime is in a pattern or328    /// expression-position path:329    /// ```330    /// struct Foo<'a> { x: &'a () }331    /// async fn foo(Foo { x: _ }: Foo<'_>) {}332    /// ```333    AnonymousCreateParameter { binder: NodeId, report_in_path: bool },334335    /// Replace all anonymous lifetimes by provided lifetime.336    Elided(LifetimeRes),337338    // -- Barrier ribs that stop lifetime lookup, or continue it but produce an error later.339    //340    /// Give a hard error when either `&` or `'_` is written. Used to341    /// rule out things like `where T: Foo<'_>`. Does not imply an342    /// error on default object bounds (e.g., `Box<dyn Foo>`).343    AnonymousReportError,344345    /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,346    /// otherwise give a warning that the previous behavior of introducing a new early-bound347    /// lifetime is a bug and will be removed (if `emit_lint` is enabled).348    StaticIfNoLifetimeInScope { lint_id: NodeId, emit_lint: bool },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}372373#[derive(Copy, Clone, Debug)]374enum LifetimeBinderKind {375    FnPtrType,376    PolyTrait,377    WhereBound,378    // Item covers foreign items, ADTs, type aliases, trait associated items and379    // trait alias associated items.380    Item,381    ConstItem,382    Function,383    Closure,384    ImplBlock,385    // Covers only `impl` associated types.386    ImplAssocType,387}388389impl LifetimeBinderKind {390    fn descr(self) -> &'static str {391        use LifetimeBinderKind::*;392        match self {393            FnPtrType => "type",394            PolyTrait => "bound",395            WhereBound => "bound",396            Item | ConstItem => "item",397            ImplAssocType => "associated type",398            ImplBlock => "impl block",399            Function => "function",400            Closure => "closure",401        }402    }403}404405#[derive(Debug)]406struct LifetimeRib {407    kind: LifetimeRibKind,408    // We need to preserve insertion order for async fns.409    bindings: FxIndexMap<Ident, (NodeId, LifetimeRes)>,410}411412impl LifetimeRib {413    fn new(kind: LifetimeRibKind) -> LifetimeRib {414        LifetimeRib { bindings: Default::default(), kind }415    }416}417418#[derive(Copy, Clone, PartialEq, Eq, Debug)]419pub(crate) enum AliasPossibility {420    No,421    Maybe,422}423424#[derive(Copy, Clone, Debug)]425pub(crate) enum PathSource<'a, 'ast, 'ra> {426    /// Type paths `Path`.427    Type,428    /// Trait paths in bounds or impls.429    Trait(AliasPossibility),430    /// Expression paths `path`, with optional parent context.431    Expr(Option<&'ast Expr>),432    /// Paths in path patterns `Path`.433    Pat,434    /// Paths in struct expressions and patterns `Path { .. }`.435    Struct(Option<&'a Expr>),436    /// Paths in tuple struct patterns `Path(..)`.437    TupleStruct(Span, &'ra [Span]),438    /// `m::A::B` in `<T as m::A>::B::C`.439    ///440    /// Second field holds the "cause" of this one, i.e. the context within441    /// which the trait item is resolved. Used for diagnostics.442    TraitItem(Namespace, &'a PathSource<'a, 'ast, 'ra>),443    /// Paths in delegation item444    Delegation,445    /// Paths in externally implementable item declarations.446    ExternItemImpl,447    /// An arg in a `use<'a, N>` precise-capturing bound.448    PreciseCapturingArg(Namespace),449    /// Paths that end with `(..)`, for return type notation.450    ReturnTypeNotation,451    /// Paths from `#[define_opaque]` attributes452    DefineOpaques,453    /// Resolving a macro454    Macro,455    /// Paths for module or crate root. Used for restrictions.456    Module,457}458459impl PathSource<'_, '_, '_> {460    fn namespace(self) -> Namespace {461        match self {462            PathSource::Type463            | PathSource::Trait(_)464            | PathSource::Struct(_)465            | PathSource::DefineOpaques466            | PathSource::Module => TypeNS,467            PathSource::Expr(..)468            | PathSource::Pat469            | PathSource::TupleStruct(..)470            | PathSource::Delegation471            | PathSource::ExternItemImpl472            | PathSource::ReturnTypeNotation => ValueNS,473            PathSource::TraitItem(ns, _) => ns,474            PathSource::PreciseCapturingArg(ns) => ns,475            PathSource::Macro => MacroNS,476        }477    }478479    fn defer_to_typeck(self) -> bool {480        match self {481            PathSource::Type482            | PathSource::Expr(..)483            | PathSource::Pat484            | PathSource::Struct(_)485            | PathSource::TupleStruct(..)486            | PathSource::ReturnTypeNotation => true,487            PathSource::Trait(_)488            | PathSource::TraitItem(..)489            | PathSource::DefineOpaques490            | PathSource::Delegation491            | PathSource::ExternItemImpl492            | PathSource::PreciseCapturingArg(..)493            | PathSource::Macro494            | PathSource::Module => false,495        }496    }497498    fn descr_expected(self) -> &'static str {499        match &self {500            PathSource::DefineOpaques => "type alias or associated type with opaqaue types",501            PathSource::Type => "type",502            PathSource::Trait(_) => "trait",503            PathSource::Pat => "unit struct, unit variant or constant",504            PathSource::Struct(_) => "struct, variant or union type",505            PathSource::TraitItem(ValueNS, PathSource::TupleStruct(..))506            | PathSource::TupleStruct(..) => "tuple struct or tuple variant",507            PathSource::TraitItem(ns, _) => match ns {508                TypeNS => "associated type",509                ValueNS => "method or associated constant",510                MacroNS => bug!("associated macro"),511            },512            PathSource::Expr(parent) => match parent.as_ref().map(|p| &p.kind) {513                // "function" here means "anything callable" rather than `DefKind::Fn`,514                // this is not precise but usually more helpful than just "value".515                Some(ExprKind::Call(call_expr, _)) => match &call_expr.kind {516                    // the case of `::some_crate()`517                    ExprKind::Path(_, path)518                        if let [segment, _] = path.segments.as_slice()519                            && segment.ident.name == kw::PathRoot =>520                    {521                        "external crate"522                    }523                    ExprKind::Path(_, path)524                        if let Some(segment) = path.segments.last()525                            && let Some(c) = segment.ident.to_string().chars().next()526                            && c.is_uppercase() =>527                    {528                        "function, tuple struct or tuple variant"529                    }530                    _ => "function",531                },532                _ => "value",533            },534            PathSource::ReturnTypeNotation | PathSource::Delegation => "function",535            PathSource::ExternItemImpl => "function or static",536            PathSource::PreciseCapturingArg(..) => "type or const parameter",537            PathSource::Macro => "macro",538            PathSource::Module => "module",539        }540    }541542    fn is_call(self) -> bool {543        matches!(self, PathSource::Expr(Some(&Expr { kind: ExprKind::Call(..), .. })))544    }545546    pub(crate) fn is_expected(self, res: Res) -> bool {547        match self {548            PathSource::DefineOpaques => {549                matches!(550                    res,551                    Res::Def(552                        DefKind::Struct553                            | DefKind::Union554                            | DefKind::Enum555                            | DefKind::TyAlias556                            | DefKind::AssocTy,557                        _558                    ) | Res::SelfTyAlias { .. }559                )560            }561            PathSource::Type => matches!(562                res,563                Res::Def(564                    DefKind::Struct565                        | DefKind::Union566                        | DefKind::Enum567                        | DefKind::Trait568                        | DefKind::TraitAlias569                        | DefKind::TyAlias570                        | DefKind::AssocTy571                        | DefKind::TyParam572                        | DefKind::OpaqueTy573                        | DefKind::ForeignTy,574                    _,575                ) | Res::PrimTy(..)576                    | Res::SelfTyParam { .. }577                    | Res::SelfTyAlias { .. }578            ),579            PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),580            PathSource::Trait(AliasPossibility::Maybe) => {581                matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))582            }583            PathSource::Expr(..) => matches!(584                res,585                Res::Def(586                    DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn)587                        | DefKind::Const { .. }588                        | DefKind::Static { .. }589                        | DefKind::Fn590                        | DefKind::AssocFn591                        | DefKind::AssocConst { .. }592                        | DefKind::ConstParam,593                    _,594                ) | Res::Local(..)595                    | Res::SelfCtor(..)596            ),597            PathSource::Pat => {598                res.expected_in_unit_struct_pat()599                    || matches!(600                        res,601                        Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, _)602                    )603            }604            PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),605            PathSource::Struct(_) => matches!(606                res,607                Res::Def(608                    DefKind::Struct609                        | DefKind::Union610                        | DefKind::Variant611                        | DefKind::TyAlias612                        | DefKind::AssocTy,613                    _,614                ) | Res::SelfTyParam { .. }615                    | Res::SelfTyAlias { .. }616            ),617            PathSource::TraitItem(ns, _) => match res {618                Res::Def(DefKind::AssocConst { .. } | DefKind::AssocFn, _) if ns == ValueNS => true,619                Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,620                _ => false,621            },622            PathSource::ReturnTypeNotation => match res {623                Res::Def(DefKind::AssocFn, _) => true,624                _ => false,625            },626            PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),627            PathSource::ExternItemImpl => {628                matches!(629                    res,630                    Res::Def(631                        DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Static { .. },632                        _633                    )634                )635            }636            PathSource::PreciseCapturingArg(ValueNS) => {637                matches!(res, Res::Def(DefKind::ConstParam, _))638            }639            // We allow `SelfTyAlias` here so we can give a more descriptive error later.640            PathSource::PreciseCapturingArg(TypeNS) => matches!(641                res,642                Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }643            ),644            PathSource::PreciseCapturingArg(MacroNS) => false,645            PathSource::Macro => matches!(res, Res::Def(DefKind::Macro(_), _)),646            PathSource::Module => matches!(res, Res::Def(DefKind::Mod, _)),647        }648    }649650    fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {651        match (self, has_unexpected_resolution) {652            (PathSource::Trait(_), true) => E0404,653            (PathSource::Trait(_), false) => E0405,654            (PathSource::Type | PathSource::DefineOpaques, true) => E0573,655            (PathSource::Type | PathSource::DefineOpaques, false) => E0425,656            (PathSource::Struct(_), true) => E0574,657            (PathSource::Struct(_), false) => E0422,658            (PathSource::Expr(..), true)659            | (PathSource::Delegation, true)660            | (PathSource::ExternItemImpl, true) => E0423,661            (PathSource::Expr(..), false)662            | (PathSource::Delegation, false)663            | (PathSource::ExternItemImpl, false) => E0425,664            (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,665            (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,666            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, true) => E0575,667            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, false) => E0576,668            (PathSource::PreciseCapturingArg(..), true) => E0799,669            (PathSource::PreciseCapturingArg(..), false) => E0800,670            (PathSource::Macro, _) => E0425,671            // FIXME: There is no dedicated error code for this case yet.672            // E0577 already covers the same situation for visibilities,673            // so we reuse it here for now. It may make sense to generalize674            // it for restrictions in the future.675            (PathSource::Module, true) => E0577,676            (PathSource::Module, false) => E0433,677        }678    }679}680681/// At this point for most items we can answer whether that item is exported or not,682/// but some items like impls require type information to determine exported-ness, so we make a683/// conservative estimate for them (e.g. based on nominal visibility).684#[derive(Clone, Copy)]685enum MaybeExported<'a> {686    Ok(NodeId),687    Impl(Option<DefId>),688    ImplItem(Result<DefId, &'a ast::Visibility>),689    NestedUse(&'a ast::Visibility),690}691692impl MaybeExported<'_> {693    fn eval(self, r: &Resolver<'_, '_>) -> bool {694        let def_id = match self {695            MaybeExported::Ok(node_id) => Some(r.local_def_id(node_id)),696            MaybeExported::Impl(Some(trait_def_id)) | MaybeExported::ImplItem(Ok(trait_def_id)) => {697                trait_def_id.as_local()698            }699            MaybeExported::Impl(None) => return true,700            MaybeExported::ImplItem(Err(vis)) | MaybeExported::NestedUse(vis) => {701                return vis.kind.is_pub();702            }703        };704        def_id.is_none_or(|def_id| r.effective_visibilities.is_exported(def_id))705    }706}707708/// Used for recording UnnecessaryQualification.709#[derive(Debug)]710pub(crate) struct UnnecessaryQualification<'ra> {711    pub decl: LateDecl<'ra>,712    pub node_id: NodeId,713    pub path_span: Span,714    pub removal_span: Span,715}716717#[derive(Default, Debug)]718pub(crate) struct DiagMetadata<'ast> {719    /// The current trait's associated items' ident, used for diagnostic suggestions.720    current_trait_assoc_items: Option<&'ast [Box<AssocItem>]>,721722    /// The current self type if inside an impl (used for better errors).723    pub(crate) current_self_type: Option<Ty>,724725    /// The current self item if inside an ADT (used for better errors).726    current_self_item: Option<NodeId>,727728    /// The current item being evaluated (used for suggestions and more detail in errors).729    pub(crate) current_item: Option<&'ast Item>,730731    /// When processing generic arguments and encountering an unresolved ident not found,732    /// suggest introducing a type or const param depending on the context.733    currently_processing_generic_args: bool,734735    /// The current enclosing (non-closure) function (used for better errors).736    current_function: Option<(FnKind<'ast>, Span)>,737738    /// A list of labels as of yet unused. Labels will be removed from this map when739    /// they are used (in a `break` or `continue` statement)740    unused_labels: FxIndexMap<NodeId, Span>,741742    /// Only used for better errors on `let <pat>: <expr, not type>;`.743    current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,744745    current_pat: Option<&'ast Pat>,746747    /// Used to detect possible `if let` written without `let` and to provide structured suggestion.748    in_if_condition: Option<&'ast Expr>,749750    /// Used to detect possible new binding written without `let` and to provide structured suggestion.751    in_assignment: Option<&'ast Expr>,752    is_assign_rhs: bool,753754    /// If we are setting an associated type in trait impl, is it a non-GAT type?755    in_non_gat_assoc_type: Option<bool>,756757    /// Used to detect possible `.` -> `..` typo when calling methods.758    in_range: Option<(&'ast Expr, &'ast Expr)>,759760    /// If we are currently in a trait object definition. Used to point at the bounds when761    /// encountering a struct or enum.762    current_trait_object: Option<&'ast [ast::GenericBound]>,763764    /// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.765    current_where_predicate: Option<&'ast WherePredicate>,766767    current_type_path: Option<&'ast Ty>,768769    /// The current impl items (used to suggest).770    current_impl_items: Option<&'ast [Box<AssocItem>]>,771772    /// The current impl items (used to suggest).773    current_impl_item: Option<&'ast AssocItem>,774775    /// When processing impl trait776    currently_processing_impl_trait: Option<(TraitRef, Ty)>,777778    /// Accumulate the errors due to missed lifetime elision,779    /// and report them all at once for each function.780    current_elision_failures:781        Vec<(MissingLifetime, LifetimeElisionCandidate, Either<NodeId, Range<NodeId>>)>,782}783784struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {785    r: &'a mut Resolver<'ra, 'tcx>,786787    /// The module that represents the current item scope.788    parent_scope: ParentScope<'ra>,789790    /// The current set of local scopes for types and values.791    ribs: PerNS<Vec<Rib<'ra>>>,792793    /// Previous popped `rib`, only used for diagnostic.794    last_block_rib: Option<Rib<'ra>>,795796    /// The current set of local scopes, for labels.797    label_ribs: Vec<Rib<'ra, NodeId>>,798799    /// The current set of local scopes for lifetimes.800    lifetime_ribs: Vec<LifetimeRib>,801802    /// We are looking for lifetimes in an elision context.803    /// The set contains all the resolutions that we encountered so far.804    /// They will be used to determine the correct lifetime for the fn return type.805    /// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named806    /// lifetimes.807    lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,808809    /// The trait that the current context can refer to.810    current_trait_ref: Option<(Module<'ra>, TraitRef)>,811812    /// Fields used to add information to diagnostic errors.813    diag_metadata: Box<DiagMetadata<'ast>>,814815    /// State used to know whether to ignore resolution errors for function bodies.816    ///817    /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items.818    /// In most cases this will be `None`, in which case errors will always be reported.819    /// If it is `true`, then it will be updated when entering a nested function or trait body.820    in_func_body: bool,821822    /// Count the number of places a lifetime is used.823    lifetime_uses: FxHashMap<LocalDefId, LifetimeUseSet>,824}825826/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.827impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {828    fn visit_attribute(&mut self, _: &'ast Attribute) {829        // We do not want to resolve expressions that appear in attributes,830        // as they do not correspond to actual code.831    }832    fn visit_item(&mut self, item: &'ast Item) {833        let prev = replace(&mut self.diag_metadata.current_item, Some(item));834        // Always report errors in items we just entered.835        let old_ignore = replace(&mut self.in_func_body, false);836        self.with_lifetime_rib(LifetimeRibKind::Item, |this| this.resolve_item(item));837        self.in_func_body = old_ignore;838        self.diag_metadata.current_item = prev;839    }840    fn visit_arm(&mut self, arm: &'ast Arm) {841        self.resolve_arm(arm);842    }843    fn visit_block(&mut self, block: &'ast Block) {844        let old_macro_rules = self.parent_scope.macro_rules;845        self.resolve_block(block);846        self.parent_scope.macro_rules = old_macro_rules;847    }848    fn visit_anon_const(&mut self, constant: &'ast AnonConst) {849        bug!("encountered anon const without a manual call to `resolve_anon_const`: {constant:#?}");850    }851    fn visit_expr(&mut self, expr: &'ast Expr) {852        self.resolve_expr(expr, None);853    }854    fn visit_pat(&mut self, p: &'ast Pat) {855        let prev = self.diag_metadata.current_pat;856        self.diag_metadata.current_pat = Some(p);857858        if let PatKind::Guard(subpat, _) = &p.kind {859            // We walk the guard expression in `resolve_pattern_inner`. Don't resolve it twice.860            self.visit_pat(subpat);861        } else {862            visit::walk_pat(self, p);863        }864865        self.diag_metadata.current_pat = prev;866    }867    fn visit_local(&mut self, local: &'ast Local) {868        let local_spans = match local.pat.kind {869            // We check for this to avoid tuple struct fields.870            PatKind::Wild => None,871            _ => Some((872                local.pat.span,873                local.ty.as_ref().map(|ty| ty.span),874                local.kind.init().map(|init| init.span),875            )),876        };877        let original = replace(&mut self.diag_metadata.current_let_binding, local_spans);878        self.resolve_local(local);879        self.diag_metadata.current_let_binding = original;880    }881    fn visit_ty(&mut self, ty: &'ast Ty) {882        let prev = self.diag_metadata.current_trait_object;883        let prev_ty = self.diag_metadata.current_type_path;884        match &ty.kind {885            TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => {886                // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with887                // NodeId `ty.id`.888                // This span will be used in case of elision failure.889                let span = self.r.tcx.sess.source_map().start_point(ty.span);890                self.resolve_elided_lifetime(ty.id, span);891                visit::walk_ty(self, ty);892            }893            TyKind::Path(qself, path) => {894                self.diag_metadata.current_type_path = Some(ty);895896                // If we have a path that ends with `(..)`, then it must be897                // return type notation. Resolve that path in the *value*898                // namespace.899                let source = if let Some(seg) = path.segments.last()900                    && let Some(args) = &seg.args901                    && matches!(**args, GenericArgs::ParenthesizedElided(..))902                {903                    PathSource::ReturnTypeNotation904                } else {905                    PathSource::Type906                };907908                self.smart_resolve_path(ty.id, qself, path, source);909910                // Check whether we should interpret this as a bare trait object.911                if qself.is_none()912                    && let Some(partial_res) = self.r.partial_res_map.get(&ty.id)913                    && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) =914                        partial_res.full_res()915                {916                    // This path is actually a bare trait object. In case of a bare `Fn`-trait917                    // object with anonymous lifetimes, we need this rib to correctly place the918                    // synthetic lifetimes.919                    let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo());920                    self.with_generic_param_rib(921                        &[],922                        RibKind::Normal,923                        ty.id,924                        LifetimeBinderKind::PolyTrait,925                        span,926                        |this| this.visit_path(path),927                    );928                } else {929                    visit::walk_ty(self, ty)930                }931            }932            TyKind::ImplicitSelf => {933                let self_ty = Ident::with_dummy_span(kw::SelfUpper);934                let res = self935                    .resolve_ident_in_lexical_scope(936                        self_ty,937                        TypeNS,938                        Some(Finalize::new(ty.id, ty.span)),939                        None,940                    )941                    .map_or(Res::Err, |d| d.res());942                self.r.record_partial_res(ty.id, PartialRes::new(res));943                visit::walk_ty(self, ty)944            }945            TyKind::ImplTrait(..) => {946                let candidates = self.lifetime_elision_candidates.take();947                self.with_lifetime_rib(LifetimeRibKind::ImplTrait, |this| visit::walk_ty(this, ty));948                self.lifetime_elision_candidates = candidates;949            }950            TyKind::TraitObject(bounds, ..) => {951                self.diag_metadata.current_trait_object = Some(&bounds[..]);952                visit::walk_ty(self, ty)953            }954            TyKind::FnPtr(fn_ptr) => {955                let span = ty.span.shrink_to_lo().to(fn_ptr.decl_span.shrink_to_lo());956                self.with_generic_param_rib(957                    &fn_ptr.generic_params,958                    RibKind::Normal,959                    ty.id,960                    LifetimeBinderKind::FnPtrType,961                    span,962                    |this| {963                        this.visit_generic_params(&fn_ptr.generic_params, false);964                        this.resolve_fn_signature(965                            ty.id,966                            false,967                            // We don't need to deal with patterns in parameters, because968                            // they are not possible for foreign or bodiless functions.969                            fn_ptr.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),970                            &fn_ptr.decl.output,971                            false,972                        )973                    },974                )975            }976            TyKind::UnsafeBinder(unsafe_binder) => {977                let span = ty.span.shrink_to_lo().to(unsafe_binder.inner_ty.span.shrink_to_lo());978                self.with_generic_param_rib(979                    &unsafe_binder.generic_params,980                    RibKind::Normal,981                    ty.id,982                    LifetimeBinderKind::FnPtrType,983                    span,984                    |this| {985                        this.visit_generic_params(&unsafe_binder.generic_params, false);986                        this.with_lifetime_rib(987                            // We don't allow anonymous `unsafe &'_ ()` binders,988                            // although I guess we could.989                            LifetimeRibKind::AnonymousReportError,990                            |this| this.visit_ty(&unsafe_binder.inner_ty),991                        );992                    },993                )994            }995            TyKind::Array(element_ty, length) => {996                self.visit_ty(element_ty);997                self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));998            }999            _ => visit::walk_ty(self, ty),1000        }1001        self.diag_metadata.current_trait_object = prev;1002        self.diag_metadata.current_type_path = prev_ty;1003    }10041005    fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {1006        match &t.kind {1007            TyPatKind::Range(start, end, _) => {1008                if let Some(start) = start {1009                    self.resolve_anon_const(start, AnonConstKind::ConstArg(IsRepeatExpr::No));1010                }1011                if let Some(end) = end {1012                    self.resolve_anon_const(end, AnonConstKind::ConstArg(IsRepeatExpr::No));1013                }1014            }1015            TyPatKind::Or(patterns) => {1016                for pat in patterns {1017                    self.visit_ty_pat(pat)1018                }1019            }1020            TyPatKind::NotNull | TyPatKind::Err(_) => {}1021        }1022    }10231024    fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {1025        let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());1026        self.with_generic_param_rib(1027            &tref.bound_generic_params,1028            RibKind::Normal,1029            tref.trait_ref.ref_id,1030            LifetimeBinderKind::PolyTrait,1031            span,1032            |this| {1033                this.visit_generic_params(&tref.bound_generic_params, false);1034                this.smart_resolve_path(1035                    tref.trait_ref.ref_id,1036                    &None,1037                    &tref.trait_ref.path,1038                    PathSource::Trait(AliasPossibility::Maybe),1039                );1040                this.visit_trait_ref(&tref.trait_ref);1041            },1042        );1043    }1044    fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {1045        self.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id));1046        let def_kind = self.r.local_def_kind(foreign_item.id);1047        match foreign_item.kind {1048            ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {1049                self.with_generic_param_rib(1050                    &generics.params,1051                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),1052                    foreign_item.id,1053                    LifetimeBinderKind::Item,1054                    generics.span,1055                    |this| visit::walk_item(this, foreign_item),1056                );1057            }1058            ForeignItemKind::Fn(box Fn { ref generics, .. }) => {1059                self.with_generic_param_rib(1060                    &generics.params,1061                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),1062                    foreign_item.id,1063                    LifetimeBinderKind::Function,1064                    generics.span,1065                    |this| visit::walk_item(this, foreign_item),1066                );1067            }1068            ForeignItemKind::Static(..) => {1069                self.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item))1070            }1071            ForeignItemKind::MacCall(..) => {1072                panic!("unexpanded macro in resolve!")1073            }1074        }1075    }1076    fn visit_fn(&mut self, fn_kind: FnKind<'ast>, _: &AttrVec, sp: Span, fn_id: NodeId) {1077        let previous_value = self.diag_metadata.current_function;1078        match fn_kind {1079            // Bail if the function is foreign, and thus cannot validly have1080            // a body, or if there's no body for some other reason.1081            FnKind::Fn(FnCtxt::Foreign, _, Fn { sig, ident, generics, .. })1082            | FnKind::Fn(_, _, Fn { sig, ident, generics, body: None, .. }) => {1083                self.visit_fn_header(&sig.header);1084                self.visit_ident(ident);1085                self.visit_generics(generics);1086                self.resolve_fn_signature(1087                    fn_id,1088                    sig.decl.has_self(),1089                    sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),1090                    &sig.decl.output,1091                    false,1092                );1093                return;1094            }1095            FnKind::Fn(..) => {1096                self.diag_metadata.current_function = Some((fn_kind, sp));1097            }1098            // Do not update `current_function` for closures: it suggests `self` parameters.1099            FnKind::Closure(..) => {}1100        };1101        debug!("(resolving function) entering function");11021103        if let FnKind::Fn(_, _, f) = fn_kind {1104            self.resolve_eii(&f.eii_impls);1105        }11061107        // Create a value rib for the function.1108        self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {1109            // Create a label rib for the function.1110            this.with_label_rib(RibKind::FnOrCoroutine, |this| {1111                match fn_kind {1112                    FnKind::Fn(_, _, Fn { sig, generics, contract, body, .. }) => {1113                        this.visit_generics(generics);11141115                        let declaration = &sig.decl;1116                        let coro_node_id = sig1117                            .header1118                            .coroutine_kind1119                            .map(|coroutine_kind| coroutine_kind.return_id());11201121                        this.resolve_fn_signature(1122                            fn_id,1123                            declaration.has_self(),1124                            declaration1125                                .inputs1126                                .iter()1127                                .map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)),1128                            &declaration.output,1129                            coro_node_id.is_some(),1130                        );11311132                        if let Some(contract) = contract {1133                            this.visit_contract(contract);1134                        }11351136                        if let Some(body) = body {1137                            // Ignore errors in function bodies if this is rustdoc1138                            // Be sure not to set this until the function signature has been resolved.1139                            let previous_state = replace(&mut this.in_func_body, true);1140                            // We only care block in the same function1141                            this.last_block_rib = None;1142                            // Resolve the function body, potentially inside the body of an async closure1143                            this.with_lifetime_rib(1144                                LifetimeRibKind::Elided(LifetimeRes::Infer),1145                                |this| this.visit_block(body),1146                            );11471148                            debug!("(resolving function) leaving function");1149                            this.in_func_body = previous_state;1150                        }1151                    }1152                    FnKind::Closure(binder, _, declaration, body) => {1153                        this.visit_closure_binder(binder);11541155                        this.with_lifetime_rib(1156                            match binder {1157                                // We do not have any explicit generic lifetime parameter.1158                                ClosureBinder::NotPresent => {1159                                    LifetimeRibKind::AnonymousCreateParameter {1160                                        binder: fn_id,1161                                        report_in_path: false,1162                                    }1163                                }1164                                ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,1165                            },1166                            // Add each argument to the rib.1167                            |this| this.resolve_params(&declaration.inputs),1168                        );1169                        this.with_lifetime_rib(1170                            match binder {1171                                ClosureBinder::NotPresent => {1172                                    LifetimeRibKind::Elided(LifetimeRes::Infer)1173                                }1174                                ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,1175                            },1176                            |this| visit::walk_fn_ret_ty(this, &declaration.output),1177                        );11781179                        // Ignore errors in function bodies if this is rustdoc1180                        // Be sure not to set this until the function signature has been resolved.1181                        let previous_state = replace(&mut this.in_func_body, true);1182                        // Resolve the function body, potentially inside the body of an async closure1183                        this.with_lifetime_rib(1184                            LifetimeRibKind::Elided(LifetimeRes::Infer),1185                            |this| this.visit_expr(body),1186                        );11871188                        debug!("(resolving function) leaving function");1189                        this.in_func_body = previous_state;1190                    }1191                }1192            })1193        });1194        self.diag_metadata.current_function = previous_value;1195    }11961197    fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {1198        self.resolve_lifetime(lifetime, use_ctxt)1199    }12001201    fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {1202        match arg {1203            // Lower the lifetime regularly; we'll resolve the lifetime and check1204            // it's a parameter later on in HIR lowering.1205            PreciseCapturingArg::Lifetime(_) => {}12061207            PreciseCapturingArg::Arg(path, id) => {1208                // we want `impl use<C>` to try to resolve `C` as both a type parameter or1209                // a const parameter. Since the resolver specifically doesn't allow having1210                // two generic params with the same name, even if they're a different namespace,1211                // it doesn't really matter which we try resolving first, but just like1212                // `Ty::Param` we just fall back to the value namespace only if it's missing1213                // from the type namespace.1214                let mut check_ns = |ns| {1215                    self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some()1216                };1217                // Like `Ty::Param`, we try resolving this as both a const and a type.1218                if !check_ns(TypeNS) && check_ns(ValueNS) {1219                    self.smart_resolve_path(1220                        *id,1221                        &None,1222                        path,1223                        PathSource::PreciseCapturingArg(ValueNS),1224                    );1225                } else {1226                    self.smart_resolve_path(1227                        *id,1228                        &None,1229                        path,1230                        PathSource::PreciseCapturingArg(TypeNS),1231                    );1232                }1233            }1234        }12351236        visit::walk_precise_capturing_arg(self, arg)1237    }12381239    fn visit_generics(&mut self, generics: &'ast Generics) {1240        self.visit_generic_params(&generics.params, self.diag_metadata.current_self_item.is_some());1241        for p in &generics.where_clause.predicates {1242            self.visit_where_predicate(p);1243        }1244    }12451246    fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) {1247        match b {1248            ClosureBinder::NotPresent => {}1249            ClosureBinder::For { generic_params, .. } => {1250                self.visit_generic_params(1251                    generic_params,1252                    self.diag_metadata.current_self_item.is_some(),1253                );1254            }1255        }1256    }12571258    fn visit_generic_arg(&mut self, arg: &'ast GenericArg) {1259        debug!("visit_generic_arg({:?})", arg);1260        let prev = replace(&mut self.diag_metadata.currently_processing_generic_args, true);1261        match arg {1262            GenericArg::Type(ty) => {1263                // We parse const arguments as path types as we cannot distinguish them during1264                // parsing. We try to resolve that ambiguity by attempting resolution the type1265                // namespace first, and if that fails we try again in the value namespace. If1266                // resolution in the value namespace succeeds, we have an generic const argument on1267                // our hands.1268                if let TyKind::Path(None, ref path) = ty.kind1269                    // We cannot disambiguate multi-segment paths right now as that requires type1270                    // checking.1271                    && path.is_potential_trivial_const_arg()1272                {1273                    let mut check_ns = |ns| {1274                        self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)1275                            .is_some()1276                    };1277                    if !check_ns(TypeNS) && check_ns(ValueNS) {1278                        self.resolve_anon_const_manual(1279                            true,1280                            AnonConstKind::ConstArg(IsRepeatExpr::No),1281                            |this| {1282                                this.smart_resolve_path(ty.id, &None, path, PathSource::Expr(None));1283                                this.visit_path(path);1284                            },1285                        );12861287                        self.diag_metadata.currently_processing_generic_args = prev;1288                        return;1289                    }1290                }12911292                self.visit_ty(ty);1293            }1294            GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg),1295            GenericArg::Const(ct) => {1296                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))1297            }1298        }1299        self.diag_metadata.currently_processing_generic_args = prev;1300    }13011302    fn visit_assoc_item_constraint(&mut self, constraint: &'ast AssocItemConstraint) {1303        self.visit_ident(&constraint.ident);1304        if let Some(ref gen_args) = constraint.gen_args {1305            // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.1306            self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {1307                this.visit_generic_args(gen_args)1308            });1309        }1310        match constraint.kind {1311            AssocItemConstraintKind::Equality { ref term } => match term {1312                Term::Ty(ty) => self.visit_ty(ty),1313                Term::Const(c) => {1314                    self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))1315                }1316            },1317            AssocItemConstraintKind::Bound { ref bounds } => {1318                walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);1319            }1320        }1321    }13221323    fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {1324        let Some(ref args) = path_segment.args else {1325            return;1326        };13271328        match &**args {1329            GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),1330            GenericArgs::Parenthesized(p_args) => {1331                // Probe the lifetime ribs to know how to behave.1332                for rib in self.lifetime_ribs.iter().rev() {1333                    match rib.kind {1334                        // We are inside a `PolyTraitRef`. The lifetimes are1335                        // to be introduced in that (maybe implicit) `for<>` binder.1336                        LifetimeRibKind::Generics {1337                            binder,1338                            kind: LifetimeBinderKind::PolyTrait,1339                            ..1340                        } => {1341                            self.resolve_fn_signature(1342                                binder,1343                                false,1344                                p_args.inputs.iter().map(|ty| (None, &**ty)),1345                                &p_args.output,1346                                false,1347                            );1348                            break;1349                        }1350                        // We have nowhere to introduce generics. Code is malformed,1351                        // so use regular lifetime resolution to avoid spurious errors.1352                        LifetimeRibKind::Item | LifetimeRibKind::Generics { .. } => {1353                            visit::walk_generic_args(self, args);1354                            break;1355                        }1356                        LifetimeRibKind::AnonymousCreateParameter { .. }1357                        | LifetimeRibKind::AnonymousReportError1358                        | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }1359                        | LifetimeRibKind::ImplTrait1360                        | LifetimeRibKind::Elided(_)1361                        | LifetimeRibKind::ElisionFailure1362                        | LifetimeRibKind::ConcreteAnonConst(_)1363                        | LifetimeRibKind::ConstParamTy => {}1364                    }1365                }1366            }1367            GenericArgs::ParenthesizedElided(_) => {}1368        }1369    }13701371    fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {1372        debug!("visit_where_predicate {:?}", p);1373        let previous_value = replace(&mut self.diag_metadata.current_where_predicate, Some(p));1374        self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {1375            if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {1376                bounded_ty,1377                bounds,1378                bound_generic_params,1379                ..1380            }) = &p.kind1381            {1382                let span = p.span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());1383                this.with_generic_param_rib(1384                    bound_generic_params,1385                    RibKind::Normal,1386                    bounded_ty.id,1387                    LifetimeBinderKind::WhereBound,1388                    span,1389                    |this| {1390                        this.visit_generic_params(bound_generic_params, false);1391                        this.visit_ty(bounded_ty);1392                        for bound in bounds {1393                            this.visit_param_bound(bound, BoundKind::Bound)1394                        }1395                    },1396                );1397            } else {1398                visit::walk_where_predicate(this, p);1399            }1400        });1401        self.diag_metadata.current_where_predicate = previous_value;1402    }14031404    fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) {1405        for (op, _) in &asm.operands {1406            match op {1407                InlineAsmOperand::In { expr, .. }1408                | InlineAsmOperand::Out { expr: Some(expr), .. }1409                | InlineAsmOperand::InOut { expr, .. } => self.visit_expr(expr),1410                InlineAsmOperand::Out { expr: None, .. } => {}1411                InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {1412                    self.visit_expr(in_expr);1413                    if let Some(out_expr) = out_expr {1414                        self.visit_expr(out_expr);1415                    }1416                }1417                InlineAsmOperand::Const { anon_const, .. } => {1418                    // Although this is `DefKind::AnonConst`, it is allowed to reference outer1419                    // generic parameters like an inline const.1420                    self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);1421                }1422                InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),1423                InlineAsmOperand::Label { block } => self.visit_block(block),1424            }1425        }1426    }14271428    fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {1429        // This is similar to the code for AnonConst.1430        self.with_rib(ValueNS, RibKind::InlineAsmSym, |this| {1431            this.with_rib(TypeNS, RibKind::InlineAsmSym, |this| {1432                this.with_label_rib(RibKind::InlineAsmSym, |this| {1433                    this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));1434                    visit::walk_inline_asm_sym(this, sym);1435                });1436            })1437        });1438    }14391440    fn visit_variant(&mut self, v: &'ast Variant) {1441        self.resolve_doc_links(&v.attrs, MaybeExported::Ok(v.id));1442        self.visit_id(v.id);1443        walk_list!(self, visit_attribute, &v.attrs);1444        self.visit_vis(&v.vis);1445        self.visit_ident(&v.ident);1446        self.visit_variant_data(&v.data);1447        if let Some(discr) = &v.disr_expr {1448            self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant);1449        }1450    }14511452    fn visit_field_def(&mut self, f: &'ast FieldDef) {1453        self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));1454        let FieldDef {1455            attrs,1456            id: _,1457            span: _,1458            vis,1459            ident,1460            ty,1461            is_placeholder: _,1462            default,1463            safety: _,1464        } = f;1465        walk_list!(self, visit_attribute, attrs);1466        try_visit!(self.visit_vis(vis));1467        visit_opt!(self, visit_ident, ident);1468        try_visit!(self.visit_ty(ty));1469        if let Some(v) = &default {1470            self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue);1471        }1472    }1473}14741475impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {1476    fn new(resolver: &'a mut Resolver<'ra, 'tcx>) -> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {1477        // During late resolution we only track the module component of the parent scope,1478        // although it may be useful to track other components as well for diagnostics.1479        let graph_root = resolver.graph_root;1480        let parent_scope = ParentScope::module(graph_root.to_module(), resolver.arenas);1481        let start_rib_kind = RibKind::Module(graph_root);1482        LateResolutionVisitor {1483            r: resolver,1484            parent_scope,1485            ribs: PerNS {1486                value_ns: vec![Rib::new(start_rib_kind)],1487                type_ns: vec![Rib::new(start_rib_kind)],1488                macro_ns: vec![Rib::new(start_rib_kind)],1489            },1490            last_block_rib: None,1491            label_ribs: Vec::new(),1492            lifetime_ribs: Vec::new(),1493            lifetime_elision_candidates: None,1494            current_trait_ref: None,1495            diag_metadata: Default::default(),1496            // errors at module scope should always be reported1497            in_func_body: false,1498            lifetime_uses: Default::default(),1499        }1500    }15011502    fn maybe_resolve_ident_in_lexical_scope(1503        &mut self,1504        ident: Ident,1505        ns: Namespace,1506    ) -> Option<LateDecl<'ra>> {1507        self.r.resolve_ident_in_lexical_scope(1508            ident,1509            ns,1510            &self.parent_scope,1511            None,1512            &self.ribs[ns],1513            None,1514            Some(&self.diag_metadata),1515        )1516    }15171518    fn resolve_ident_in_lexical_scope(1519        &mut self,1520        ident: Ident,1521        ns: Namespace,1522        finalize: Option<Finalize>,1523        ignore_decl: Option<Decl<'ra>>,1524    ) -> Option<LateDecl<'ra>> {1525        self.r.resolve_ident_in_lexical_scope(1526            ident,1527            ns,1528            &self.parent_scope,1529            finalize,1530            &self.ribs[ns],1531            ignore_decl,1532            Some(&self.diag_metadata),1533        )1534    }15351536    fn resolve_path(1537        &mut self,1538        path: &[Segment],1539        opt_ns: Option<Namespace>, // `None` indicates a module path in import1540        finalize: Option<Finalize>,1541        source: PathSource<'_, 'ast, 'ra>,1542    ) -> PathResult<'ra> {1543        self.r.cm().resolve_path_with_ribs(1544            path,1545            opt_ns,1546            &self.parent_scope,1547            Some(source),1548            finalize.map(|finalize| Finalize { stage: Stage::Late, ..finalize }),1549            Some(&self.ribs),1550            None,1551            None,1552            Some(&self.diag_metadata),1553        )1554    }15551556    // AST resolution1557    //1558    // We maintain a list of value ribs and type ribs.1559    //1560    // Simultaneously, we keep track of the current position in the module1561    // graph in the `parent_scope.module` pointer. When we go to resolve a name in1562    // the value or type namespaces, we first look through all the ribs and1563    // then query the module graph. When we resolve a name in the module1564    // namespace, we can skip all the ribs (since nested modules are not1565    // allowed within blocks in Rust) and jump straight to the current module1566    // graph node.1567    //1568    // Named implementations are handled separately. When we find a method1569    // call, we consult the module node to find all of the implementations in1570    // scope. This information is lazily cached in the module node. We then1571    // generate a fake "implementation scope" containing all the1572    // implementations thus found, for compatibility with old resolve pass.15731574    /// Do some `work` within a new innermost rib of the given `kind` in the given namespace (`ns`).1575    fn with_rib<T>(1576        &mut self,1577        ns: Namespace,1578        kind: RibKind<'ra>,1579        work: impl FnOnce(&mut Self) -> T,1580    ) -> T {1581        self.ribs[ns].push(Rib::new(kind));1582        let ret = work(self);1583        self.ribs[ns].pop();1584        ret1585    }15861587    fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper: bool) {1588        // For type parameter defaults, we have to ban access1589        // to following type parameters, as the GenericArgs can only1590        // provide previous type parameters as they're built. We1591        // put all the parameters on the ban list and then remove1592        // them one by one as they are processed and become available.1593        let mut forward_ty_ban_rib =1594            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));1595        let mut forward_const_ban_rib =1596            Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));1597        for param in params.iter() {1598            match param.kind {1599                GenericParamKind::Type { .. } => {1600                    forward_ty_ban_rib1601                        .bindings1602                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);1603                }1604                GenericParamKind::Const { .. } => {1605                    forward_const_ban_rib1606                        .bindings1607                        .insert(Ident::with_dummy_span(param.ident.name), Res::Err);1608                }1609                GenericParamKind::Lifetime => {}1610            }1611        }16121613        // rust-lang/rust#61631: The type `Self` is essentially1614        // another type parameter. For ADTs, we consider it1615        // well-defined only after all of the ADT type parameters have1616        // been provided. Therefore, we do not allow use of `Self`1617        // anywhere in ADT type parameter defaults.1618        //1619        // (We however cannot ban `Self` for defaults on *all* generic1620        // lists; e.g. trait generics can usefully refer to `Self`,1621        // such as in the case of `trait Add<Rhs = Self>`.)1622        if add_self_upper {1623            // (`Some` if + only if we are in ADT's generics.)1624            forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);1625        }16261627        // NOTE: We use different ribs here not for a technical reason, but just1628        // for better diagnostics.1629        let mut forward_ty_ban_rib_const_param_ty = Rib {1630            bindings: forward_ty_ban_rib.bindings.clone(),1631            patterns_with_skipped_bindings: Default::default(),1632            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),1633        };1634        let mut forward_const_ban_rib_const_param_ty = Rib {1635            bindings: forward_const_ban_rib.bindings.clone(),1636            patterns_with_skipped_bindings: Default::default(),1637            kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),1638        };1639        // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better1640        // diagnostics, so we don't mention anything about const param tys having generics at all.1641        if !self.r.tcx.features().generic_const_parameter_types() {1642            forward_ty_ban_rib_const_param_ty.bindings.clear();1643            forward_const_ban_rib_const_param_ty.bindings.clear();1644        }16451646        self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {1647            for param in params {1648                match param.kind {1649                    GenericParamKind::Lifetime => {1650                        for bound in &param.bounds {1651                            this.visit_param_bound(bound, BoundKind::Bound);1652                        }1653                    }1654                    GenericParamKind::Type { ref default } => {1655                        for bound in &param.bounds {1656                            this.visit_param_bound(bound, BoundKind::Bound);1657                        }16581659                        if let Some(ty) = default {1660                            this.ribs[TypeNS].push(forward_ty_ban_rib);1661                            this.ribs[ValueNS].push(forward_const_ban_rib);1662                            this.visit_ty(ty);1663                            forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();1664                            forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();1665                        }16661667                        // Allow all following defaults to refer to this type parameter.1668                        let i = &Ident::with_dummy_span(param.ident.name);1669                        forward_ty_ban_rib.bindings.swap_remove(i);1670                        forward_ty_ban_rib_const_param_ty.bindings.swap_remove(i);1671                    }1672                    GenericParamKind::Const { ref ty, span: _, ref default } => {1673                        // Const parameters can't have param bounds.1674                        assert!(param.bounds.is_empty());16751676                        this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty);1677                        this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty);1678                        if this.r.tcx.features().generic_const_parameter_types() {1679                            this.visit_ty(ty)1680                        } else {1681                            this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));1682                            this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));1683                            this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {1684                                this.visit_ty(ty)1685                            });1686                            this.ribs[TypeNS].pop().unwrap();1687                            this.ribs[ValueNS].pop().unwrap();1688                        }1689                        forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();1690                        forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();16911692                        if let Some(expr) = default {1693                            this.ribs[TypeNS].push(forward_ty_ban_rib);1694                            this.ribs[ValueNS].push(forward_const_ban_rib);1695                            this.resolve_anon_const(1696                                expr,1697                                AnonConstKind::ConstArg(IsRepeatExpr::No),1698                            );1699                            forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();1700                            forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();1701                        }17021703                        // Allow all following defaults to refer to this const parameter.1704                        let i = &Ident::with_dummy_span(param.ident.name);1705                        forward_const_ban_rib.bindings.swap_remove(i);1706                        forward_const_ban_rib_const_param_ty.bindings.swap_remove(i);1707                    }1708                }1709            }1710        })1711    }17121713    #[instrument(level = "debug", skip(self, work))]1714    fn with_lifetime_rib<T>(1715        &mut self,1716        kind: LifetimeRibKind,1717        work: impl FnOnce(&mut Self) -> T,1718    ) -> T {1719        self.lifetime_ribs.push(LifetimeRib::new(kind));1720        let outer_elision_candidates = self.lifetime_elision_candidates.take();1721        let ret = work(self);1722        self.lifetime_elision_candidates = outer_elision_candidates;1723        self.lifetime_ribs.pop();1724        ret1725    }17261727    #[instrument(level = "debug", skip(self))]1728    fn resolve_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) {1729        let ident = lifetime.ident;17301731        if ident.name == kw::StaticLifetime {1732            self.record_lifetime_res(1733                lifetime.id,1734                LifetimeRes::Static,1735                LifetimeElisionCandidate::Named,1736            );1737            return;1738        }17391740        if ident.name == kw::UnderscoreLifetime {1741            return self.resolve_anonymous_lifetime(lifetime, lifetime.id, false);1742        }17431744        let mut lifetime_rib_iter = self.lifetime_ribs.iter().rev();1745        while let Some(rib) = lifetime_rib_iter.next() {1746            let normalized_ident = ident.normalize_to_macros_2_0();1747            if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) {1748                self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named);17491750                if let LifetimeRes::Param { param, binder } = res {1751                    match self.lifetime_uses.entry(param) {1752                        Entry::Vacant(v) => {1753                            debug!("First use of {:?} at {:?}", res, ident.span);1754                            let use_set = self1755                                .lifetime_ribs1756                                .iter()1757                                .rev()1758                                .find_map(|rib| match rib.kind {1759                                    // Do not suggest eliding a lifetime where an anonymous1760                                    // lifetime would be illegal.1761                                    LifetimeRibKind::Item1762                                    | LifetimeRibKind::AnonymousReportError1763                                    | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }1764                                    | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),1765                                    // An anonymous lifetime is legal here, and bound to the right1766                                    // place, go ahead.1767                                    LifetimeRibKind::AnonymousCreateParameter {1768                                        binder: anon_binder,1769                                        ..1770                                    } => Some(if binder == anon_binder {1771                                        LifetimeUseSet::One { use_span: ident.span, use_ctxt }1772                                    } else {1773                                        LifetimeUseSet::Many1774                                    }),1775                                    // Only report if eliding the lifetime would have the same1776                                    // semantics.1777                                    LifetimeRibKind::Elided(r) => Some(if res == r {1778                                        LifetimeUseSet::One { use_span: ident.span, use_ctxt }1779                                    } else {1780                                        LifetimeUseSet::Many1781                                    }),1782                                    LifetimeRibKind::Generics { .. }1783                                    | LifetimeRibKind::ConstParamTy => None,1784                                    LifetimeRibKind::ConcreteAnonConst(_) => {1785                                        span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)1786                                    }17871788                                    LifetimeRibKind::ImplTrait => {1789                                        if self.r.tcx.features().anonymous_lifetime_in_impl_trait()1790                                        {1791                                            None1792                                        } else {1793                                            Some(LifetimeUseSet::Many)1794                                        }1795                                    }1796                                })1797                                .unwrap_or(LifetimeUseSet::Many);1798                            debug!(?use_ctxt, ?use_set);1799                            v.insert(use_set);1800                        }1801                        Entry::Occupied(mut o) => {1802                            debug!("Many uses of {:?} at {:?}", res, ident.span);1803                            *o.get_mut() = LifetimeUseSet::Many;1804                        }1805                    }1806                }1807                return;1808            }18091810            match rib.kind {1811                LifetimeRibKind::Item => break,1812                LifetimeRibKind::ConstParamTy => {1813                    let guar = self.emit_non_static_lt_in_const_param_ty_error(lifetime);1814                    self.record_lifetime_res(1815                        lifetime.id,1816                        LifetimeRes::Error(guar),1817                        LifetimeElisionCandidate::Ignore,1818                    );1819                    return;1820                }1821                LifetimeRibKind::ConcreteAnonConst(cause) => {1822                    let guar = self.emit_forbidden_non_static_lifetime_error(cause, lifetime);1823                    self.record_lifetime_res(1824                        lifetime.id,1825                        LifetimeRes::Error(guar),1826                        LifetimeElisionCandidate::Ignore,1827                    );1828                    return;1829                }1830                LifetimeRibKind::AnonymousCreateParameter { .. }1831                | LifetimeRibKind::Elided(_)1832                | LifetimeRibKind::Generics { .. }1833                | LifetimeRibKind::ElisionFailure1834                | LifetimeRibKind::AnonymousReportError1835                | LifetimeRibKind::ImplTrait1836                | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {}1837            }1838        }18391840        let normalized_ident = ident.normalize_to_macros_2_0();1841        let outer_res = lifetime_rib_iter1842            .find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer));18431844        let guar = self.emit_undeclared_lifetime_error(lifetime, outer_res);1845        self.record_lifetime_res(1846            lifetime.id,1847            LifetimeRes::Error(guar),1848            LifetimeElisionCandidate::Named,1849        );1850    }18511852    #[instrument(level = "debug", skip(self))]1853    fn resolve_anonymous_lifetime(1854        &mut self,1855        lifetime: &Lifetime,1856        id_for_lint: NodeId,1857        elided: bool,1858    ) {1859        debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);18601861        let kind =1862            if elided { MissingLifetimeKind::Ampersand } else { MissingLifetimeKind::Underscore };1863        let missing_lifetime = MissingLifetime {1864            id: lifetime.id,1865            span: lifetime.ident.span,1866            kind,1867            count: 1,1868            id_for_lint,1869        };1870        let elision_candidate = LifetimeElisionCandidate::Missing(missing_lifetime);1871        for (i, rib) in self.lifetime_ribs.iter().enumerate().rev() {1872            debug!(?rib.kind);1873            match rib.kind {1874                LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {1875                    let res = self.create_fresh_lifetime(lifetime.ident, binder, kind);1876                    self.record_lifetime_res(lifetime.id, res, elision_candidate);1877                    return;1878                }1879                LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {1880                    let mut lifetimes_in_scope = vec![];1881                    for rib in self.lifetime_ribs[..i].iter().rev() {1882                        lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));1883                        // Consider any anonymous lifetimes, too1884                        if let LifetimeRibKind::AnonymousCreateParameter { binder, .. } = rib.kind1885                            && let Some(extra) = self.r.extra_lifetime_params_map.get(&binder)1886                        {1887                            lifetimes_in_scope.extend(extra.iter().map(|(ident, _, _)| ident.span));1888                        }1889                        if let LifetimeRibKind::Item = rib.kind {1890                            break;1891                        }1892                    }1893                    if lifetimes_in_scope.is_empty() {1894                        self.record_lifetime_res(1895                            lifetime.id,1896                            LifetimeRes::Static,1897                            elision_candidate,1898                        );1899                        return;1900                    } else if emit_lint {1901                        let lt_span = if elided {1902                            lifetime.ident.span.shrink_to_hi()1903                        } else {1904                            lifetime.ident.span1905                        };1906                        let code = if elided { "'static " } else { "'static" };19071908                        self.r.lint_buffer.buffer_lint(1909                            lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,1910                            node_id,1911                            lifetime.ident.span,1912                            crate::errors::AssociatedConstElidedLifetime {1913                                elided,1914                                code,1915                                span: lt_span,1916                                lifetimes_in_scope: lifetimes_in_scope.into(),1917                            },1918                        );1919                    }1920                }1921                LifetimeRibKind::AnonymousReportError => {1922                    let guar = if elided {1923                        let suggestion = self.lifetime_ribs[i..].iter().rev().find_map(|rib| {1924                            if let LifetimeRibKind::Generics {1925                                span,1926                                kind: LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound,1927                                ..1928                            } = rib.kind1929                            {1930                                Some(errors::ElidedAnonymousLifetimeReportErrorSuggestion {1931                                    lo: span.shrink_to_lo(),1932                                    hi: lifetime.ident.span.shrink_to_hi(),1933                                })1934                            } else {1935                                None1936                            }1937                        });1938                        // are we trying to use an anonymous lifetime1939                        // on a non GAT associated trait type?1940                        if !self.in_func_body1941                            && let Some((module, _)) = &self.current_trait_ref1942                            && let Some(ty) = &self.diag_metadata.current_self_type1943                            && Some(true) == self.diag_metadata.in_non_gat_assoc_type1944                            && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _, _) =1945                                module.kind1946                        {1947                            if def_id_matches_path(1948                                self.r.tcx,1949                                trait_id,1950                                &["core", "iter", "traits", "iterator", "Iterator"],1951                            ) {1952                                self.r.dcx().emit_err(errors::LendingIteratorReportError {1953                                    lifetime: lifetime.ident.span,1954                                    ty: ty.span,1955                                })1956                            } else {1957                                let decl = if !trait_id.is_local()1958                                    && let Some(assoc) = self.diag_metadata.current_impl_item1959                                    && let AssocItemKind::Type(_) = assoc.kind1960                                    && let assocs = self.r.tcx.associated_items(trait_id)1961                                    && let Some(ident) = assoc.kind.ident()1962                                    && let Some(assoc) = assocs.find_by_ident_and_kind(1963                                        self.r.tcx,1964                                        ident,1965                                        AssocTag::Type,1966                                        trait_id,1967                                    ) {1968                                    let mut decl: MultiSpan =1969                                        self.r.tcx.def_span(assoc.def_id).into();1970                                    decl.push_span_label(1971                                        self.r.tcx.def_span(trait_id),1972                                        String::new(),1973                                    );1974                                    decl1975                                } else {1976                                    DUMMY_SP.into()1977                                };1978                                let mut err = self.r.dcx().create_err(1979                                    errors::AnonymousLifetimeNonGatReportError {1980                                        lifetime: lifetime.ident.span,1981                                        decl,1982                                    },1983                                );1984                                self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span);1985                                err.emit()1986                            }1987                        } else {1988                            self.r.dcx().emit_err(errors::ElidedAnonymousLifetimeReportError {1989                                span: lifetime.ident.span,1990                                suggestion,1991                            })1992                        }1993                    } else {1994                        self.r.dcx().emit_err(errors::ExplicitAnonymousLifetimeReportError {1995                            span: lifetime.ident.span,1996                        })1997                    };1998                    self.record_lifetime_res(1999                        lifetime.id,2000                        LifetimeRes::Error(guar),

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.