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