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