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 ¶m.bounds {1671 this.visit_param_bound(bound, BoundKind::Bound);1672 }1673 }1674 GenericParamKind::Type { ref default } => {1675 for bound in ¶m.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.