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