1 // ignore-tidy-filelength
2 //! "Late resolution" is the pass that resolves most of names in a crate beside imports and macros.
3 //! It runs when the crate is fully expanded and its module structure is fully built.
4 //! So it just walks through the crate and resolves all the expressions, types, etc.
6 //! If you wonder why there's no `early.rs`, that's because it's split into three files -
7 //! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`.
11 use crate::{path_names_to_string, BindingError, Finalize, LexicalScopeBinding}
;
12 use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult}
;
13 use crate::{ResolutionError, Resolver, Segment, UseError}
;
15 use rustc_ast
::ptr
::P
;
16 use rustc_ast
::visit
::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}
;
18 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet, FxIndexMap}
;
19 use rustc_errors
::DiagnosticId
;
20 use rustc_hir
::def
::Namespace
::{self, *}
;
21 use rustc_hir
::def
::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS}
;
22 use rustc_hir
::def_id
::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}
;
23 use rustc_hir
::{BindingAnnotation, PrimTy, TraitCandidate}
;
24 use rustc_middle
::middle
::resolve_lifetime
::Set1
;
25 use rustc_middle
::ty
::DefIdTree
;
26 use rustc_middle
::{bug, span_bug}
;
27 use rustc_session
::lint
;
28 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
29 use rustc_span
::{BytePos, Span}
;
30 use smallvec
::{smallvec, SmallVec}
;
32 use rustc_span
::source_map
::{respan, Spanned}
;
33 use std
::assert_matches
::debug_assert_matches
;
34 use std
::collections
::{hash_map::Entry, BTreeSet}
;
35 use std
::mem
::{replace, take}
;
39 type Res
= def
::Res
<NodeId
>;
41 type IdentMap
<T
> = FxHashMap
<Ident
, T
>;
43 /// Map from the name in a pattern to its binding mode.
44 type BindingMap
= IdentMap
<BindingInfo
>;
47 ElisionFnParameter
, LifetimeElisionCandidate
, MissingLifetime
, MissingLifetimeKind
,
50 #[derive(Copy, Clone, Debug)]
53 annotation
: BindingAnnotation
,
56 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
57 pub enum PatternSource
{
64 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
71 pub fn descr(self) -> &'
static str {
73 PatternSource
::Match
=> "match binding",
74 PatternSource
::Let
=> "let binding",
75 PatternSource
::For
=> "for binding",
76 PatternSource
::FnParam
=> "function parameter",
81 /// Denotes whether the context for the set of already bound bindings is a `Product`
82 /// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
83 /// See those functions for more information.
86 /// A product pattern context, e.g., `Variant(a, b)`.
88 /// An or-pattern context, e.g., `p_0 | ... | p_n`.
92 /// Does this the item (from the item rib scope) allow generic parameters?
93 #[derive(Copy, Clone, Debug)]
94 pub(crate) enum HasGenericParams
{
99 /// May this constant have generics?
100 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
101 pub(crate) enum ConstantHasGenerics
{
106 impl ConstantHasGenerics
{
107 fn force_yes_if(self, b
: bool
) -> Self {
108 if b { Self::Yes }
else { self }
112 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
113 pub(crate) enum ConstantItemKind
{
118 /// The rib kind restricts certain accesses,
119 /// e.g. to a `Res::Local` of an outer item.
120 #[derive(Copy, Clone, Debug)]
121 pub(crate) enum RibKind
<'a
> {
122 /// No restriction needs to be applied.
125 /// We passed through an impl or trait and are now in one of its
126 /// methods or associated types. Allow references to ty params that impl or trait
127 /// binds. Disallow any other upvars (including other ty params that are
131 /// We passed through a closure. Disallow labels.
132 ClosureOrAsyncRibKind
,
134 /// We passed through an item scope. Disallow upvars.
135 ItemRibKind(HasGenericParams
),
137 /// We're in a constant item. Can't refer to dynamic stuff.
139 /// The item may reference generic parameters in trivial constant expressions.
140 /// All other constants aren't allowed to use generic params at all.
141 ConstantItemRibKind(ConstantHasGenerics
, Option
<(Ident
, ConstantItemKind
)>),
143 /// We passed through a module.
144 ModuleRibKind(Module
<'a
>),
146 /// We passed through a `macro_rules!` statement
147 MacroDefinition(DefId
),
149 /// All bindings in this rib are generic parameters that can't be used
150 /// from the default of a generic parameter because they're not declared
151 /// before said generic parameter. Also see the `visit_generics` override.
152 ForwardGenericParamBanRibKind
,
154 /// We are inside of the type of a const parameter. Can't refer to any
158 /// We are inside a `sym` inline assembly operand. Can only refer to
164 /// Whether this rib kind contains generic parameters, as opposed to local
166 pub(crate) fn contains_params(&self) -> bool
{
169 | ClosureOrAsyncRibKind
170 | ConstantItemRibKind(..)
173 | ConstParamTyRibKind
174 | InlineAsmSymRibKind
=> false,
175 AssocItemRibKind
| ItemRibKind(_
) | ForwardGenericParamBanRibKind
=> true,
179 /// This rib forbids referring to labels defined in upwards ribs.
180 fn is_label_barrier(self) -> bool
{
182 NormalRibKind
| MacroDefinition(..) => false,
185 | ClosureOrAsyncRibKind
187 | ConstantItemRibKind(..)
189 | ForwardGenericParamBanRibKind
190 | ConstParamTyRibKind
191 | InlineAsmSymRibKind
=> true,
196 /// A single local scope.
198 /// A rib represents a scope names can live in. Note that these appear in many places, not just
199 /// around braces. At any place where the list of accessible names (of the given namespace)
200 /// changes or a new restrictions on the name accessibility are introduced, a new rib is put onto a
201 /// stack. This may be, for example, a `let` statement (because it introduces variables), a macro,
204 /// Different [rib kinds](enum@RibKind) are transparent for different names.
206 /// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
207 /// resolving, the name is looked up from inside out.
209 pub(crate) struct Rib
<'a
, R
= Res
> {
210 pub bindings
: IdentMap
<R
>,
211 pub kind
: RibKind
<'a
>,
214 impl<'a
, R
> Rib
<'a
, R
> {
215 fn new(kind
: RibKind
<'a
>) -> Rib
<'a
, R
> {
216 Rib { bindings: Default::default(), kind }
220 #[derive(Clone, Copy, Debug)]
221 enum LifetimeUseSet
{
222 One { use_span: Span, use_ctxt: visit::LifetimeCtxt }
,
226 #[derive(Copy, Clone, Debug)]
227 enum LifetimeRibKind
{
228 // -- Ribs introducing named lifetimes
230 /// This rib declares generic parameters.
231 /// Only for this kind the `LifetimeRib::bindings` field can be non-empty.
232 Generics { binder: NodeId, span: Span, kind: LifetimeBinderKind }
,
234 // -- Ribs introducing unnamed lifetimes
236 /// Create a new anonymous lifetime parameter and reference it.
238 /// If `report_in_path`, report an error when encountering lifetime elision in a path:
240 /// struct Foo<'a> { x: &'a () }
241 /// async fn foo(x: Foo) {}
244 /// Note: the error should not trigger when the elided lifetime is in a pattern or
245 /// expression-position path:
247 /// struct Foo<'a> { x: &'a () }
248 /// async fn foo(Foo { x: _ }: Foo<'_>) {}
250 AnonymousCreateParameter { binder: NodeId, report_in_path: bool }
,
252 /// Replace all anonymous lifetimes by provided lifetime.
255 // -- Barrier ribs that stop lifetime lookup, or continue it but produce an error later.
257 /// Give a hard error when either `&` or `'_` is written. Used to
258 /// rule out things like `where T: Foo<'_>`. Does not imply an
259 /// error on default object bounds (e.g., `Box<dyn Foo>`).
260 AnonymousReportError
,
262 /// Signal we cannot find which should be the anonymous lifetime.
265 /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
266 /// generics. We are disallowing this until we can decide on how we want to handle non-'static
267 /// lifetimes in const generics. See issue #74052 for discussion.
270 /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
271 /// This function will emit an error if `generic_const_exprs` is not enabled, the body
272 /// identified by `body_id` is an anonymous constant and `lifetime_ref` is non-static.
275 /// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
279 #[derive(Copy, Clone, Debug)]
280 enum LifetimeBinderKind
{
290 impl LifetimeBinderKind
{
291 fn descr(self) -> &'
static str {
292 use LifetimeBinderKind
::*;
294 BareFnType
=> "type",
295 PolyTrait
=> "bound",
296 WhereBound
=> "bound",
298 ImplBlock
=> "impl block",
299 Function
=> "function",
300 Closure
=> "closure",
307 kind
: LifetimeRibKind
,
308 // We need to preserve insertion order for async fns.
309 bindings
: FxIndexMap
<Ident
, (NodeId
, LifetimeRes
)>,
313 fn new(kind
: LifetimeRibKind
) -> LifetimeRib
{
314 LifetimeRib { bindings: Default::default(), kind }
318 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
319 pub(crate) enum AliasPossibility
{
324 #[derive(Copy, Clone, Debug)]
325 pub(crate) enum PathSource
<'a
> {
326 // Type paths `Path`.
328 // Trait paths in bounds or impls.
329 Trait(AliasPossibility
),
330 // Expression paths `path`, with optional parent context.
331 Expr(Option
<&'a Expr
>),
332 // Paths in path patterns `Path`.
334 // Paths in struct expressions and patterns `Path { .. }`.
336 // Paths in tuple struct patterns `Path(..)`.
337 TupleStruct(Span
, &'a
[Span
]),
338 // `m::A::B` in `<T as m::A>::B::C`.
339 TraitItem(Namespace
),
342 impl<'a
> PathSource
<'a
> {
343 fn namespace(self) -> Namespace
{
345 PathSource
::Type
| PathSource
::Trait(_
) | PathSource
::Struct
=> TypeNS
,
346 PathSource
::Expr(..) | PathSource
::Pat
| PathSource
::TupleStruct(..) => ValueNS
,
347 PathSource
::TraitItem(ns
) => ns
,
351 fn defer_to_typeck(self) -> bool
{
354 | PathSource
::Expr(..)
357 | PathSource
::TupleStruct(..) => true,
358 PathSource
::Trait(_
) | PathSource
::TraitItem(..) => false,
362 fn descr_expected(self) -> &'
static str {
364 PathSource
::Type
=> "type",
365 PathSource
::Trait(_
) => "trait",
366 PathSource
::Pat
=> "unit struct, unit variant or constant",
367 PathSource
::Struct
=> "struct, variant or union type",
368 PathSource
::TupleStruct(..) => "tuple struct or tuple variant",
369 PathSource
::TraitItem(ns
) => match ns
{
370 TypeNS
=> "associated type",
371 ValueNS
=> "method or associated constant",
372 MacroNS
=> bug
!("associated macro"),
374 PathSource
::Expr(parent
) => match parent
.as_ref().map(|p
| &p
.kind
) {
375 // "function" here means "anything callable" rather than `DefKind::Fn`,
376 // this is not precise but usually more helpful than just "value".
377 Some(ExprKind
::Call(call_expr
, _
)) => match &call_expr
.kind
{
378 // the case of `::some_crate()`
379 ExprKind
::Path(_
, path
)
380 if path
.segments
.len() == 2
381 && path
.segments
[0].ident
.name
== kw
::PathRoot
=>
385 ExprKind
::Path(_
, path
) => {
386 let mut msg
= "function";
387 if let Some(segment
) = path
.segments
.iter().last() {
388 if let Some(c
) = segment
.ident
.to_string().chars().next() {
389 if c
.is_uppercase() {
390 msg
= "function, tuple struct or tuple variant";
403 fn is_call(self) -> bool
{
404 matches
!(self, PathSource
::Expr(Some(&Expr { kind: ExprKind::Call(..), .. }
)))
407 pub(crate) fn is_expected(self, res
: Res
) -> bool
{
409 PathSource
::Type
=> matches
!(
416 | DefKind
::TraitAlias
421 | DefKind
::ForeignTy
,
424 | Res
::SelfTyParam { .. }
425 | Res
::SelfTyAlias { .. }
427 PathSource
::Trait(AliasPossibility
::No
) => matches
!(res
, Res
::Def(DefKind
::Trait
, _
)),
428 PathSource
::Trait(AliasPossibility
::Maybe
) => {
429 matches
!(res
, Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
))
431 PathSource
::Expr(..) => matches
!(
434 DefKind
::Ctor(_
, CtorKind
::Const
| CtorKind
::Fn
)
439 | DefKind
::AssocConst
440 | DefKind
::ConstParam
,
446 res
.expected_in_unit_struct_pat()
447 || matches
!(res
, Res
::Def(DefKind
::Const
| DefKind
::AssocConst
, _
))
449 PathSource
::TupleStruct(..) => res
.expected_in_tuple_struct_pat(),
450 PathSource
::Struct
=> matches
!(
459 ) | Res
::SelfTyParam { .. }
460 | Res
::SelfTyAlias { .. }
462 PathSource
::TraitItem(ns
) => match res
{
463 Res
::Def(DefKind
::AssocConst
| DefKind
::AssocFn
, _
) if ns
== ValueNS
=> true,
464 Res
::Def(DefKind
::AssocTy
, _
) if ns
== TypeNS
=> true,
470 fn error_code(self, has_unexpected_resolution
: bool
) -> DiagnosticId
{
471 use rustc_errors
::error_code
;
472 match (self, has_unexpected_resolution
) {
473 (PathSource
::Trait(_
), true) => error_code
!(E0404
),
474 (PathSource
::Trait(_
), false) => error_code
!(E0405
),
475 (PathSource
::Type
, true) => error_code
!(E0573
),
476 (PathSource
::Type
, false) => error_code
!(E0412
),
477 (PathSource
::Struct
, true) => error_code
!(E0574
),
478 (PathSource
::Struct
, false) => error_code
!(E0422
),
479 (PathSource
::Expr(..), true) => error_code
!(E0423
),
480 (PathSource
::Expr(..), false) => error_code
!(E0425
),
481 (PathSource
::Pat
| PathSource
::TupleStruct(..), true) => error_code
!(E0532
),
482 (PathSource
::Pat
| PathSource
::TupleStruct(..), false) => error_code
!(E0531
),
483 (PathSource
::TraitItem(..), true) => error_code
!(E0575
),
484 (PathSource
::TraitItem(..), false) => error_code
!(E0576
),
490 struct DiagnosticMetadata
<'ast
> {
491 /// The current trait's associated items' ident, used for diagnostic suggestions.
492 current_trait_assoc_items
: Option
<&'ast
[P
<AssocItem
>]>,
494 /// The current self type if inside an impl (used for better errors).
495 current_self_type
: Option
<Ty
>,
497 /// The current self item if inside an ADT (used for better errors).
498 current_self_item
: Option
<NodeId
>,
500 /// The current trait (used to suggest).
501 current_item
: Option
<&'ast Item
>,
503 /// When processing generics and encountering a type not found, suggest introducing a type
505 currently_processing_generics
: bool
,
507 /// The current enclosing (non-closure) function (used for better errors).
508 current_function
: Option
<(FnKind
<'ast
>, Span
)>,
510 /// A list of labels as of yet unused. Labels will be removed from this map when
511 /// they are used (in a `break` or `continue` statement)
512 unused_labels
: FxHashMap
<NodeId
, Span
>,
514 /// Only used for better errors on `fn(): fn()`.
515 current_type_ascription
: Vec
<Span
>,
517 /// Only used for better errors on `let x = { foo: bar };`.
518 /// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only
519 /// needed for cases where this parses as a correct type ascription.
520 current_block_could_be_bare_struct_literal
: Option
<Span
>,
522 /// Only used for better errors on `let <pat>: <expr, not type>;`.
523 current_let_binding
: Option
<(Span
, Option
<Span
>, Option
<Span
>)>,
525 /// Used to detect possible `if let` written without `let` and to provide structured suggestion.
526 in_if_condition
: Option
<&'ast Expr
>,
528 /// Used to detect possible new binding written without `let` and to provide structured suggestion.
529 in_assignment
: Option
<&'ast Expr
>,
531 /// If we are currently in a trait object definition. Used to point at the bounds when
532 /// encountering a struct or enum.
533 current_trait_object
: Option
<&'ast
[ast
::GenericBound
]>,
535 /// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
536 current_where_predicate
: Option
<&'ast WherePredicate
>,
538 current_type_path
: Option
<&'ast Ty
>,
540 /// The current impl items (used to suggest).
541 current_impl_items
: Option
<&'ast
[P
<AssocItem
>]>,
543 /// When processing impl trait
544 currently_processing_impl_trait
: Option
<(TraitRef
, Ty
)>,
546 /// Accumulate the errors due to missed lifetime elision,
547 /// and report them all at once for each function.
548 current_elision_failures
: Vec
<MissingLifetime
>,
551 struct LateResolutionVisitor
<'a
, 'b
, 'ast
> {
552 r
: &'b
mut Resolver
<'a
>,
554 /// The module that represents the current item scope.
555 parent_scope
: ParentScope
<'a
>,
557 /// The current set of local scopes for types and values.
558 /// FIXME #4948: Reuse ribs to avoid allocation.
559 ribs
: PerNS
<Vec
<Rib
<'a
>>>,
561 /// The current set of local scopes, for labels.
562 label_ribs
: Vec
<Rib
<'a
, NodeId
>>,
564 /// The current set of local scopes for lifetimes.
565 lifetime_ribs
: Vec
<LifetimeRib
>,
567 /// We are looking for lifetimes in an elision context.
568 /// The set contains all the resolutions that we encountered so far.
569 /// They will be used to determine the correct lifetime for the fn return type.
570 /// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named
572 lifetime_elision_candidates
: Option
<Vec
<(LifetimeRes
, LifetimeElisionCandidate
)>>,
574 /// The trait that the current context can refer to.
575 current_trait_ref
: Option
<(Module
<'a
>, TraitRef
)>,
577 /// Fields used to add information to diagnostic errors.
578 diagnostic_metadata
: Box
<DiagnosticMetadata
<'ast
>>,
580 /// State used to know whether to ignore resolution errors for function bodies.
582 /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items.
583 /// In most cases this will be `None`, in which case errors will always be reported.
584 /// If it is `true`, then it will be updated when entering a nested function or trait body.
587 /// Count the number of places a lifetime is used.
588 lifetime_uses
: FxHashMap
<LocalDefId
, LifetimeUseSet
>,
591 /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
592 impl<'a
: 'ast
, 'ast
> Visitor
<'ast
> for LateResolutionVisitor
<'a
, '_
, 'ast
> {
593 fn visit_attribute(&mut self, _
: &'ast Attribute
) {
594 // We do not want to resolve expressions that appear in attributes,
595 // as they do not correspond to actual code.
597 fn visit_item(&mut self, item
: &'ast Item
) {
598 let prev
= replace(&mut self.diagnostic_metadata
.current_item
, Some(item
));
599 // Always report errors in items we just entered.
600 let old_ignore
= replace(&mut self.in_func_body
, false);
601 self.with_lifetime_rib(LifetimeRibKind
::Item
, |this
| this
.resolve_item(item
));
602 self.in_func_body
= old_ignore
;
603 self.diagnostic_metadata
.current_item
= prev
;
605 fn visit_arm(&mut self, arm
: &'ast Arm
) {
606 self.resolve_arm(arm
);
608 fn visit_block(&mut self, block
: &'ast Block
) {
609 self.resolve_block(block
);
611 fn visit_anon_const(&mut self, constant
: &'ast AnonConst
) {
612 // We deal with repeat expressions explicitly in `resolve_expr`.
613 self.with_lifetime_rib(LifetimeRibKind
::AnonConst
, |this
| {
614 this
.with_lifetime_rib(LifetimeRibKind
::Elided(LifetimeRes
::Static
), |this
| {
615 this
.resolve_anon_const(constant
, IsRepeatExpr
::No
);
619 fn visit_expr(&mut self, expr
: &'ast Expr
) {
620 self.resolve_expr(expr
, None
);
622 fn visit_local(&mut self, local
: &'ast Local
) {
623 let local_spans
= match local
.pat
.kind
{
624 // We check for this to avoid tuple struct fields.
625 PatKind
::Wild
=> None
,
628 local
.ty
.as_ref().map(|ty
| ty
.span
),
629 local
.kind
.init().map(|init
| init
.span
),
632 let original
= replace(&mut self.diagnostic_metadata
.current_let_binding
, local_spans
);
633 self.resolve_local(local
);
634 self.diagnostic_metadata
.current_let_binding
= original
;
636 fn visit_ty(&mut self, ty
: &'ast Ty
) {
637 let prev
= self.diagnostic_metadata
.current_trait_object
;
638 let prev_ty
= self.diagnostic_metadata
.current_type_path
;
640 TyKind
::Rptr(None
, _
) => {
641 // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
643 // This span will be used in case of elision failure.
644 let span
= self.r
.session
.source_map().start_point(ty
.span
);
645 self.resolve_elided_lifetime(ty
.id
, span
);
646 visit
::walk_ty(self, ty
);
648 TyKind
::Path(ref qself
, ref path
) => {
649 self.diagnostic_metadata
.current_type_path
= Some(ty
);
650 self.smart_resolve_path(ty
.id
, qself
.as_ref(), path
, PathSource
::Type
);
652 // Check whether we should interpret this as a bare trait object.
654 && let Some(partial_res
) = self.r
.partial_res_map
.get(&ty
.id
)
655 && let Some(Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
)) = partial_res
.full_res()
657 // This path is actually a bare trait object. In case of a bare `Fn`-trait
658 // object with anonymous lifetimes, we need this rib to correctly place the
659 // synthetic lifetimes.
660 let span
= ty
.span
.shrink_to_lo().to(path
.span
.shrink_to_lo());
661 self.with_generic_param_rib(
664 LifetimeRibKind
::Generics
{
666 kind
: LifetimeBinderKind
::PolyTrait
,
669 |this
| this
.visit_path(&path
, ty
.id
),
672 visit
::walk_ty(self, ty
)
675 TyKind
::ImplicitSelf
=> {
676 let self_ty
= Ident
::with_dummy_span(kw
::SelfUpper
);
678 .resolve_ident_in_lexical_scope(
681 Some(Finalize
::new(ty
.id
, ty
.span
)),
684 .map_or(Res
::Err
, |d
| d
.res());
685 self.r
.record_partial_res(ty
.id
, PartialRes
::new(res
));
686 visit
::walk_ty(self, ty
)
688 TyKind
::ImplTrait(..) => {
689 let candidates
= self.lifetime_elision_candidates
.take();
690 visit
::walk_ty(self, ty
);
691 self.lifetime_elision_candidates
= candidates
;
693 TyKind
::TraitObject(ref bounds
, ..) => {
694 self.diagnostic_metadata
.current_trait_object
= Some(&bounds
[..]);
695 visit
::walk_ty(self, ty
)
697 TyKind
::BareFn(ref bare_fn
) => {
698 let span
= ty
.span
.shrink_to_lo().to(bare_fn
.decl_span
.shrink_to_lo());
699 self.with_generic_param_rib(
700 &bare_fn
.generic_params
,
702 LifetimeRibKind
::Generics
{
704 kind
: LifetimeBinderKind
::BareFnType
,
708 this
.visit_generic_params(&bare_fn
.generic_params
, false);
709 this
.with_lifetime_rib(
710 LifetimeRibKind
::AnonymousCreateParameter
{
712 report_in_path
: false,
715 this
.resolve_fn_signature(
718 // We don't need to deal with patterns in parameters, because
719 // they are not possible for foreign or bodiless functions.
724 .map(|Param { ty, .. }
| (None
, &**ty
)),
725 &bare_fn
.decl
.output
,
732 _
=> visit
::walk_ty(self, ty
),
734 self.diagnostic_metadata
.current_trait_object
= prev
;
735 self.diagnostic_metadata
.current_type_path
= prev_ty
;
737 fn visit_poly_trait_ref(&mut self, tref
: &'ast PolyTraitRef
) {
738 let span
= tref
.span
.shrink_to_lo().to(tref
.trait_ref
.path
.span
.shrink_to_lo());
739 self.with_generic_param_rib(
740 &tref
.bound_generic_params
,
742 LifetimeRibKind
::Generics
{
743 binder
: tref
.trait_ref
.ref_id
,
744 kind
: LifetimeBinderKind
::PolyTrait
,
748 this
.visit_generic_params(&tref
.bound_generic_params
, false);
749 this
.smart_resolve_path(
750 tref
.trait_ref
.ref_id
,
752 &tref
.trait_ref
.path
,
753 PathSource
::Trait(AliasPossibility
::Maybe
),
755 this
.visit_trait_ref(&tref
.trait_ref
);
759 fn visit_foreign_item(&mut self, foreign_item
: &'ast ForeignItem
) {
760 match foreign_item
.kind
{
761 ForeignItemKind
::TyAlias(box TyAlias { ref generics, .. }
) => {
762 self.with_generic_param_rib(
764 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
765 LifetimeRibKind
::Generics
{
766 binder
: foreign_item
.id
,
767 kind
: LifetimeBinderKind
::Item
,
770 |this
| visit
::walk_foreign_item(this
, foreign_item
),
773 ForeignItemKind
::Fn(box Fn { ref generics, .. }
) => {
774 self.with_generic_param_rib(
776 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
777 LifetimeRibKind
::Generics
{
778 binder
: foreign_item
.id
,
779 kind
: LifetimeBinderKind
::Function
,
782 |this
| visit
::walk_foreign_item(this
, foreign_item
),
785 ForeignItemKind
::Static(..) => {
786 self.with_static_rib(|this
| {
787 visit
::walk_foreign_item(this
, foreign_item
);
790 ForeignItemKind
::MacCall(..) => {
791 panic
!("unexpanded macro in resolve!")
795 fn visit_fn(&mut self, fn_kind
: FnKind
<'ast
>, sp
: Span
, fn_id
: NodeId
) {
796 let previous_value
= self.diagnostic_metadata
.current_function
;
798 // Bail if the function is foreign, and thus cannot validly have
799 // a body, or if there's no body for some other reason.
800 FnKind
::Fn(FnCtxt
::Foreign
, _
, sig
, _
, generics
, _
)
801 | FnKind
::Fn(_
, _
, sig
, _
, generics
, None
) => {
802 self.visit_fn_header(&sig
.header
);
803 self.visit_generics(generics
);
804 self.with_lifetime_rib(
805 LifetimeRibKind
::AnonymousCreateParameter
{
807 report_in_path
: false,
810 this
.resolve_fn_signature(
813 sig
.decl
.inputs
.iter().map(|Param { ty, .. }
| (None
, &**ty
)),
817 this
.record_lifetime_params_for_async(
819 sig
.header
.asyncness
.opt_return_id(),
826 self.diagnostic_metadata
.current_function
= Some((fn_kind
, sp
));
828 // Do not update `current_function` for closures: it suggests `self` parameters.
829 FnKind
::Closure(..) => {}
831 debug
!("(resolving function) entering function");
833 // Create a value rib for the function.
834 self.with_rib(ValueNS
, ClosureOrAsyncRibKind
, |this
| {
835 // Create a label rib for the function.
836 this
.with_label_rib(ClosureOrAsyncRibKind
, |this
| {
838 FnKind
::Fn(_
, _
, sig
, _
, generics
, body
) => {
839 this
.visit_generics(generics
);
841 let declaration
= &sig
.decl
;
842 let async_node_id
= sig
.header
.asyncness
.opt_return_id();
844 this
.with_lifetime_rib(
845 LifetimeRibKind
::AnonymousCreateParameter
{
847 report_in_path
: async_node_id
.is_some(),
850 this
.resolve_fn_signature(
852 declaration
.has_self(),
856 .map(|Param { pat, ty, .. }
| (Some(&**pat
), &**ty
)),
862 this
.record_lifetime_params_for_async(fn_id
, async_node_id
);
864 if let Some(body
) = body
{
865 // Ignore errors in function bodies if this is rustdoc
866 // Be sure not to set this until the function signature has been resolved.
867 let previous_state
= replace(&mut this
.in_func_body
, true);
868 // Resolve the function body, potentially inside the body of an async closure
869 this
.with_lifetime_rib(
870 LifetimeRibKind
::Elided(LifetimeRes
::Infer
),
871 |this
| this
.visit_block(body
),
874 debug
!("(resolving function) leaving function");
875 this
.in_func_body
= previous_state
;
878 FnKind
::Closure(binder
, declaration
, body
) => {
879 this
.visit_closure_binder(binder
);
881 this
.with_lifetime_rib(
883 // We do not have any explicit generic lifetime parameter.
884 ClosureBinder
::NotPresent
=> {
885 LifetimeRibKind
::AnonymousCreateParameter
{
887 report_in_path
: false,
890 ClosureBinder
::For { .. }
=> LifetimeRibKind
::AnonymousReportError
,
892 // Add each argument to the rib.
893 |this
| this
.resolve_params(&declaration
.inputs
),
895 this
.with_lifetime_rib(
897 ClosureBinder
::NotPresent
=> {
898 LifetimeRibKind
::Elided(LifetimeRes
::Infer
)
900 ClosureBinder
::For { .. }
=> LifetimeRibKind
::AnonymousReportError
,
902 |this
| visit
::walk_fn_ret_ty(this
, &declaration
.output
),
905 // Ignore errors in function bodies if this is rustdoc
906 // Be sure not to set this until the function signature has been resolved.
907 let previous_state
= replace(&mut this
.in_func_body
, true);
908 // Resolve the function body, potentially inside the body of an async closure
909 this
.with_lifetime_rib(
910 LifetimeRibKind
::Elided(LifetimeRes
::Infer
),
911 |this
| this
.visit_expr(body
),
914 debug
!("(resolving function) leaving function");
915 this
.in_func_body
= previous_state
;
920 self.diagnostic_metadata
.current_function
= previous_value
;
922 fn visit_lifetime(&mut self, lifetime
: &'ast Lifetime
, use_ctxt
: visit
::LifetimeCtxt
) {
923 self.resolve_lifetime(lifetime
, use_ctxt
)
926 fn visit_generics(&mut self, generics
: &'ast Generics
) {
927 self.visit_generic_params(
929 self.diagnostic_metadata
.current_self_item
.is_some(),
931 for p
in &generics
.where_clause
.predicates
{
932 self.visit_where_predicate(p
);
936 fn visit_closure_binder(&mut self, b
: &'ast ClosureBinder
) {
938 ClosureBinder
::NotPresent
=> {}
939 ClosureBinder
::For { generic_params, .. }
=> {
940 self.visit_generic_params(
942 self.diagnostic_metadata
.current_self_item
.is_some(),
948 fn visit_generic_arg(&mut self, arg
: &'ast GenericArg
) {
949 debug
!("visit_generic_arg({:?})", arg
);
950 let prev
= replace(&mut self.diagnostic_metadata
.currently_processing_generics
, true);
952 GenericArg
::Type(ref ty
) => {
953 // We parse const arguments as path types as we cannot distinguish them during
954 // parsing. We try to resolve that ambiguity by attempting resolution the type
955 // namespace first, and if that fails we try again in the value namespace. If
956 // resolution in the value namespace succeeds, we have an generic const argument on
958 if let TyKind
::Path(ref qself
, ref path
) = ty
.kind
{
959 // We cannot disambiguate multi-segment paths right now as that requires type
961 if path
.segments
.len() == 1 && path
.segments
[0].args
.is_none() {
962 let mut check_ns
= |ns
| {
963 self.maybe_resolve_ident_in_lexical_scope(path
.segments
[0].ident
, ns
)
966 if !check_ns(TypeNS
) && check_ns(ValueNS
) {
967 // This must be equivalent to `visit_anon_const`, but we cannot call it
968 // directly due to visitor lifetimes so we have to copy-paste some code.
970 // Note that we might not be inside of an repeat expression here,
971 // but considering that `IsRepeatExpr` is only relevant for
972 // non-trivial constants this is doesn't matter.
973 self.with_constant_rib(
975 ConstantHasGenerics
::Yes
,
978 this
.smart_resolve_path(
982 PathSource
::Expr(None
),
985 if let Some(ref qself
) = *qself
{
986 this
.visit_ty(&qself
.ty
);
988 this
.visit_path(path
, ty
.id
);
992 self.diagnostic_metadata
.currently_processing_generics
= prev
;
1000 GenericArg
::Lifetime(lt
) => self.visit_lifetime(lt
, visit
::LifetimeCtxt
::GenericArg
),
1001 GenericArg
::Const(ct
) => self.visit_anon_const(ct
),
1003 self.diagnostic_metadata
.currently_processing_generics
= prev
;
1006 fn visit_assoc_constraint(&mut self, constraint
: &'ast AssocConstraint
) {
1007 self.visit_ident(constraint
.ident
);
1008 if let Some(ref gen_args
) = constraint
.gen_args
{
1009 // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.
1010 self.with_lifetime_rib(LifetimeRibKind
::AnonymousReportError
, |this
| {
1011 this
.visit_generic_args(gen_args
)
1014 match constraint
.kind
{
1015 AssocConstraintKind
::Equality { ref term }
=> match term
{
1016 Term
::Ty(ty
) => self.visit_ty(ty
),
1017 Term
::Const(c
) => self.visit_anon_const(c
),
1019 AssocConstraintKind
::Bound { ref bounds }
=> {
1020 walk_list
!(self, visit_param_bound
, bounds
, BoundKind
::Bound
);
1025 fn visit_path_segment(&mut self, path_segment
: &'ast PathSegment
) {
1026 if let Some(ref args
) = path_segment
.args
{
1028 GenericArgs
::AngleBracketed(..) => visit
::walk_generic_args(self, args
),
1029 GenericArgs
::Parenthesized(p_args
) => {
1030 // Probe the lifetime ribs to know how to behave.
1031 for rib
in self.lifetime_ribs
.iter().rev() {
1033 // We are inside a `PolyTraitRef`. The lifetimes are
1034 // to be intoduced in that (maybe implicit) `for<>` binder.
1035 LifetimeRibKind
::Generics
{
1037 kind
: LifetimeBinderKind
::PolyTrait
,
1040 self.with_lifetime_rib(
1041 LifetimeRibKind
::AnonymousCreateParameter
{
1043 report_in_path
: false,
1046 this
.resolve_fn_signature(
1049 p_args
.inputs
.iter().map(|ty
| (None
, &**ty
)),
1056 // We have nowhere to introduce generics. Code is malformed,
1057 // so use regular lifetime resolution to avoid spurious errors.
1058 LifetimeRibKind
::Item
| LifetimeRibKind
::Generics { .. }
=> {
1059 visit
::walk_generic_args(self, args
);
1062 LifetimeRibKind
::AnonymousCreateParameter { .. }
1063 | LifetimeRibKind
::AnonymousReportError
1064 | LifetimeRibKind
::Elided(_
)
1065 | LifetimeRibKind
::ElisionFailure
1066 | LifetimeRibKind
::AnonConst
1067 | LifetimeRibKind
::ConstGeneric
=> {}
1075 fn visit_where_predicate(&mut self, p
: &'ast WherePredicate
) {
1076 debug
!("visit_where_predicate {:?}", p
);
1077 let previous_value
=
1078 replace(&mut self.diagnostic_metadata
.current_where_predicate
, Some(p
));
1079 self.with_lifetime_rib(LifetimeRibKind
::AnonymousReportError
, |this
| {
1080 if let WherePredicate
::BoundPredicate(WhereBoundPredicate
{
1083 ref bound_generic_params
,
1084 span
: predicate_span
,
1088 let span
= predicate_span
.shrink_to_lo().to(bounded_ty
.span
.shrink_to_lo());
1089 this
.with_generic_param_rib(
1090 &bound_generic_params
,
1092 LifetimeRibKind
::Generics
{
1093 binder
: bounded_ty
.id
,
1094 kind
: LifetimeBinderKind
::WhereBound
,
1098 this
.visit_generic_params(&bound_generic_params
, false);
1099 this
.visit_ty(bounded_ty
);
1100 for bound
in bounds
{
1101 this
.visit_param_bound(bound
, BoundKind
::Bound
)
1106 visit
::walk_where_predicate(this
, p
);
1109 self.diagnostic_metadata
.current_where_predicate
= previous_value
;
1112 fn visit_inline_asm(&mut self, asm
: &'ast InlineAsm
) {
1113 for (op
, _
) in &asm
.operands
{
1115 InlineAsmOperand
::In { expr, .. }
1116 | InlineAsmOperand
::Out { expr: Some(expr), .. }
1117 | InlineAsmOperand
::InOut { expr, .. }
=> self.visit_expr(expr
),
1118 InlineAsmOperand
::Out { expr: None, .. }
=> {}
1119 InlineAsmOperand
::SplitInOut { in_expr, out_expr, .. }
=> {
1120 self.visit_expr(in_expr
);
1121 if let Some(out_expr
) = out_expr
{
1122 self.visit_expr(out_expr
);
1125 InlineAsmOperand
::Const { anon_const, .. }
=> {
1126 // Although this is `DefKind::AnonConst`, it is allowed to reference outer
1127 // generic parameters like an inline const.
1128 self.resolve_inline_const(anon_const
);
1130 InlineAsmOperand
::Sym { sym }
=> self.visit_inline_asm_sym(sym
),
1135 fn visit_inline_asm_sym(&mut self, sym
: &'ast InlineAsmSym
) {
1136 // This is similar to the code for AnonConst.
1137 self.with_rib(ValueNS
, InlineAsmSymRibKind
, |this
| {
1138 this
.with_rib(TypeNS
, InlineAsmSymRibKind
, |this
| {
1139 this
.with_label_rib(InlineAsmSymRibKind
, |this
| {
1140 this
.smart_resolve_path(
1144 PathSource
::Expr(None
),
1146 visit
::walk_inline_asm_sym(this
, sym
);
1153 impl<'a
: 'ast
, 'b
, 'ast
> LateResolutionVisitor
<'a
, 'b
, 'ast
> {
1154 fn new(resolver
: &'b
mut Resolver
<'a
>) -> LateResolutionVisitor
<'a
, 'b
, 'ast
> {
1155 // During late resolution we only track the module component of the parent scope,
1156 // although it may be useful to track other components as well for diagnostics.
1157 let graph_root
= resolver
.graph_root
;
1158 let parent_scope
= ParentScope
::module(graph_root
, resolver
);
1159 let start_rib_kind
= ModuleRibKind(graph_root
);
1160 LateResolutionVisitor
{
1164 value_ns
: vec
![Rib
::new(start_rib_kind
)],
1165 type_ns
: vec
![Rib
::new(start_rib_kind
)],
1166 macro_ns
: vec
![Rib
::new(start_rib_kind
)],
1168 label_ribs
: Vec
::new(),
1169 lifetime_ribs
: Vec
::new(),
1170 lifetime_elision_candidates
: None
,
1171 current_trait_ref
: None
,
1172 diagnostic_metadata
: Box
::new(DiagnosticMetadata
::default()),
1173 // errors at module scope should always be reported
1174 in_func_body
: false,
1175 lifetime_uses
: Default
::default(),
1179 fn maybe_resolve_ident_in_lexical_scope(
1183 ) -> Option
<LexicalScopeBinding
<'a
>> {
1184 self.r
.resolve_ident_in_lexical_scope(
1194 fn resolve_ident_in_lexical_scope(
1198 finalize
: Option
<Finalize
>,
1199 ignore_binding
: Option
<&'a NameBinding
<'a
>>,
1200 ) -> Option
<LexicalScopeBinding
<'a
>> {
1201 self.r
.resolve_ident_in_lexical_scope(
1214 opt_ns
: Option
<Namespace
>, // `None` indicates a module path in import
1215 finalize
: Option
<Finalize
>,
1216 ) -> PathResult
<'a
> {
1217 self.r
.resolve_path_with_ribs(
1229 // We maintain a list of value ribs and type ribs.
1231 // Simultaneously, we keep track of the current position in the module
1232 // graph in the `parent_scope.module` pointer. When we go to resolve a name in
1233 // the value or type namespaces, we first look through all the ribs and
1234 // then query the module graph. When we resolve a name in the module
1235 // namespace, we can skip all the ribs (since nested modules are not
1236 // allowed within blocks in Rust) and jump straight to the current module
1239 // Named implementations are handled separately. When we find a method
1240 // call, we consult the module node to find all of the implementations in
1241 // scope. This information is lazily cached in the module node. We then
1242 // generate a fake "implementation scope" containing all the
1243 // implementations thus found, for compatibility with old resolve pass.
1245 /// Do some `work` within a new innermost rib of the given `kind` in the given namespace (`ns`).
1250 work
: impl FnOnce(&mut Self) -> T
,
1252 self.ribs
[ns
].push(Rib
::new(kind
));
1253 let ret
= work(self);
1254 self.ribs
[ns
].pop();
1258 fn with_scope
<T
>(&mut self, id
: NodeId
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
1259 if let Some(module
) = self.r
.get_module(self.r
.local_def_id(id
).to_def_id()) {
1260 // Move down in the graph.
1261 let orig_module
= replace(&mut self.parent_scope
.module
, module
);
1262 self.with_rib(ValueNS
, ModuleRibKind(module
), |this
| {
1263 this
.with_rib(TypeNS
, ModuleRibKind(module
), |this
| {
1265 this
.parent_scope
.module
= orig_module
;
1274 fn visit_generic_params(&mut self, params
: &'ast
[GenericParam
], add_self_upper
: bool
) {
1275 // For type parameter defaults, we have to ban access
1276 // to following type parameters, as the InternalSubsts can only
1277 // provide previous type parameters as they're built. We
1278 // put all the parameters on the ban list and then remove
1279 // them one by one as they are processed and become available.
1280 let mut forward_ty_ban_rib
= Rib
::new(ForwardGenericParamBanRibKind
);
1281 let mut forward_const_ban_rib
= Rib
::new(ForwardGenericParamBanRibKind
);
1282 for param
in params
.iter() {
1284 GenericParamKind
::Type { .. }
=> {
1287 .insert(Ident
::with_dummy_span(param
.ident
.name
), Res
::Err
);
1289 GenericParamKind
::Const { .. }
=> {
1290 forward_const_ban_rib
1292 .insert(Ident
::with_dummy_span(param
.ident
.name
), Res
::Err
);
1294 GenericParamKind
::Lifetime
=> {}
1298 // rust-lang/rust#61631: The type `Self` is essentially
1299 // another type parameter. For ADTs, we consider it
1300 // well-defined only after all of the ADT type parameters have
1301 // been provided. Therefore, we do not allow use of `Self`
1302 // anywhere in ADT type parameter defaults.
1304 // (We however cannot ban `Self` for defaults on *all* generic
1305 // lists; e.g. trait generics can usefully refer to `Self`,
1306 // such as in the case of `trait Add<Rhs = Self>`.)
1308 // (`Some` if + only if we are in ADT's generics.)
1309 forward_ty_ban_rib
.bindings
.insert(Ident
::with_dummy_span(kw
::SelfUpper
), Res
::Err
);
1312 self.with_lifetime_rib(LifetimeRibKind
::AnonymousReportError
, |this
| {
1313 for param
in params
{
1315 GenericParamKind
::Lifetime
=> {
1316 for bound
in ¶m
.bounds
{
1317 this
.visit_param_bound(bound
, BoundKind
::Bound
);
1320 GenericParamKind
::Type { ref default }
=> {
1321 for bound
in ¶m
.bounds
{
1322 this
.visit_param_bound(bound
, BoundKind
::Bound
);
1325 if let Some(ref ty
) = default {
1326 this
.ribs
[TypeNS
].push(forward_ty_ban_rib
);
1327 this
.ribs
[ValueNS
].push(forward_const_ban_rib
);
1329 forward_const_ban_rib
= this
.ribs
[ValueNS
].pop().unwrap();
1330 forward_ty_ban_rib
= this
.ribs
[TypeNS
].pop().unwrap();
1333 // Allow all following defaults to refer to this type parameter.
1336 .remove(&Ident
::with_dummy_span(param
.ident
.name
));
1338 GenericParamKind
::Const { ref ty, kw_span: _, ref default }
=> {
1339 // Const parameters can't have param bounds.
1340 assert
!(param
.bounds
.is_empty());
1342 this
.ribs
[TypeNS
].push(Rib
::new(ConstParamTyRibKind
));
1343 this
.ribs
[ValueNS
].push(Rib
::new(ConstParamTyRibKind
));
1344 this
.with_lifetime_rib(LifetimeRibKind
::ConstGeneric
, |this
| {
1347 this
.ribs
[TypeNS
].pop().unwrap();
1348 this
.ribs
[ValueNS
].pop().unwrap();
1350 if let Some(ref expr
) = default {
1351 this
.ribs
[TypeNS
].push(forward_ty_ban_rib
);
1352 this
.ribs
[ValueNS
].push(forward_const_ban_rib
);
1353 this
.with_lifetime_rib(LifetimeRibKind
::ConstGeneric
, |this
| {
1354 this
.resolve_anon_const(expr
, IsRepeatExpr
::No
)
1356 forward_const_ban_rib
= this
.ribs
[ValueNS
].pop().unwrap();
1357 forward_ty_ban_rib
= this
.ribs
[TypeNS
].pop().unwrap();
1360 // Allow all following defaults to refer to this const parameter.
1361 forward_const_ban_rib
1363 .remove(&Ident
::with_dummy_span(param
.ident
.name
));
1370 #[instrument(level = "debug", skip(self, work))]
1371 fn with_lifetime_rib
<T
>(
1373 kind
: LifetimeRibKind
,
1374 work
: impl FnOnce(&mut Self) -> T
,
1376 self.lifetime_ribs
.push(LifetimeRib
::new(kind
));
1377 let outer_elision_candidates
= self.lifetime_elision_candidates
.take();
1378 let ret
= work(self);
1379 self.lifetime_elision_candidates
= outer_elision_candidates
;
1380 self.lifetime_ribs
.pop();
1384 #[instrument(level = "debug", skip(self))]
1385 fn resolve_lifetime(&mut self, lifetime
: &'ast Lifetime
, use_ctxt
: visit
::LifetimeCtxt
) {
1386 let ident
= lifetime
.ident
;
1388 if ident
.name
== kw
::StaticLifetime
{
1389 self.record_lifetime_res(
1391 LifetimeRes
::Static
,
1392 LifetimeElisionCandidate
::Named
,
1397 if ident
.name
== kw
::UnderscoreLifetime
{
1398 return self.resolve_anonymous_lifetime(lifetime
, false);
1401 let mut lifetime_rib_iter
= self.lifetime_ribs
.iter().rev();
1402 while let Some(rib
) = lifetime_rib_iter
.next() {
1403 let normalized_ident
= ident
.normalize_to_macros_2_0();
1404 if let Some(&(_
, res
)) = rib
.bindings
.get(&normalized_ident
) {
1405 self.record_lifetime_res(lifetime
.id
, res
, LifetimeElisionCandidate
::Named
);
1407 if let LifetimeRes
::Param { param, .. }
= res
{
1408 match self.lifetime_uses
.entry(param
) {
1409 Entry
::Vacant(v
) => {
1410 debug
!("First use of {:?} at {:?}", res
, ident
.span
);
1415 .find_map(|rib
| match rib
.kind
{
1416 // Do not suggest eliding a lifetime where an anonymous
1417 // lifetime would be illegal.
1418 LifetimeRibKind
::Item
1419 | LifetimeRibKind
::AnonymousReportError
1420 | LifetimeRibKind
::ElisionFailure
=> Some(LifetimeUseSet
::Many
),
1421 // An anonymous lifetime is legal here, go ahead.
1422 LifetimeRibKind
::AnonymousCreateParameter { .. }
=> {
1423 Some(LifetimeUseSet
::One { use_span: ident.span, use_ctxt }
)
1425 // Only report if eliding the lifetime would have the same
1427 LifetimeRibKind
::Elided(r
) => Some(if res
== r
{
1428 LifetimeUseSet
::One { use_span: ident.span, use_ctxt }
1430 LifetimeUseSet
::Many
1432 LifetimeRibKind
::Generics { .. }
=> None
,
1433 LifetimeRibKind
::ConstGeneric
| LifetimeRibKind
::AnonConst
=> {
1434 span_bug
!(ident
.span
, "unexpected rib kind: {:?}", rib
.kind
)
1437 .unwrap_or(LifetimeUseSet
::Many
);
1438 debug
!(?use_ctxt
, ?use_set
);
1441 Entry
::Occupied(mut o
) => {
1442 debug
!("Many uses of {:?} at {:?}", res
, ident
.span
);
1443 *o
.get_mut() = LifetimeUseSet
::Many
;
1451 LifetimeRibKind
::Item
=> break,
1452 LifetimeRibKind
::ConstGeneric
=> {
1453 self.emit_non_static_lt_in_const_generic_error(lifetime
);
1454 self.record_lifetime_res(
1457 LifetimeElisionCandidate
::Ignore
,
1461 LifetimeRibKind
::AnonConst
=> {
1462 self.maybe_emit_forbidden_non_static_lifetime_error(lifetime
);
1463 self.record_lifetime_res(
1466 LifetimeElisionCandidate
::Ignore
,
1470 LifetimeRibKind
::AnonymousCreateParameter { .. }
1471 | LifetimeRibKind
::Elided(_
)
1472 | LifetimeRibKind
::Generics { .. }
1473 | LifetimeRibKind
::ElisionFailure
1474 | LifetimeRibKind
::AnonymousReportError
=> {}
1478 let mut outer_res
= None
;
1479 for rib
in lifetime_rib_iter
{
1480 let normalized_ident
= ident
.normalize_to_macros_2_0();
1481 if let Some((&outer
, _
)) = rib
.bindings
.get_key_value(&normalized_ident
) {
1482 outer_res
= Some(outer
);
1487 self.emit_undeclared_lifetime_error(lifetime
, outer_res
);
1488 self.record_lifetime_res(lifetime
.id
, LifetimeRes
::Error
, LifetimeElisionCandidate
::Named
);
1491 #[instrument(level = "debug", skip(self))]
1492 fn resolve_anonymous_lifetime(&mut self, lifetime
: &Lifetime
, elided
: bool
) {
1493 debug_assert_eq
!(lifetime
.ident
.name
, kw
::UnderscoreLifetime
);
1495 let missing_lifetime
= MissingLifetime
{
1497 span
: lifetime
.ident
.span
,
1499 MissingLifetimeKind
::Ampersand
1501 MissingLifetimeKind
::Underscore
1505 let elision_candidate
= LifetimeElisionCandidate
::Missing(missing_lifetime
);
1506 for rib
in self.lifetime_ribs
.iter().rev() {
1509 LifetimeRibKind
::AnonymousCreateParameter { binder, .. }
=> {
1510 let res
= self.create_fresh_lifetime(lifetime
.id
, lifetime
.ident
, binder
);
1511 self.record_lifetime_res(lifetime
.id
, res
, elision_candidate
);
1514 LifetimeRibKind
::AnonymousReportError
=> {
1515 let (msg
, note
) = if elided
{
1517 "`&` without an explicit lifetime name cannot be used here",
1518 "explicit lifetime name needed here",
1521 ("`'_` cannot be used here", "`'_` is a reserved lifetime name")
1523 rustc_errors
::struct_span_err
!(
1525 lifetime
.ident
.span
,
1530 .span_label(lifetime
.ident
.span
, note
)
1533 self.record_lifetime_res(lifetime
.id
, LifetimeRes
::Error
, elision_candidate
);
1536 LifetimeRibKind
::Elided(res
) => {
1537 self.record_lifetime_res(lifetime
.id
, res
, elision_candidate
);
1540 LifetimeRibKind
::ElisionFailure
=> {
1541 self.diagnostic_metadata
.current_elision_failures
.push(missing_lifetime
);
1542 self.record_lifetime_res(lifetime
.id
, LifetimeRes
::Error
, elision_candidate
);
1545 LifetimeRibKind
::Item
=> break,
1546 LifetimeRibKind
::Generics { .. }
| LifetimeRibKind
::ConstGeneric
=> {}
1547 LifetimeRibKind
::AnonConst
=> {
1548 // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
1549 span_bug
!(lifetime
.ident
.span
, "unexpected rib kind: {:?}", rib
.kind
)
1553 self.record_lifetime_res(lifetime
.id
, LifetimeRes
::Error
, elision_candidate
);
1554 self.report_missing_lifetime_specifiers(vec
![missing_lifetime
], None
);
1557 #[instrument(level = "debug", skip(self))]
1558 fn resolve_elided_lifetime(&mut self, anchor_id
: NodeId
, span
: Span
) {
1559 let id
= self.r
.next_node_id();
1560 let lt
= Lifetime { id, ident: Ident::new(kw::UnderscoreLifetime, span) }
;
1562 self.record_lifetime_res(
1564 LifetimeRes
::ElidedAnchor { start: id, end: NodeId::from_u32(id.as_u32() + 1) }
,
1565 LifetimeElisionCandidate
::Ignore
,
1567 self.resolve_anonymous_lifetime(<
, true);
1570 #[instrument(level = "debug", skip(self))]
1571 fn create_fresh_lifetime(&mut self, id
: NodeId
, ident
: Ident
, binder
: NodeId
) -> LifetimeRes
{
1572 debug_assert_eq
!(ident
.name
, kw
::UnderscoreLifetime
);
1573 debug
!(?ident
.span
);
1575 // Leave the responsibility to create the `LocalDefId` to lowering.
1576 let param
= self.r
.next_node_id();
1577 let res
= LifetimeRes
::Fresh { param, binder }
;
1579 // Record the created lifetime parameter so lowering can pick it up and add it to HIR.
1581 .extra_lifetime_params_map
1583 .or_insert_with(Vec
::new
)
1584 .push((ident
, param
, res
));
1588 #[instrument(level = "debug", skip(self))]
1589 fn resolve_elided_lifetimes_in_path(
1592 partial_res
: PartialRes
,
1594 source
: PathSource
<'_
>,
1597 let proj_start
= path
.len() - partial_res
.unresolved_segments();
1598 for (i
, segment
) in path
.iter().enumerate() {
1599 if segment
.has_lifetime_args
{
1602 let Some(segment_id
) = segment
.id
else {
1606 // Figure out if this is a type/trait segment,
1607 // which may need lifetime elision performed.
1608 let type_def_id
= match partial_res
.base_res() {
1609 Res
::Def(DefKind
::AssocTy
, def_id
) if i
+ 2 == proj_start
=> self.r
.parent(def_id
),
1610 Res
::Def(DefKind
::Variant
, def_id
) if i
+ 1 == proj_start
=> self.r
.parent(def_id
),
1611 Res
::Def(DefKind
::Struct
, def_id
)
1612 | Res
::Def(DefKind
::Union
, def_id
)
1613 | Res
::Def(DefKind
::Enum
, def_id
)
1614 | Res
::Def(DefKind
::TyAlias
, def_id
)
1615 | Res
::Def(DefKind
::Trait
, def_id
)
1616 if i
+ 1 == proj_start
=>
1623 let expected_lifetimes
= self.r
.item_generics_num_lifetimes(type_def_id
);
1624 if expected_lifetimes
== 0 {
1628 let node_ids
= self.r
.next_node_ids(expected_lifetimes
);
1629 self.record_lifetime_res(
1631 LifetimeRes
::ElidedAnchor { start: node_ids.start, end: node_ids.end }
,
1632 LifetimeElisionCandidate
::Ignore
,
1635 let inferred
= match source
{
1636 PathSource
::Trait(..) | PathSource
::TraitItem(..) | PathSource
::Type
=> false,
1637 PathSource
::Expr(..)
1639 | PathSource
::Struct
1640 | PathSource
::TupleStruct(..) => true,
1643 // Do not create a parameter for patterns and expressions: type checking can infer
1644 // the appropriate lifetime for us.
1645 for id
in node_ids
{
1646 self.record_lifetime_res(
1649 LifetimeElisionCandidate
::Named
,
1655 let elided_lifetime_span
= if segment
.has_generic_args
{
1656 // If there are brackets, but not generic arguments, then use the opening bracket
1657 segment
.args_span
.with_hi(segment
.args_span
.lo() + BytePos(1))
1659 // If there are no brackets, use the identifier span.
1660 // HACK: we use find_ancestor_inside to properly suggest elided spans in paths
1661 // originating from macros, since the segment's span might be from a macro arg.
1662 segment
.ident
.span
.find_ancestor_inside(path_span
).unwrap_or(path_span
)
1664 let ident
= Ident
::new(kw
::UnderscoreLifetime
, elided_lifetime_span
);
1666 let missing_lifetime
= MissingLifetime
{
1668 span
: elided_lifetime_span
,
1669 kind
: if segment
.has_generic_args
{
1670 MissingLifetimeKind
::Comma
1672 MissingLifetimeKind
::Brackets
1674 count
: expected_lifetimes
,
1676 let mut should_lint
= true;
1677 for rib
in self.lifetime_ribs
.iter().rev() {
1679 // In create-parameter mode we error here because we don't want to support
1680 // deprecated impl elision in new features like impl elision and `async fn`,
1681 // both of which work using the `CreateParameter` mode:
1683 // impl Foo for std::cell::Ref<u32> // note lack of '_
1684 // async fn foo(_: std::cell::Ref<u32>) { ... }
1685 LifetimeRibKind
::AnonymousCreateParameter { report_in_path: true, .. }
=> {
1686 let sess
= self.r
.session
;
1687 let mut err
= rustc_errors
::struct_span_err
!(
1691 "implicit elided lifetime not allowed here"
1693 rustc_errors
::add_elided_lifetime_in_path_suggestion(
1698 !segment
.has_generic_args
,
1699 elided_lifetime_span
,
1701 err
.note("assuming a `'static` lifetime...");
1703 should_lint
= false;
1705 for id
in node_ids
{
1706 self.record_lifetime_res(
1709 LifetimeElisionCandidate
::Named
,
1714 // Do not create a parameter for patterns and expressions.
1715 LifetimeRibKind
::AnonymousCreateParameter { binder, .. }
=> {
1716 // Group all suggestions into the first record.
1717 let mut candidate
= LifetimeElisionCandidate
::Missing(missing_lifetime
);
1718 for id
in node_ids
{
1719 let res
= self.create_fresh_lifetime(id
, ident
, binder
);
1720 self.record_lifetime_res(
1723 replace(&mut candidate
, LifetimeElisionCandidate
::Named
),
1728 LifetimeRibKind
::Elided(res
) => {
1729 let mut candidate
= LifetimeElisionCandidate
::Missing(missing_lifetime
);
1730 for id
in node_ids
{
1731 self.record_lifetime_res(
1734 replace(&mut candidate
, LifetimeElisionCandidate
::Ignore
),
1739 LifetimeRibKind
::ElisionFailure
=> {
1740 self.diagnostic_metadata
.current_elision_failures
.push(missing_lifetime
);
1741 for id
in node_ids
{
1742 self.record_lifetime_res(
1745 LifetimeElisionCandidate
::Ignore
,
1750 // `LifetimeRes::Error`, which would usually be used in the case of
1751 // `ReportError`, is unsuitable here, as we don't emit an error yet. Instead,
1752 // we simply resolve to an implicit lifetime, which will be checked later, at
1753 // which point a suitable error will be emitted.
1754 LifetimeRibKind
::AnonymousReportError
| LifetimeRibKind
::Item
=> {
1755 for id
in node_ids
{
1756 self.record_lifetime_res(
1759 LifetimeElisionCandidate
::Ignore
,
1762 self.report_missing_lifetime_specifiers(vec
![missing_lifetime
], None
);
1765 LifetimeRibKind
::Generics { .. }
| LifetimeRibKind
::ConstGeneric
=> {}
1766 LifetimeRibKind
::AnonConst
=> {
1767 // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
1768 span_bug
!(elided_lifetime_span
, "unexpected rib kind: {:?}", rib
.kind
)
1774 self.r
.lint_buffer
.buffer_lint_with_diagnostic(
1775 lint
::builtin
::ELIDED_LIFETIMES_IN_PATHS
,
1777 elided_lifetime_span
,
1778 "hidden lifetime parameters in types are deprecated",
1779 lint
::BuiltinLintDiagnostics
::ElidedLifetimesInPaths(
1782 !segment
.has_generic_args
,
1783 elided_lifetime_span
,
1790 #[instrument(level = "debug", skip(self))]
1791 fn record_lifetime_res(
1795 candidate
: LifetimeElisionCandidate
,
1797 if let Some(prev_res
) = self.r
.lifetimes_res_map
.insert(id
, res
) {
1799 "lifetime {:?} resolved multiple times ({:?} before, {:?} now)",
1804 LifetimeRes
::Param { .. }
| LifetimeRes
::Fresh { .. }
| LifetimeRes
::Static
=> {
1805 if let Some(ref mut candidates
) = self.lifetime_elision_candidates
{
1806 candidates
.push((res
, candidate
));
1809 LifetimeRes
::Infer
| LifetimeRes
::Error
| LifetimeRes
::ElidedAnchor { .. }
=> {}
1813 #[instrument(level = "debug", skip(self))]
1814 fn record_lifetime_param(&mut self, id
: NodeId
, res
: LifetimeRes
) {
1815 if let Some(prev_res
) = self.r
.lifetimes_res_map
.insert(id
, res
) {
1817 "lifetime parameter {:?} resolved multiple times ({:?} before, {:?} now)",
1823 /// Perform resolution of a function signature, accounting for lifetime elision.
1824 #[instrument(level = "debug", skip(self, inputs))]
1825 fn resolve_fn_signature(
1829 inputs
: impl Iterator
<Item
= (Option
<&'ast Pat
>, &'ast Ty
)> + Clone
,
1830 output_ty
: &'ast FnRetTy
,
1832 // Add each argument to the rib.
1833 let elision_lifetime
= self.resolve_fn_params(has_self
, inputs
);
1834 debug
!(?elision_lifetime
);
1836 let outer_failures
= take(&mut self.diagnostic_metadata
.current_elision_failures
);
1837 let output_rib
= if let Ok(res
) = elision_lifetime
.as_ref() {
1838 LifetimeRibKind
::Elided(*res
)
1840 LifetimeRibKind
::ElisionFailure
1842 self.with_lifetime_rib(output_rib
, |this
| visit
::walk_fn_ret_ty(this
, &output_ty
));
1843 let elision_failures
=
1844 replace(&mut self.diagnostic_metadata
.current_elision_failures
, outer_failures
);
1845 if !elision_failures
.is_empty() {
1846 let Err(failure_info
) = elision_lifetime
else { bug!() }
;
1847 self.report_missing_lifetime_specifiers(elision_failures
, Some(failure_info
));
1851 /// Resolve inside function parameters and parameter types.
1852 /// Returns the lifetime for elision in fn return type,
1853 /// or diagnostic information in case of elision failure.
1854 fn resolve_fn_params(
1857 inputs
: impl Iterator
<Item
= (Option
<&'ast Pat
>, &'ast Ty
)>,
1858 ) -> Result
<LifetimeRes
, (Vec
<MissingLifetime
>, Vec
<ElisionFnParameter
>)> {
1860 /// We have not found any candidate.
1862 /// We have a candidate bound to `self`.
1864 /// We have a candidate bound to a parameter.
1866 /// We failed elision.
1870 // Save elision state to reinstate it later.
1871 let outer_candidates
= self.lifetime_elision_candidates
.take();
1873 // Result of elision.
1874 let mut elision_lifetime
= Elision
::None
;
1875 // Information for diagnostics.
1876 let mut parameter_info
= Vec
::new();
1877 let mut all_candidates
= Vec
::new();
1879 let mut bindings
= smallvec
![(PatBoundCtx
::Product
, Default
::default())];
1880 for (index
, (pat
, ty
)) in inputs
.enumerate() {
1882 self.with_lifetime_rib(LifetimeRibKind
::Elided(LifetimeRes
::Infer
), |this
| {
1883 if let Some(pat
) = pat
{
1884 this
.resolve_pattern(pat
, PatternSource
::FnParam
, &mut bindings
);
1888 // Record elision candidates only for this parameter.
1889 debug_assert_matches
!(self.lifetime_elision_candidates
, None
);
1890 self.lifetime_elision_candidates
= Some(Default
::default());
1892 let local_candidates
= self.lifetime_elision_candidates
.take();
1894 if let Some(candidates
) = local_candidates
{
1895 let distinct
: FxHashSet
<_
> = candidates
.iter().map(|(res
, _
)| *res
).collect();
1896 let lifetime_count
= distinct
.len();
1897 if lifetime_count
!= 0 {
1898 parameter_info
.push(ElisionFnParameter
{
1900 ident
: if let Some(pat
) = pat
&& let PatKind
::Ident(_
, ident
, _
) = pat
.kind
{
1908 all_candidates
.extend(candidates
.into_iter().filter_map(|(_
, candidate
)| {
1910 LifetimeElisionCandidate
::Ignore
| LifetimeElisionCandidate
::Named
=> {
1913 LifetimeElisionCandidate
::Missing(missing
) => Some(missing
),
1917 let mut distinct_iter
= distinct
.into_iter();
1918 if let Some(res
) = distinct_iter
.next() {
1919 match elision_lifetime
{
1920 // We are the first parameter to bind lifetimes.
1922 if distinct_iter
.next().is_none() {
1923 // We have a single lifetime => success.
1924 elision_lifetime
= Elision
::Param(res
)
1926 // We have have multiple lifetimes => error.
1927 elision_lifetime
= Elision
::Err
;
1930 // We have 2 parameters that bind lifetimes => error.
1931 Elision
::Param(_
) => elision_lifetime
= Elision
::Err
,
1932 // `self` elision takes precedence over everything else.
1933 Elision
::Self_(_
) | Elision
::Err
=> {}
1938 // Handle `self` specially.
1939 if index
== 0 && has_self
{
1940 let self_lifetime
= self.find_lifetime_for_self(ty
);
1941 if let Set1
::One(lifetime
) = self_lifetime
{
1942 // We found `self` elision.
1943 elision_lifetime
= Elision
::Self_(lifetime
);
1945 // We do not have `self` elision: disregard the `Elision::Param` that we may
1947 elision_lifetime
= Elision
::None
;
1950 debug
!("(resolving function / closure) recorded parameter");
1953 // Reinstate elision state.
1954 debug_assert_matches
!(self.lifetime_elision_candidates
, None
);
1955 self.lifetime_elision_candidates
= outer_candidates
;
1957 if let Elision
::Param(res
) | Elision
::Self_(res
) = elision_lifetime
{
1961 // We do not have a candidate.
1962 Err((all_candidates
, parameter_info
))
1965 /// List all the lifetimes that appear in the provided type.
1966 fn find_lifetime_for_self(&self, ty
: &'ast Ty
) -> Set1
<LifetimeRes
> {
1967 struct SelfVisitor
<'r
, 'a
> {
1968 r
: &'r Resolver
<'a
>,
1969 impl_self
: Option
<Res
>,
1970 lifetime
: Set1
<LifetimeRes
>,
1973 impl SelfVisitor
<'_
, '_
> {
1974 // Look for `self: &'a Self` - also desugared from `&'a self`,
1975 // and if that matches, use it for elision and return early.
1976 fn is_self_ty(&self, ty
: &Ty
) -> bool
{
1978 TyKind
::ImplicitSelf
=> true,
1979 TyKind
::Path(None
, _
) => {
1980 let path_res
= self.r
.partial_res_map
[&ty
.id
].full_res();
1981 if let Some(Res
::SelfTyParam { .. }
| Res
::SelfTyAlias { .. }
) = path_res
{
1984 self.impl_self
.is_some() && path_res
== self.impl_self
1991 impl<'a
> Visitor
<'a
> for SelfVisitor
<'_
, '_
> {
1992 fn visit_ty(&mut self, ty
: &'a Ty
) {
1993 trace
!("SelfVisitor considering ty={:?}", ty
);
1994 if let TyKind
::Rptr(lt
, ref mt
) = ty
.kind
&& self.is_self_ty(&mt
.ty
) {
1995 let lt_id
= if let Some(lt
) = lt
{
1998 let res
= self.r
.lifetimes_res_map
[&ty
.id
];
1999 let LifetimeRes
::ElidedAnchor { start, .. }
= res
else { bug!() }
;
2002 let lt_res
= self.r
.lifetimes_res_map
[<_id
];
2003 trace
!("SelfVisitor inserting res={:?}", lt_res
);
2004 self.lifetime
.insert(lt_res
);
2006 visit
::walk_ty(self, ty
)
2010 let impl_self
= self
2011 .diagnostic_metadata
2015 if let TyKind
::Path(None
, _
) = ty
.kind
{
2016 self.r
.partial_res_map
.get(&ty
.id
)
2021 .and_then(|res
| res
.full_res())
2023 // Permit the types that unambiguously always
2024 // result in the same type constructor being used
2025 // (it can't differ between `Self` and `self`).
2028 Res
::Def(DefKind
::Struct
| DefKind
::Union
| DefKind
::Enum
, _
,) | Res
::PrimTy(_
)
2031 let mut visitor
= SelfVisitor { r: self.r, impl_self, lifetime: Set1::Empty }
;
2032 visitor
.visit_ty(ty
);
2033 trace
!("SelfVisitor found={:?}", visitor
.lifetime
);
2037 /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
2038 /// label and reports an error if the label is not found or is unreachable.
2039 fn resolve_label(&mut self, mut label
: Ident
) -> Result
<(NodeId
, Span
), ResolutionError
<'a
>> {
2040 let mut suggestion
= None
;
2042 for i
in (0..self.label_ribs
.len()).rev() {
2043 let rib
= &self.label_ribs
[i
];
2045 if let MacroDefinition(def
) = rib
.kind
{
2046 // If an invocation of this macro created `ident`, give up on `ident`
2047 // and switch to `ident`'s source from the macro definition.
2048 if def
== self.r
.macro_def(label
.span
.ctxt()) {
2049 label
.span
.remove_mark();
2053 let ident
= label
.normalize_to_macro_rules();
2054 if let Some((ident
, id
)) = rib
.bindings
.get_key_value(&ident
) {
2055 let definition_span
= ident
.span
;
2056 return if self.is_label_valid_from_rib(i
) {
2057 Ok((*id
, definition_span
))
2059 Err(ResolutionError
::UnreachableLabel
{
2067 // Diagnostics: Check if this rib contains a label with a similar name, keep track of
2068 // the first such label that is encountered.
2069 suggestion
= suggestion
.or_else(|| self.suggestion_for_label_in_rib(i
, label
));
2072 Err(ResolutionError
::UndeclaredLabel { name: label.name, suggestion }
)
2075 /// Determine whether or not a label from the `rib_index`th label rib is reachable.
2076 fn is_label_valid_from_rib(&self, rib_index
: usize) -> bool
{
2077 let ribs
= &self.label_ribs
[rib_index
+ 1..];
2080 if rib
.kind
.is_label_barrier() {
2088 fn resolve_adt(&mut self, item
: &'ast Item
, generics
: &'ast Generics
) {
2089 debug
!("resolve_adt");
2090 self.with_current_self_item(item
, |this
| {
2091 this
.with_generic_param_rib(
2093 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
2094 LifetimeRibKind
::Generics
{
2096 kind
: LifetimeBinderKind
::Item
,
2097 span
: generics
.span
,
2100 let item_def_id
= this
.r
.local_def_id(item
.id
).to_def_id();
2103 alias_to
: item_def_id
,
2104 forbid_generic
: false,
2105 is_trait_impl
: false,
2108 visit
::walk_item(this
, item
);
2116 fn future_proof_import(&mut self, use_tree
: &UseTree
) {
2117 let segments
= &use_tree
.prefix
.segments
;
2118 if !segments
.is_empty() {
2119 let ident
= segments
[0].ident
;
2120 if ident
.is_path_segment_keyword() || ident
.span
.rust_2015() {
2124 let nss
= match use_tree
.kind
{
2125 UseTreeKind
::Simple(..) if segments
.len() == 1 => &[TypeNS
, ValueNS
][..],
2128 let report_error
= |this
: &Self, ns
| {
2129 let what
= if ns
== TypeNS { "type parameters" }
else { "local variables" }
;
2130 if this
.should_report_errs() {
2133 .span_err(ident
.span
, &format
!("imports cannot refer to {}", what
));
2138 match self.maybe_resolve_ident_in_lexical_scope(ident
, ns
) {
2139 Some(LexicalScopeBinding
::Res(..)) => {
2140 report_error(self, ns
);
2142 Some(LexicalScopeBinding
::Item(binding
)) => {
2143 if let Some(LexicalScopeBinding
::Res(..)) =
2144 self.resolve_ident_in_lexical_scope(ident
, ns
, None
, Some(binding
))
2146 report_error(self, ns
);
2152 } else if let UseTreeKind
::Nested(use_trees
) = &use_tree
.kind
{
2153 for (use_tree
, _
) in use_trees
{
2154 self.future_proof_import(use_tree
);
2159 fn resolve_item(&mut self, item
: &'ast Item
) {
2160 let name
= item
.ident
.name
;
2161 debug
!("(resolving item) resolving {} ({:?})", name
, item
.kind
);
2164 ItemKind
::TyAlias(box TyAlias { ref generics, .. }
) => {
2165 self.with_generic_param_rib(
2167 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
2168 LifetimeRibKind
::Generics
{
2170 kind
: LifetimeBinderKind
::Item
,
2171 span
: generics
.span
,
2173 |this
| visit
::walk_item(this
, item
),
2177 ItemKind
::Fn(box Fn { ref generics, .. }
) => {
2178 self.with_generic_param_rib(
2180 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
2181 LifetimeRibKind
::Generics
{
2183 kind
: LifetimeBinderKind
::Function
,
2184 span
: generics
.span
,
2186 |this
| visit
::walk_item(this
, item
),
2190 ItemKind
::Enum(_
, ref generics
)
2191 | ItemKind
::Struct(_
, ref generics
)
2192 | ItemKind
::Union(_
, ref generics
) => {
2193 self.resolve_adt(item
, generics
);
2196 ItemKind
::Impl(box Impl
{
2200 items
: ref impl_items
,
2203 self.diagnostic_metadata
.current_impl_items
= Some(impl_items
);
2204 self.resolve_implementation(generics
, of_trait
, &self_ty
, item
.id
, impl_items
);
2205 self.diagnostic_metadata
.current_impl_items
= None
;
2208 ItemKind
::Trait(box Trait { ref generics, ref bounds, ref items, .. }
) => {
2209 // Create a new rib for the trait-wide type parameters.
2210 self.with_generic_param_rib(
2212 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
2213 LifetimeRibKind
::Generics
{
2215 kind
: LifetimeBinderKind
::Item
,
2216 span
: generics
.span
,
2219 let local_def_id
= this
.r
.local_def_id(item
.id
).to_def_id();
2220 this
.with_self_rib(Res
::SelfTyParam { trait_: local_def_id }
, |this
| {
2221 this
.visit_generics(generics
);
2222 walk_list
!(this
, visit_param_bound
, bounds
, BoundKind
::SuperTraits
);
2223 this
.resolve_trait_items(items
);
2229 ItemKind
::TraitAlias(ref generics
, ref bounds
) => {
2230 // Create a new rib for the trait-wide type parameters.
2231 self.with_generic_param_rib(
2233 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
2234 LifetimeRibKind
::Generics
{
2236 kind
: LifetimeBinderKind
::Item
,
2237 span
: generics
.span
,
2240 let local_def_id
= this
.r
.local_def_id(item
.id
).to_def_id();
2241 this
.with_self_rib(Res
::SelfTyParam { trait_: local_def_id }
, |this
| {
2242 this
.visit_generics(generics
);
2243 walk_list
!(this
, visit_param_bound
, bounds
, BoundKind
::Bound
);
2249 ItemKind
::Mod(..) | ItemKind
::ForeignMod(_
) => {
2250 self.with_scope(item
.id
, |this
| {
2251 visit
::walk_item(this
, item
);
2255 ItemKind
::Static(ref ty
, _
, ref expr
) | ItemKind
::Const(_
, ref ty
, ref expr
) => {
2256 self.with_static_rib(|this
| {
2257 this
.with_lifetime_rib(LifetimeRibKind
::Elided(LifetimeRes
::Static
), |this
| {
2260 this
.with_lifetime_rib(LifetimeRibKind
::Elided(LifetimeRes
::Infer
), |this
| {
2261 if let Some(expr
) = expr
{
2262 let constant_item_kind
= match item
.kind
{
2263 ItemKind
::Const(..) => ConstantItemKind
::Const
,
2264 ItemKind
::Static(..) => ConstantItemKind
::Static
,
2265 _
=> unreachable
!(),
2267 // We already forbid generic params because of the above item rib,
2268 // so it doesn't matter whether this is a trivial constant.
2269 this
.with_constant_rib(
2271 ConstantHasGenerics
::Yes
,
2272 Some((item
.ident
, constant_item_kind
)),
2273 |this
| this
.visit_expr(expr
),
2280 ItemKind
::Use(ref use_tree
) => {
2281 self.future_proof_import(use_tree
);
2284 ItemKind
::ExternCrate(..) | ItemKind
::MacroDef(..) => {
2285 // do nothing, these are just around to be encoded
2288 ItemKind
::GlobalAsm(_
) => {
2289 visit
::walk_item(self, item
);
2292 ItemKind
::MacCall(_
) => panic
!("unexpanded macro in resolve!"),
2296 fn with_generic_param_rib
<'c
, F
>(
2298 params
: &'c
[GenericParam
],
2300 lifetime_kind
: LifetimeRibKind
,
2303 F
: FnOnce(&mut Self),
2305 debug
!("with_generic_param_rib");
2306 let LifetimeRibKind
::Generics { binder, span: generics_span, kind: generics_kind, .. }
2307 = lifetime_kind
else { panic!() }
;
2309 let mut function_type_rib
= Rib
::new(kind
);
2310 let mut function_value_rib
= Rib
::new(kind
);
2311 let mut function_lifetime_rib
= LifetimeRib
::new(lifetime_kind
);
2312 let mut seen_bindings
= FxHashMap
::default();
2313 // Store all seen lifetimes names from outer scopes.
2314 let mut seen_lifetimes
= FxHashSet
::default();
2316 // We also can't shadow bindings from the parent item
2317 if let AssocItemRibKind
= kind
{
2318 let mut add_bindings_for_ns
= |ns
| {
2319 let parent_rib
= self.ribs
[ns
]
2321 .rfind(|r
| matches
!(r
.kind
, ItemRibKind(_
)))
2322 .expect("associated item outside of an item");
2324 .extend(parent_rib
.bindings
.iter().map(|(ident
, _
)| (*ident
, ident
.span
)));
2326 add_bindings_for_ns(ValueNS
);
2327 add_bindings_for_ns(TypeNS
);
2330 // Forbid shadowing lifetime bindings
2331 for rib
in self.lifetime_ribs
.iter().rev() {
2332 seen_lifetimes
.extend(rib
.bindings
.iter().map(|(ident
, _
)| *ident
));
2333 if let LifetimeRibKind
::Item
= rib
.kind
{
2338 for param
in params
{
2339 let ident
= param
.ident
.normalize_to_macros_2_0();
2340 debug
!("with_generic_param_rib: {}", param
.id
);
2342 if let GenericParamKind
::Lifetime
= param
.kind
2343 && let Some(&original
) = seen_lifetimes
.get(&ident
)
2345 diagnostics
::signal_lifetime_shadowing(self.r
.session
, original
, param
.ident
);
2346 // Record lifetime res, so lowering knows there is something fishy.
2347 self.record_lifetime_param(param
.id
, LifetimeRes
::Error
);
2351 match seen_bindings
.entry(ident
) {
2352 Entry
::Occupied(entry
) => {
2353 let span
= *entry
.get();
2354 let err
= ResolutionError
::NameAlreadyUsedInParameterList(ident
.name
, span
);
2355 self.report_error(param
.ident
.span
, err
);
2356 if let GenericParamKind
::Lifetime
= param
.kind
{
2357 // Record lifetime res, so lowering knows there is something fishy.
2358 self.record_lifetime_param(param
.id
, LifetimeRes
::Error
);
2362 Entry
::Vacant(entry
) => {
2363 entry
.insert(param
.ident
.span
);
2367 if param
.ident
.name
== kw
::UnderscoreLifetime
{
2368 rustc_errors
::struct_span_err
!(
2372 "`'_` cannot be used here"
2374 .span_label(param
.ident
.span
, "`'_` is a reserved lifetime name")
2376 // Record lifetime res, so lowering knows there is something fishy.
2377 self.record_lifetime_param(param
.id
, LifetimeRes
::Error
);
2381 if param
.ident
.name
== kw
::StaticLifetime
{
2382 rustc_errors
::struct_span_err
!(
2386 "invalid lifetime parameter name: `{}`",
2389 .span_label(param
.ident
.span
, "'static is a reserved lifetime name")
2391 // Record lifetime res, so lowering knows there is something fishy.
2392 self.record_lifetime_param(param
.id
, LifetimeRes
::Error
);
2396 let def_id
= self.r
.local_def_id(param
.id
);
2398 // Plain insert (no renaming).
2399 let (rib
, def_kind
) = match param
.kind
{
2400 GenericParamKind
::Type { .. }
=> (&mut function_type_rib
, DefKind
::TyParam
),
2401 GenericParamKind
::Const { .. }
=> (&mut function_value_rib
, DefKind
::ConstParam
),
2402 GenericParamKind
::Lifetime
=> {
2403 let res
= LifetimeRes
::Param { param: def_id, binder }
;
2404 self.record_lifetime_param(param
.id
, res
);
2405 function_lifetime_rib
.bindings
.insert(ident
, (param
.id
, res
));
2410 let res
= match kind
{
2411 ItemRibKind(..) | AssocItemRibKind
=> Res
::Def(def_kind
, def_id
.to_def_id()),
2412 NormalRibKind
=> Res
::Err
,
2413 _
=> span_bug
!(param
.ident
.span
, "Unexpected rib kind {:?}", kind
),
2415 self.r
.record_partial_res(param
.id
, PartialRes
::new(res
));
2416 rib
.bindings
.insert(ident
, res
);
2419 self.lifetime_ribs
.push(function_lifetime_rib
);
2420 self.ribs
[ValueNS
].push(function_value_rib
);
2421 self.ribs
[TypeNS
].push(function_type_rib
);
2425 self.ribs
[TypeNS
].pop();
2426 self.ribs
[ValueNS
].pop();
2427 let function_lifetime_rib
= self.lifetime_ribs
.pop().unwrap();
2429 // Do not account for the parameters we just bound for function lifetime elision.
2430 if let Some(ref mut candidates
) = self.lifetime_elision_candidates
{
2431 for (_
, res
) in function_lifetime_rib
.bindings
.values() {
2432 candidates
.retain(|(r
, _
)| r
!= res
);
2436 if let LifetimeBinderKind
::BareFnType
2437 | LifetimeBinderKind
::WhereBound
2438 | LifetimeBinderKind
::Function
2439 | LifetimeBinderKind
::ImplBlock
= generics_kind
2441 self.maybe_report_lifetime_uses(generics_span
, params
)
2445 fn with_label_rib(&mut self, kind
: RibKind
<'a
>, f
: impl FnOnce(&mut Self)) {
2446 self.label_ribs
.push(Rib
::new(kind
));
2448 self.label_ribs
.pop();
2451 fn with_static_rib(&mut self, f
: impl FnOnce(&mut Self)) {
2452 let kind
= ItemRibKind(HasGenericParams
::No
);
2453 self.with_rib(ValueNS
, kind
, |this
| this
.with_rib(TypeNS
, kind
, f
))
2456 // HACK(min_const_generics,const_evaluatable_unchecked): We
2457 // want to keep allowing `[0; std::mem::size_of::<*mut T>()]`
2458 // with a future compat lint for now. We do this by adding an
2459 // additional special case for repeat expressions.
2461 // Note that we intentionally still forbid `[0; N + 1]` during
2462 // name resolution so that we don't extend the future
2463 // compat lint to new cases.
2464 #[instrument(level = "debug", skip(self, f))]
2465 fn with_constant_rib(
2467 is_repeat
: IsRepeatExpr
,
2468 may_use_generics
: ConstantHasGenerics
,
2469 item
: Option
<(Ident
, ConstantItemKind
)>,
2470 f
: impl FnOnce(&mut Self),
2472 self.with_rib(ValueNS
, ConstantItemRibKind(may_use_generics
, item
), |this
| {
2475 ConstantItemRibKind(
2476 may_use_generics
.force_yes_if(is_repeat
== IsRepeatExpr
::Yes
),
2480 this
.with_label_rib(ConstantItemRibKind(may_use_generics
, item
), f
);
2486 fn with_current_self_type
<T
>(&mut self, self_type
: &Ty
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
2487 // Handle nested impls (inside fn bodies)
2488 let previous_value
=
2489 replace(&mut self.diagnostic_metadata
.current_self_type
, Some(self_type
.clone()));
2490 let result
= f(self);
2491 self.diagnostic_metadata
.current_self_type
= previous_value
;
2495 fn with_current_self_item
<T
>(&mut self, self_item
: &Item
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
2496 let previous_value
=
2497 replace(&mut self.diagnostic_metadata
.current_self_item
, Some(self_item
.id
));
2498 let result
= f(self);
2499 self.diagnostic_metadata
.current_self_item
= previous_value
;
2503 /// When evaluating a `trait` use its associated types' idents for suggestions in E0412.
2504 fn resolve_trait_items(&mut self, trait_items
: &'ast
[P
<AssocItem
>]) {
2505 let trait_assoc_items
=
2506 replace(&mut self.diagnostic_metadata
.current_trait_assoc_items
, Some(&trait_items
));
2508 let walk_assoc_item
=
2509 |this
: &mut Self, generics
: &Generics
, kind
, item
: &'ast AssocItem
| {
2510 this
.with_generic_param_rib(
2513 LifetimeRibKind
::Generics { binder: item.id, span: generics.span, kind }
,
2514 |this
| visit
::walk_assoc_item(this
, item
, AssocCtxt
::Trait
),
2518 for item
in trait_items
{
2520 AssocItemKind
::Const(_
, ty
, default) => {
2522 // Only impose the restrictions of `ConstRibKind` for an
2523 // actual constant expression in a provided default.
2524 if let Some(expr
) = default {
2525 // We allow arbitrary const expressions inside of associated consts,
2526 // even if they are potentially not const evaluatable.
2528 // Type parameters can already be used and as associated consts are
2529 // not used as part of the type system, this is far less surprising.
2530 self.with_lifetime_rib(
2531 LifetimeRibKind
::Elided(LifetimeRes
::Infer
),
2533 this
.with_constant_rib(
2535 ConstantHasGenerics
::Yes
,
2537 |this
| this
.visit_expr(expr
),
2543 AssocItemKind
::Fn(box Fn { generics, .. }
) => {
2544 walk_assoc_item(self, generics
, LifetimeBinderKind
::Function
, item
);
2546 AssocItemKind
::Type(box TyAlias { generics, .. }
) => self
2547 .with_lifetime_rib(LifetimeRibKind
::AnonymousReportError
, |this
| {
2548 walk_assoc_item(this
, generics
, LifetimeBinderKind
::Item
, item
)
2550 AssocItemKind
::MacCall(_
) => {
2551 panic
!("unexpanded macro in resolve!")
2556 self.diagnostic_metadata
.current_trait_assoc_items
= trait_assoc_items
;
2559 /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`).
2560 fn with_optional_trait_ref
<T
>(
2562 opt_trait_ref
: Option
<&TraitRef
>,
2563 self_type
: &'ast Ty
,
2564 f
: impl FnOnce(&mut Self, Option
<DefId
>) -> T
,
2566 let mut new_val
= None
;
2567 let mut new_id
= None
;
2568 if let Some(trait_ref
) = opt_trait_ref
{
2569 let path
: Vec
<_
> = Segment
::from_path(&trait_ref
.path
);
2570 self.diagnostic_metadata
.currently_processing_impl_trait
=
2571 Some((trait_ref
.clone(), self_type
.clone()));
2572 let res
= self.smart_resolve_path_fragment(
2575 PathSource
::Trait(AliasPossibility
::No
),
2576 Finalize
::new(trait_ref
.ref_id
, trait_ref
.path
.span
),
2578 self.diagnostic_metadata
.currently_processing_impl_trait
= None
;
2579 if let Some(def_id
) = res
.expect_full_res().opt_def_id() {
2580 new_id
= Some(def_id
);
2581 new_val
= Some((self.r
.expect_module(def_id
), trait_ref
.clone()));
2584 let original_trait_ref
= replace(&mut self.current_trait_ref
, new_val
);
2585 let result
= f(self, new_id
);
2586 self.current_trait_ref
= original_trait_ref
;
2590 fn with_self_rib_ns(&mut self, ns
: Namespace
, self_res
: Res
, f
: impl FnOnce(&mut Self)) {
2591 let mut self_type_rib
= Rib
::new(NormalRibKind
);
2593 // Plain insert (no renaming, since types are not currently hygienic)
2594 self_type_rib
.bindings
.insert(Ident
::with_dummy_span(kw
::SelfUpper
), self_res
);
2595 self.ribs
[ns
].push(self_type_rib
);
2597 self.ribs
[ns
].pop();
2600 fn with_self_rib(&mut self, self_res
: Res
, f
: impl FnOnce(&mut Self)) {
2601 self.with_self_rib_ns(TypeNS
, self_res
, f
)
2604 fn resolve_implementation(
2606 generics
: &'ast Generics
,
2607 opt_trait_reference
: &'ast Option
<TraitRef
>,
2608 self_type
: &'ast Ty
,
2610 impl_items
: &'ast
[P
<AssocItem
>],
2612 debug
!("resolve_implementation");
2613 // If applicable, create a rib for the type parameters.
2614 self.with_generic_param_rib(
2616 ItemRibKind(HasGenericParams
::Yes(generics
.span
)),
2617 LifetimeRibKind
::Generics
{
2618 span
: generics
.span
,
2620 kind
: LifetimeBinderKind
::ImplBlock
,
2623 // Dummy self type for better errors if `Self` is used in the trait path.
2624 this
.with_self_rib(Res
::SelfTyParam { trait_: LOCAL_CRATE.as_def_id() }
, |this
| {
2625 this
.with_lifetime_rib(
2626 LifetimeRibKind
::AnonymousCreateParameter
{
2628 report_in_path
: true
2631 // Resolve the trait reference, if necessary.
2632 this
.with_optional_trait_ref(
2633 opt_trait_reference
.as_ref(),
2636 let item_def_id
= this
.r
.local_def_id(item_id
);
2638 // Register the trait definitions from here.
2639 if let Some(trait_id
) = trait_id
{
2647 let item_def_id
= item_def_id
.to_def_id();
2648 let res
= Res
::SelfTyAlias
{
2649 alias_to
: item_def_id
,
2650 forbid_generic
: false,
2651 is_trait_impl
: trait_id
.is_some()
2653 this
.with_self_rib(res
, |this
| {
2654 if let Some(trait_ref
) = opt_trait_reference
.as_ref() {
2655 // Resolve type arguments in the trait path.
2656 visit
::walk_trait_ref(this
, trait_ref
);
2658 // Resolve the self type.
2659 this
.visit_ty(self_type
);
2660 // Resolve the generic parameters.
2661 this
.visit_generics(generics
);
2663 // Resolve the items within the impl.
2664 this
.with_current_self_type(self_type
, |this
| {
2665 this
.with_self_rib_ns(ValueNS
, Res
::SelfCtor(item_def_id
), |this
| {
2666 debug
!("resolve_implementation with_self_rib_ns(ValueNS, ...)");
2667 let mut seen_trait_items
= Default
::default();
2668 for item
in impl_items
{
2669 this
.resolve_impl_item(&**item
, &mut seen_trait_items
);
2683 fn resolve_impl_item(
2685 item
: &'ast AssocItem
,
2686 seen_trait_items
: &mut FxHashMap
<DefId
, Span
>,
2688 use crate::ResolutionError
::*;
2690 AssocItemKind
::Const(_
, ty
, default) => {
2691 debug
!("resolve_implementation AssocItemKind::Const");
2692 // If this is a trait impl, ensure the const
2694 self.check_trait_item(
2701 |i
, s
, c
| ConstNotMemberOfTrait(i
, s
, c
),
2705 if let Some(expr
) = default {
2706 // We allow arbitrary const expressions inside of associated consts,
2707 // even if they are potentially not const evaluatable.
2709 // Type parameters can already be used and as associated consts are
2710 // not used as part of the type system, this is far less surprising.
2711 self.with_lifetime_rib(LifetimeRibKind
::Elided(LifetimeRes
::Infer
), |this
| {
2712 this
.with_constant_rib(
2714 ConstantHasGenerics
::Yes
,
2716 |this
| this
.visit_expr(expr
),
2721 AssocItemKind
::Fn(box Fn { generics, .. }
) => {
2722 debug
!("resolve_implementation AssocItemKind::Fn");
2723 // We also need a new scope for the impl item type parameters.
2724 self.with_generic_param_rib(
2727 LifetimeRibKind
::Generics
{
2729 span
: generics
.span
,
2730 kind
: LifetimeBinderKind
::Function
,
2733 // If this is a trait impl, ensure the method
2735 this
.check_trait_item(
2742 |i
, s
, c
| MethodNotMemberOfTrait(i
, s
, c
),
2745 visit
::walk_assoc_item(this
, item
, AssocCtxt
::Impl
)
2749 AssocItemKind
::Type(box TyAlias { generics, .. }
) => {
2750 debug
!("resolve_implementation AssocItemKind::Type");
2751 // We also need a new scope for the impl item type parameters.
2752 self.with_generic_param_rib(
2755 LifetimeRibKind
::Generics
{
2757 span
: generics
.span
,
2758 kind
: LifetimeBinderKind
::Item
,
2761 this
.with_lifetime_rib(LifetimeRibKind
::AnonymousReportError
, |this
| {
2762 // If this is a trait impl, ensure the type
2764 this
.check_trait_item(
2771 |i
, s
, c
| TypeNotMemberOfTrait(i
, s
, c
),
2774 visit
::walk_assoc_item(this
, item
, AssocCtxt
::Impl
)
2779 AssocItemKind
::MacCall(_
) => {
2780 panic
!("unexpanded macro in resolve!")
2785 fn check_trait_item
<F
>(
2789 kind
: &AssocItemKind
,
2792 seen_trait_items
: &mut FxHashMap
<DefId
, Span
>,
2795 F
: FnOnce(Ident
, String
, Option
<Symbol
>) -> ResolutionError
<'a
>,
2797 // If there is a TraitRef in scope for an impl, then the method must be in the trait.
2798 let Some((module
, _
)) = &self.current_trait_ref
else { return; }
;
2799 ident
.span
.normalize_to_macros_2_0_and_adjust(module
.expansion
);
2800 let key
= self.r
.new_key(ident
, ns
);
2801 let mut binding
= self.r
.resolution(module
, key
).try_borrow().ok().and_then(|r
| r
.binding
);
2803 if binding
.is_none() {
2804 // We could not find the trait item in the correct namespace.
2805 // Check the other namespace to report an error.
2811 let key
= self.r
.new_key(ident
, ns
);
2812 binding
= self.r
.resolution(module
, key
).try_borrow().ok().and_then(|r
| r
.binding
);
2815 let Some(binding
) = binding
else {
2816 // We could not find the method: report an error.
2817 let candidate
= self.find_similarly_named_assoc_item(ident
.name
, kind
);
2818 let path
= &self.current_trait_ref
.as_ref().unwrap().1.path
;
2819 let path_names
= path_names_to_string(path
);
2820 self.report_error(span
, err(ident
, path_names
, candidate
));
2824 let res
= binding
.res();
2825 let Res
::Def(def_kind
, id_in_trait
) = res
else { bug!() }
;
2827 match seen_trait_items
.entry(id_in_trait
) {
2828 Entry
::Occupied(entry
) => {
2831 ResolutionError
::TraitImplDuplicate
{
2833 old_span
: *entry
.get(),
2834 trait_item_span
: binding
.span
,
2839 Entry
::Vacant(entry
) => {
2844 match (def_kind
, kind
) {
2845 (DefKind
::AssocTy
, AssocItemKind
::Type(..))
2846 | (DefKind
::AssocFn
, AssocItemKind
::Fn(..))
2847 | (DefKind
::AssocConst
, AssocItemKind
::Const(..)) => {
2848 self.r
.record_partial_res(id
, PartialRes
::new(res
));
2854 // The method kind does not correspond to what appeared in the trait, report.
2855 let path
= &self.current_trait_ref
.as_ref().unwrap().1.path
;
2856 let (code
, kind
) = match kind
{
2857 AssocItemKind
::Const(..) => (rustc_errors
::error_code
!(E0323
), "const"),
2858 AssocItemKind
::Fn(..) => (rustc_errors
::error_code
!(E0324
), "method"),
2859 AssocItemKind
::Type(..) => (rustc_errors
::error_code
!(E0325
), "type"),
2860 AssocItemKind
::MacCall(..) => span_bug
!(span
, "unexpanded macro"),
2862 let trait_path
= path_names_to_string(path
);
2865 ResolutionError
::TraitImplMismatch
{
2870 trait_item_span
: binding
.span
,
2875 fn resolve_params(&mut self, params
: &'ast
[Param
]) {
2876 let mut bindings
= smallvec
![(PatBoundCtx
::Product
, Default
::default())];
2877 self.with_lifetime_rib(LifetimeRibKind
::Elided(LifetimeRes
::Infer
), |this
| {
2878 for Param { pat, .. }
in params
{
2879 this
.resolve_pattern(pat
, PatternSource
::FnParam
, &mut bindings
);
2882 for Param { ty, .. }
in params
{
2887 fn resolve_local(&mut self, local
: &'ast Local
) {
2888 debug
!("resolving local ({:?})", local
);
2889 // Resolve the type.
2890 walk_list
!(self, visit_ty
, &local
.ty
);
2892 // Resolve the initializer.
2893 if let Some((init
, els
)) = local
.kind
.init_else_opt() {
2894 self.visit_expr(init
);
2896 // Resolve the `else` block
2897 if let Some(els
) = els
{
2898 self.visit_block(els
);
2902 // Resolve the pattern.
2903 self.resolve_pattern_top(&local
.pat
, PatternSource
::Let
);
2906 /// build a map from pattern identifiers to binding-info's.
2907 /// this is done hygienically. This could arise for a macro
2908 /// that expands into an or-pattern where one 'x' was from the
2909 /// user and one 'x' came from the macro.
2910 fn binding_mode_map(&mut self, pat
: &Pat
) -> BindingMap
{
2911 let mut binding_map
= FxHashMap
::default();
2913 pat
.walk(&mut |pat
| {
2915 PatKind
::Ident(annotation
, ident
, ref sub_pat
)
2916 if sub_pat
.is_some() || self.is_base_res_local(pat
.id
) =>
2918 binding_map
.insert(ident
, BindingInfo { span: ident.span, annotation }
);
2920 PatKind
::Or(ref ps
) => {
2921 // Check the consistency of this or-pattern and
2922 // then add all bindings to the larger map.
2923 for bm
in self.check_consistent_bindings(ps
) {
2924 binding_map
.extend(bm
);
2937 fn is_base_res_local(&self, nid
: NodeId
) -> bool
{
2939 self.r
.partial_res_map
.get(&nid
).map(|res
| res
.expect_full_res()),
2940 Some(Res
::Local(..))
2944 /// Checks that all of the arms in an or-pattern have exactly the
2945 /// same set of bindings, with the same binding modes for each.
2946 fn check_consistent_bindings(&mut self, pats
: &[P
<Pat
>]) -> Vec
<BindingMap
> {
2947 let mut missing_vars
= FxHashMap
::default();
2948 let mut inconsistent_vars
= FxHashMap
::default();
2950 // 1) Compute the binding maps of all arms.
2951 let maps
= pats
.iter().map(|pat
| self.binding_mode_map(pat
)).collect
::<Vec
<_
>>();
2953 // 2) Record any missing bindings or binding mode inconsistencies.
2954 for (map_outer
, pat_outer
) in pats
.iter().enumerate().map(|(idx
, pat
)| (&maps
[idx
], pat
)) {
2955 // Check against all arms except for the same pattern which is always self-consistent.
2959 .filter(|(_
, pat
)| pat
.id
!= pat_outer
.id
)
2960 .flat_map(|(idx
, _
)| maps
[idx
].iter())
2961 .map(|(key
, binding
)| (key
.name
, map_outer
.get(&key
), binding
));
2963 for (name
, info
, &binding_inner
) in inners
{
2966 // The inner binding is missing in the outer.
2968 missing_vars
.entry(name
).or_insert_with(|| BindingError
{
2970 origin
: BTreeSet
::new(),
2971 target
: BTreeSet
::new(),
2972 could_be_path
: name
.as_str().starts_with(char::is_uppercase
),
2974 binding_error
.origin
.insert(binding_inner
.span
);
2975 binding_error
.target
.insert(pat_outer
.span
);
2977 Some(binding_outer
) => {
2978 if binding_outer
.annotation
!= binding_inner
.annotation
{
2979 // The binding modes in the outer and inner bindings differ.
2982 .or_insert((binding_inner
.span
, binding_outer
.span
));
2989 // 3) Report all missing variables we found.
2990 let mut missing_vars
= missing_vars
.into_iter().collect
::<Vec
<_
>>();
2991 missing_vars
.sort_by_key(|&(sym
, ref _err
)| sym
);
2993 for (name
, mut v
) in missing_vars
.into_iter() {
2994 if inconsistent_vars
.contains_key(&name
) {
2995 v
.could_be_path
= false;
2998 *v
.origin
.iter().next().unwrap(),
2999 ResolutionError
::VariableNotBoundInPattern(v
, self.parent_scope
),
3003 // 4) Report all inconsistencies in binding modes we found.
3004 let mut inconsistent_vars
= inconsistent_vars
.iter().collect
::<Vec
<_
>>();
3005 inconsistent_vars
.sort();
3006 for (name
, v
) in inconsistent_vars
{
3007 self.report_error(v
.0, ResolutionError
::VariableBoundWithDifferentMode(*name
, v
.1));
3010 // 5) Finally bubble up all the binding maps.
3014 /// Check the consistency of the outermost or-patterns.
3015 fn check_consistent_bindings_top(&mut self, pat
: &'ast Pat
) {
3016 pat
.walk(&mut |pat
| match pat
.kind
{
3017 PatKind
::Or(ref ps
) => {
3018 self.check_consistent_bindings(ps
);
3025 fn resolve_arm(&mut self, arm
: &'ast Arm
) {
3026 self.with_rib(ValueNS
, NormalRibKind
, |this
| {
3027 this
.resolve_pattern_top(&arm
.pat
, PatternSource
::Match
);
3028 walk_list
!(this
, visit_expr
, &arm
.guard
);
3029 this
.visit_expr(&arm
.body
);
3033 /// Arising from `source`, resolve a top level pattern.
3034 fn resolve_pattern_top(&mut self, pat
: &'ast Pat
, pat_src
: PatternSource
) {
3035 let mut bindings
= smallvec
![(PatBoundCtx
::Product
, Default
::default())];
3036 self.resolve_pattern(pat
, pat_src
, &mut bindings
);
3042 pat_src
: PatternSource
,
3043 bindings
: &mut SmallVec
<[(PatBoundCtx
, FxHashSet
<Ident
>); 1]>,
3045 // We walk the pattern before declaring the pattern's inner bindings,
3046 // so that we avoid resolving a literal expression to a binding defined
3048 visit
::walk_pat(self, pat
);
3049 self.resolve_pattern_inner(pat
, pat_src
, bindings
);
3050 // This has to happen *after* we determine which pat_idents are variants:
3051 self.check_consistent_bindings_top(pat
);
3054 /// Resolve bindings in a pattern. This is a helper to `resolve_pattern`.
3058 /// A stack of sets of bindings accumulated.
3060 /// In each set, `PatBoundCtx::Product` denotes that a found binding in it should
3061 /// be interpreted as re-binding an already bound binding. This results in an error.
3062 /// Meanwhile, `PatBound::Or` denotes that a found binding in the set should result
3063 /// in reusing this binding rather than creating a fresh one.
3065 /// When called at the top level, the stack must have a single element
3066 /// with `PatBound::Product`. Otherwise, pushing to the stack happens as
3067 /// or-patterns (`p_0 | ... | p_n`) are encountered and the context needs
3068 /// to be switched to `PatBoundCtx::Or` and then `PatBoundCtx::Product` for each `p_i`.
3069 /// When each `p_i` has been dealt with, the top set is merged with its parent.
3070 /// When a whole or-pattern has been dealt with, the thing happens.
3072 /// See the implementation and `fresh_binding` for more details.
3073 fn resolve_pattern_inner(
3076 pat_src
: PatternSource
,
3077 bindings
: &mut SmallVec
<[(PatBoundCtx
, FxHashSet
<Ident
>); 1]>,
3079 // Visit all direct subpatterns of this pattern.
3080 pat
.walk(&mut |pat
| {
3081 debug
!("resolve_pattern pat={:?} node={:?}", pat
, pat
.kind
);
3083 PatKind
::Ident(bmode
, ident
, ref sub
) => {
3084 // First try to resolve the identifier as some existing entity,
3085 // then fall back to a fresh binding.
3086 let has_sub
= sub
.is_some();
3088 .try_resolve_as_non_binding(pat_src
, bmode
, ident
, has_sub
)
3089 .unwrap_or_else(|| self.fresh_binding(ident
, pat
.id
, pat_src
, bindings
));
3090 self.r
.record_partial_res(pat
.id
, PartialRes
::new(res
));
3091 self.r
.record_pat_span(pat
.id
, pat
.span
);
3093 PatKind
::TupleStruct(ref qself
, ref path
, ref sub_patterns
) => {
3094 self.smart_resolve_path(
3098 PathSource
::TupleStruct(
3100 self.r
.arenas
.alloc_pattern_spans(sub_patterns
.iter().map(|p
| p
.span
)),
3104 PatKind
::Path(ref qself
, ref path
) => {
3105 self.smart_resolve_path(pat
.id
, qself
.as_ref(), path
, PathSource
::Pat
);
3107 PatKind
::Struct(ref qself
, ref path
, ..) => {
3108 self.smart_resolve_path(pat
.id
, qself
.as_ref(), path
, PathSource
::Struct
);
3110 PatKind
::Or(ref ps
) => {
3111 // Add a new set of bindings to the stack. `Or` here records that when a
3112 // binding already exists in this set, it should not result in an error because
3113 // `V1(a) | V2(a)` must be allowed and are checked for consistency later.
3114 bindings
.push((PatBoundCtx
::Or
, Default
::default()));
3116 // Now we need to switch back to a product context so that each
3117 // part of the or-pattern internally rejects already bound names.
3118 // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
3119 bindings
.push((PatBoundCtx
::Product
, Default
::default()));
3120 self.resolve_pattern_inner(p
, pat_src
, bindings
);
3121 // Move up the non-overlapping bindings to the or-pattern.
3122 // Existing bindings just get "merged".
3123 let collected
= bindings
.pop().unwrap().1;
3124 bindings
.last_mut().unwrap().1.extend(collected
);
3126 // This or-pattern itself can itself be part of a product,
3127 // e.g. `(V1(a) | V2(a), a)` or `(a, V1(a) | V2(a))`.
3128 // Both cases bind `a` again in a product pattern and must be rejected.
3129 let collected
= bindings
.pop().unwrap().1;
3130 bindings
.last_mut().unwrap().1.extend(collected
);
3132 // Prevent visiting `ps` as we've already done so above.
3145 pat_src
: PatternSource
,
3146 bindings
: &mut SmallVec
<[(PatBoundCtx
, FxHashSet
<Ident
>); 1]>,
3148 // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
3149 // (We must not add it if it's in the bindings map because that breaks the assumptions
3150 // later passes make about or-patterns.)
3151 let ident
= ident
.normalize_to_macro_rules();
3153 let mut bound_iter
= bindings
.iter().filter(|(_
, set
)| set
.contains(&ident
));
3154 // Already bound in a product pattern? e.g. `(a, a)` which is not allowed.
3155 let already_bound_and
= bound_iter
.clone().any(|(ctx
, _
)| *ctx
== PatBoundCtx
::Product
);
3156 // Already bound in an or-pattern? e.g. `V1(a) | V2(a)`.
3157 // This is *required* for consistency which is checked later.
3158 let already_bound_or
= bound_iter
.any(|(ctx
, _
)| *ctx
== PatBoundCtx
::Or
);
3160 if already_bound_and
{
3161 // Overlap in a product pattern somewhere; report an error.
3162 use ResolutionError
::*;
3163 let error
= match pat_src
{
3164 // `fn f(a: u8, a: u8)`:
3165 PatternSource
::FnParam
=> IdentifierBoundMoreThanOnceInParameterList
,
3167 _
=> IdentifierBoundMoreThanOnceInSamePattern
,
3169 self.report_error(ident
.span
, error(ident
.name
));
3172 // Record as bound if it's valid:
3173 let ident_valid
= ident
.name
!= kw
::Empty
;
3175 bindings
.last_mut().unwrap().1.insert
(ident
);
3178 if already_bound_or
{
3179 // `Variant1(a) | Variant2(a)`, ok
3180 // Reuse definition from the first `a`.
3181 self.innermost_rib_bindings(ValueNS
)[&ident
]
3183 let res
= Res
::Local(pat_id
);
3185 // A completely fresh binding add to the set if it's valid.
3186 self.innermost_rib_bindings(ValueNS
).insert(ident
, res
);
3192 fn innermost_rib_bindings(&mut self, ns
: Namespace
) -> &mut IdentMap
<Res
> {
3193 &mut self.ribs
[ns
].last_mut().unwrap().bindings
3196 fn try_resolve_as_non_binding(
3198 pat_src
: PatternSource
,
3199 ann
: BindingAnnotation
,
3203 // An immutable (no `mut`) by-value (no `ref`) binding pattern without
3204 // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
3205 // also be interpreted as a path to e.g. a constant, variant, etc.
3206 let is_syntactic_ambiguity
= !has_sub
&& ann
== BindingAnnotation
::NONE
;
3208 let ls_binding
= self.maybe_resolve_ident_in_lexical_scope(ident
, ValueNS
)?
;
3209 let (res
, binding
) = match ls_binding
{
3210 LexicalScopeBinding
::Item(binding
)
3211 if is_syntactic_ambiguity
&& binding
.is_ambiguity() =>
3213 // For ambiguous bindings we don't know all their definitions and cannot check
3214 // whether they can be shadowed by fresh bindings or not, so force an error.
3215 // issues/33118#issuecomment-233962221 (see below) still applies here,
3216 // but we have to ignore it for backward compatibility.
3217 self.r
.record_use(ident
, binding
, false);
3220 LexicalScopeBinding
::Item(binding
) => (binding
.res(), Some(binding
)),
3221 LexicalScopeBinding
::Res(res
) => (res
, None
),
3225 Res
::SelfCtor(_
) // See #70549.
3227 DefKind
::Ctor(_
, CtorKind
::Const
) | DefKind
::Const
| DefKind
::ConstParam
,
3229 ) if is_syntactic_ambiguity
=> {
3230 // Disambiguate in favor of a unit struct/variant or constant pattern.
3231 if let Some(binding
) = binding
{
3232 self.r
.record_use(ident
, binding
, false);
3236 Res
::Def(DefKind
::Ctor(..) | DefKind
::Const
| DefKind
::Static(_
), _
) => {
3237 // This is unambiguously a fresh binding, either syntactically
3238 // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
3239 // to something unusable as a pattern (e.g., constructor function),
3240 // but we still conservatively report an error, see
3241 // issues/33118#issuecomment-233962221 for one reason why.
3242 let binding
= binding
.expect("no binding for a ctor or static");
3245 ResolutionError
::BindingShadowsSomethingUnacceptable
{
3246 shadowing_binding
: pat_src
,
3248 participle
: if binding
.is_import() { "imported" }
else { "defined" }
,
3249 article
: binding
.res().article(),
3250 shadowed_binding
: binding
.res(),
3251 shadowed_binding_span
: binding
.span
,
3256 Res
::Def(DefKind
::ConstParam
, def_id
) => {
3257 // Same as for DefKind::Const above, but here, `binding` is `None`, so we
3258 // have to construct the error differently
3261 ResolutionError
::BindingShadowsSomethingUnacceptable
{
3262 shadowing_binding
: pat_src
,
3264 participle
: "defined",
3265 article
: res
.article(),
3266 shadowed_binding
: res
,
3267 shadowed_binding_span
: self.r
.opt_span(def_id
).expect("const parameter defined outside of local crate"),
3272 Res
::Def(DefKind
::Fn
, _
) | Res
::Local(..) | Res
::Err
=> {
3273 // These entities are explicitly allowed to be shadowed by fresh bindings.
3276 Res
::SelfCtor(_
) => {
3277 // We resolve `Self` in pattern position as an ident sometimes during recovery,
3278 // so delay a bug instead of ICEing.
3279 self.r
.session
.delay_span_bug(
3281 "unexpected `SelfCtor` in pattern, expected identifier"
3287 "unexpected resolution for an identifier in pattern: {:?}",
3293 // High-level and context dependent path resolution routine.
3294 // Resolves the path and records the resolution into definition map.
3295 // If resolution fails tries several techniques to find likely
3296 // resolution candidates, suggest imports or other help, and report
3297 // errors in user friendly way.
3298 fn smart_resolve_path(
3301 qself
: Option
<&QSelf
>,
3303 source
: PathSource
<'ast
>,
3305 self.smart_resolve_path_fragment(
3307 &Segment
::from_path(path
),
3309 Finalize
::new(id
, path
.span
),
3313 fn smart_resolve_path_fragment(
3315 qself
: Option
<&QSelf
>,
3317 source
: PathSource
<'ast
>,
3321 "smart_resolve_path_fragment(qself={:?}, path={:?}, finalize={:?})",
3322 qself
, path
, finalize
,
3324 let ns
= source
.namespace();
3326 let Finalize { node_id, path_span, .. }
= finalize
;
3327 let report_errors
= |this
: &mut Self, res
: Option
<Res
>| {
3328 if this
.should_report_errs() {
3329 let (err
, candidates
) =
3330 this
.smart_resolve_report_errors(path
, path_span
, source
, res
);
3332 let def_id
= this
.parent_scope
.module
.nearest_parent_mod();
3333 let instead
= res
.is_some();
3335 if res
.is_none() { this.report_missing_type_error(path) }
else { None }
;
3337 this
.r
.use_injections
.push(UseError
{
3344 is_call
: source
.is_call(),
3348 PartialRes
::new(Res
::Err
)
3351 // For paths originating from calls (like in `HashMap::new()`), tries
3352 // to enrich the plain `failed to resolve: ...` message with hints
3353 // about possible missing imports.
3355 // Similar thing, for types, happens in `report_errors` above.
3356 let report_errors_for_call
= |this
: &mut Self, parent_err
: Spanned
<ResolutionError
<'a
>>| {
3357 if !source
.is_call() {
3358 return Some(parent_err
);
3361 // Before we start looking for candidates, we have to get our hands
3362 // on the type user is trying to perform invocation on; basically:
3363 // we're transforming `HashMap::new` into just `HashMap`.
3364 let path
= match path
.split_last() {
3365 Some((_
, path
)) if !path
.is_empty() => path
,
3366 _
=> return Some(parent_err
),
3369 let (mut err
, candidates
) =
3370 this
.smart_resolve_report_errors(path
, path_span
, PathSource
::Type
, None
);
3372 if candidates
.is_empty() {
3374 return Some(parent_err
);
3377 // There are two different error messages user might receive at
3379 // - E0412 cannot find type `{}` in this scope
3380 // - E0433 failed to resolve: use of undeclared type or module `{}`
3382 // The first one is emitted for paths in type-position, and the
3383 // latter one - for paths in expression-position.
3385 // Thus (since we're in expression-position at this point), not to
3386 // confuse the user, we want to keep the *message* from E0432 (so
3387 // `parent_err`), but we want *hints* from E0412 (so `err`).
3389 // And that's what happens below - we're just mixing both messages
3390 // into a single one.
3391 let mut parent_err
= this
.r
.into_struct_error(parent_err
.span
, parent_err
.node
);
3393 err
.message
= take(&mut parent_err
.message
);
3394 err
.code
= take(&mut parent_err
.code
);
3395 err
.children
= take(&mut parent_err
.children
);
3397 parent_err
.cancel();
3399 let def_id
= this
.parent_scope
.module
.nearest_parent_mod();
3401 if this
.should_report_errs() {
3402 this
.r
.use_injections
.push(UseError
{
3409 is_call
: source
.is_call(),
3415 // We don't return `Some(parent_err)` here, because the error will
3416 // be already printed as part of the `use` injections
3420 let partial_res
= match self.resolve_qpath_anywhere(
3425 source
.defer_to_typeck(),
3428 Ok(Some(partial_res
)) if let Some(res
) = partial_res
.full_res() => {
3429 if source
.is_expected(res
) || res
== Res
::Err
{
3432 report_errors(self, Some(res
))
3436 Ok(Some(partial_res
)) if source
.defer_to_typeck() => {
3437 // Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B`
3438 // or `<T>::A::B`. If `B` should be resolved in value namespace then
3439 // it needs to be added to the trait map.
3441 let item_name
= path
.last().unwrap().ident
;
3442 let traits
= self.traits_in_scope(item_name
, ns
);
3443 self.r
.trait_map
.insert(node_id
, traits
);
3446 if PrimTy
::from_name(path
[0].ident
.name
).is_some() {
3447 let mut std_path
= Vec
::with_capacity(1 + path
.len());
3449 std_path
.push(Segment
::from_ident(Ident
::with_dummy_span(sym
::std
)));
3450 std_path
.extend(path
);
3451 if let PathResult
::Module(_
) | PathResult
::NonModule(_
) =
3452 self.resolve_path(&std_path
, Some(ns
), None
)
3454 // Check if we wrote `str::from_utf8` instead of `std::str::from_utf8`
3456 path
.iter().last().map_or(path_span
, |segment
| segment
.ident
.span
);
3458 self.r
.confused_type_with_std_module
.insert(item_span
, path_span
);
3459 self.r
.confused_type_with_std_module
.insert(path_span
, path_span
);
3467 if let Some(err
) = report_errors_for_call(self, err
) {
3468 self.report_error(err
.span
, err
.node
);
3471 PartialRes
::new(Res
::Err
)
3474 _
=> report_errors(self, None
),
3477 if !matches
!(source
, PathSource
::TraitItem(..)) {
3478 // Avoid recording definition of `A::B` in `<T as A>::B::C`.
3479 self.r
.record_partial_res(node_id
, partial_res
);
3480 self.resolve_elided_lifetimes_in_path(node_id
, partial_res
, path
, source
, path_span
);
3486 fn self_type_is_available(&mut self) -> bool
{
3488 .maybe_resolve_ident_in_lexical_scope(Ident
::with_dummy_span(kw
::SelfUpper
), TypeNS
);
3489 if let Some(LexicalScopeBinding
::Res(res
)) = binding { res != Res::Err }
else { false }
3492 fn self_value_is_available(&mut self, self_span
: Span
) -> bool
{
3493 let ident
= Ident
::new(kw
::SelfLower
, self_span
);
3494 let binding
= self.maybe_resolve_ident_in_lexical_scope(ident
, ValueNS
);
3495 if let Some(LexicalScopeBinding
::Res(res
)) = binding { res != Res::Err }
else { false }
3498 /// A wrapper around [`Resolver::report_error`].
3500 /// This doesn't emit errors for function bodies if this is rustdoc.
3501 fn report_error(&mut self, span
: Span
, resolution_error
: ResolutionError
<'a
>) {
3502 if self.should_report_errs() {
3503 self.r
.report_error(span
, resolution_error
);
3508 /// If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items.
3509 fn should_report_errs(&self) -> bool
{
3510 !(self.r
.session
.opts
.actually_rustdoc
&& self.in_func_body
)
3513 // Resolve in alternative namespaces if resolution in the primary namespace fails.
3514 fn resolve_qpath_anywhere(
3516 qself
: Option
<&QSelf
>,
3518 primary_ns
: Namespace
,
3520 defer_to_typeck
: bool
,
3522 ) -> Result
<Option
<PartialRes
>, Spanned
<ResolutionError
<'a
>>> {
3523 let mut fin_res
= None
;
3525 for (i
, &ns
) in [primary_ns
, TypeNS
, ValueNS
].iter().enumerate() {
3526 if i
== 0 || ns
!= primary_ns
{
3527 match self.resolve_qpath(qself
, path
, ns
, finalize
)?
{
3529 if partial_res
.unresolved_segments() == 0 || defer_to_typeck
=>
3531 return Ok(Some(partial_res
));
3534 if fin_res
.is_none() {
3535 fin_res
= partial_res
;
3542 assert
!(primary_ns
!= MacroNS
);
3544 if qself
.is_none() {
3545 let path_seg
= |seg
: &Segment
| PathSegment
::from_ident(seg
.ident
);
3546 let path
= Path { segments: path.iter().map(path_seg).collect(), span, tokens: None }
;
3547 if let Ok((_
, res
)) =
3548 self.r
.resolve_macro_path(&path
, None
, &self.parent_scope
, false, false)
3550 return Ok(Some(PartialRes
::new(res
)));
3557 /// Handles paths that may refer to associated items.
3560 qself
: Option
<&QSelf
>,
3564 ) -> Result
<Option
<PartialRes
>, Spanned
<ResolutionError
<'a
>>> {
3566 "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",
3567 qself
, path
, ns
, finalize
,
3570 if let Some(qself
) = qself
{
3571 if qself
.position
== 0 {
3572 // This is a case like `<T>::B`, where there is no
3573 // trait to resolve. In that case, we leave the `B`
3574 // segment to be resolved by type-check.
3575 return Ok(Some(PartialRes
::with_unresolved_segments(
3576 Res
::Def(DefKind
::Mod
, CRATE_DEF_ID
.to_def_id()),
3581 // Make sure `A::B` in `<T as A::B>::C` is a trait item.
3583 // Currently, `path` names the full item (`A::B::C`, in
3584 // our example). so we extract the prefix of that that is
3585 // the trait (the slice upto and including
3586 // `qself.position`). And then we recursively resolve that,
3587 // but with `qself` set to `None`.
3588 let ns
= if qself
.position
+ 1 == path
.len() { ns }
else { TypeNS }
;
3589 let partial_res
= self.smart_resolve_path_fragment(
3591 &path
[..=qself
.position
],
3592 PathSource
::TraitItem(ns
),
3593 Finalize
::with_root_span(finalize
.node_id
, finalize
.path_span
, qself
.path_span
),
3596 // The remaining segments (the `C` in our example) will
3597 // have to be resolved by type-check, since that requires doing
3598 // trait resolution.
3599 return Ok(Some(PartialRes
::with_unresolved_segments(
3600 partial_res
.base_res(),
3601 partial_res
.unresolved_segments() + path
.len() - qself
.position
- 1,
3605 let result
= match self.resolve_path(&path
, Some(ns
), Some(finalize
)) {
3606 PathResult
::NonModule(path_res
) => path_res
,
3607 PathResult
::Module(ModuleOrUniformRoot
::Module(module
)) if !module
.is_normal() => {
3608 PartialRes
::new(module
.res().unwrap())
3610 // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
3611 // don't report an error right away, but try to fallback to a primitive type.
3612 // So, we are still able to successfully resolve something like
3614 // use std::u8; // bring module u8 in scope
3615 // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
3616 // u8::max_value() // OK, resolves to associated function <u8>::max_value,
3617 // // not to non-existent std::u8::max_value
3620 // Such behavior is required for backward compatibility.
3621 // The same fallback is used when `a` resolves to nothing.
3622 PathResult
::Module(ModuleOrUniformRoot
::Module(_
)) | PathResult
::Failed { .. }
3623 if (ns
== TypeNS
|| path
.len() > 1)
3624 && PrimTy
::from_name(path
[0].ident
.name
).is_some() =>
3626 let prim
= PrimTy
::from_name(path
[0].ident
.name
).unwrap();
3627 PartialRes
::with_unresolved_segments(Res
::PrimTy(prim
), path
.len() - 1)
3629 PathResult
::Module(ModuleOrUniformRoot
::Module(module
)) => {
3630 PartialRes
::new(module
.res().unwrap())
3632 PathResult
::Failed { is_error_from_last_segment: false, span, label, suggestion }
=> {
3633 return Err(respan(span
, ResolutionError
::FailedToResolve { label, suggestion }
));
3635 PathResult
::Module(..) | PathResult
::Failed { .. }
=> return Ok(None
),
3636 PathResult
::Indeterminate
=> bug
!("indeterminate path result in resolve_qpath"),
3640 && let Some(res
) = result
.full_res()
3642 && path
[0].ident
.name
!= kw
::PathRoot
3643 && path
[0].ident
.name
!= kw
::DollarCrate
3645 let unqualified_result
= {
3646 match self.resolve_path(&[*path
.last().unwrap()], Some(ns
), None
) {
3647 PathResult
::NonModule(path_res
) => path_res
.expect_full_res(),
3648 PathResult
::Module(ModuleOrUniformRoot
::Module(module
)) => {
3649 module
.res().unwrap()
3651 _
=> return Ok(Some(result
)),
3654 if res
== unqualified_result
{
3655 let lint
= lint
::builtin
::UNUSED_QUALIFICATIONS
;
3656 self.r
.lint_buffer
.buffer_lint(
3660 "unnecessary qualification",
3668 fn with_resolved_label(&mut self, label
: Option
<Label
>, id
: NodeId
, f
: impl FnOnce(&mut Self)) {
3669 if let Some(label
) = label
{
3670 if label
.ident
.as_str().as_bytes()[1] != b'_'
{
3671 self.diagnostic_metadata
.unused_labels
.insert(id
, label
.ident
.span
);
3674 if let Ok((_
, orig_span
)) = self.resolve_label(label
.ident
) {
3675 diagnostics
::signal_label_shadowing(self.r
.session
, orig_span
, label
.ident
)
3678 self.with_label_rib(NormalRibKind
, |this
| {
3679 let ident
= label
.ident
.normalize_to_macro_rules();
3680 this
.label_ribs
.last_mut().unwrap().bindings
.insert(ident
, id
);
3688 fn resolve_labeled_block(&mut self, label
: Option
<Label
>, id
: NodeId
, block
: &'ast Block
) {
3689 self.with_resolved_label(label
, id
, |this
| this
.visit_block(block
));
3692 fn resolve_block(&mut self, block
: &'ast Block
) {
3693 debug
!("(resolving block) entering block");
3694 // Move down in the graph, if there's an anonymous module rooted here.
3695 let orig_module
= self.parent_scope
.module
;
3696 let anonymous_module
= self.r
.block_map
.get(&block
.id
).cloned(); // clones a reference
3698 let mut num_macro_definition_ribs
= 0;
3699 if let Some(anonymous_module
) = anonymous_module
{
3700 debug
!("(resolving block) found anonymous module, moving down");
3701 self.ribs
[ValueNS
].push(Rib
::new(ModuleRibKind(anonymous_module
)));
3702 self.ribs
[TypeNS
].push(Rib
::new(ModuleRibKind(anonymous_module
)));
3703 self.parent_scope
.module
= anonymous_module
;
3705 self.ribs
[ValueNS
].push(Rib
::new(NormalRibKind
));
3708 let prev
= self.diagnostic_metadata
.current_block_could_be_bare_struct_literal
.take();
3709 if let (true, [Stmt { kind: StmtKind::Expr(expr), .. }
]) =
3710 (block
.could_be_bare_literal
, &block
.stmts
[..])
3711 && let ExprKind
::Type(..) = expr
.kind
3713 self.diagnostic_metadata
.current_block_could_be_bare_struct_literal
=
3716 // Descend into the block.
3717 for stmt
in &block
.stmts
{
3718 if let StmtKind
::Item(ref item
) = stmt
.kind
3719 && let ItemKind
::MacroDef(..) = item
.kind
{
3720 num_macro_definition_ribs
+= 1;
3721 let res
= self.r
.local_def_id(item
.id
).to_def_id();
3722 self.ribs
[ValueNS
].push(Rib
::new(MacroDefinition(res
)));
3723 self.label_ribs
.push(Rib
::new(MacroDefinition(res
)));
3726 self.visit_stmt(stmt
);
3728 self.diagnostic_metadata
.current_block_could_be_bare_struct_literal
= prev
;
3731 self.parent_scope
.module
= orig_module
;
3732 for _
in 0..num_macro_definition_ribs
{
3733 self.ribs
[ValueNS
].pop();
3734 self.label_ribs
.pop();
3736 self.ribs
[ValueNS
].pop();
3737 if anonymous_module
.is_some() {
3738 self.ribs
[TypeNS
].pop();
3740 debug
!("(resolving block) leaving block");
3743 fn resolve_anon_const(&mut self, constant
: &'ast AnonConst
, is_repeat
: IsRepeatExpr
) {
3744 debug
!("resolve_anon_const {:?} is_repeat: {:?}", constant
, is_repeat
);
3745 self.with_constant_rib(
3747 if constant
.value
.is_potential_trivial_const_param() {
3748 ConstantHasGenerics
::Yes
3750 ConstantHasGenerics
::No
3753 |this
| visit
::walk_anon_const(this
, constant
),
3757 fn resolve_inline_const(&mut self, constant
: &'ast AnonConst
) {
3758 debug
!("resolve_anon_const {constant:?}");
3759 self.with_constant_rib(IsRepeatExpr
::No
, ConstantHasGenerics
::Yes
, None
, |this
| {
3760 visit
::walk_anon_const(this
, constant
)
3764 fn resolve_expr(&mut self, expr
: &'ast Expr
, parent
: Option
<&'ast Expr
>) {
3765 // First, record candidate traits for this expression if it could
3766 // result in the invocation of a method call.
3768 self.record_candidate_traits_for_expr_if_necessary(expr
);
3770 // Next, resolve the node.
3772 ExprKind
::Path(ref qself
, ref path
) => {
3773 self.smart_resolve_path(expr
.id
, qself
.as_ref(), path
, PathSource
::Expr(parent
));
3774 visit
::walk_expr(self, expr
);
3777 ExprKind
::Struct(ref se
) => {
3778 self.smart_resolve_path(expr
.id
, se
.qself
.as_ref(), &se
.path
, PathSource
::Struct
);
3779 visit
::walk_expr(self, expr
);
3782 ExprKind
::Break(Some(label
), _
) | ExprKind
::Continue(Some(label
)) => {
3783 match self.resolve_label(label
.ident
) {
3784 Ok((node_id
, _
)) => {
3785 // Since this res is a label, it is never read.
3786 self.r
.label_res_map
.insert(expr
.id
, node_id
);
3787 self.diagnostic_metadata
.unused_labels
.remove(&node_id
);
3790 self.report_error(label
.ident
.span
, error
);
3794 // visit `break` argument if any
3795 visit
::walk_expr(self, expr
);
3798 ExprKind
::Break(None
, Some(ref e
)) => {
3799 // We use this instead of `visit::walk_expr` to keep the parent expr around for
3800 // better diagnostics.
3801 self.resolve_expr(e
, Some(&expr
));
3804 ExprKind
::Let(ref pat
, ref scrutinee
, _
) => {
3805 self.visit_expr(scrutinee
);
3806 self.resolve_pattern_top(pat
, PatternSource
::Let
);
3809 ExprKind
::If(ref cond
, ref then
, ref opt_else
) => {
3810 self.with_rib(ValueNS
, NormalRibKind
, |this
| {
3811 let old
= this
.diagnostic_metadata
.in_if_condition
.replace(cond
);
3812 this
.visit_expr(cond
);
3813 this
.diagnostic_metadata
.in_if_condition
= old
;
3814 this
.visit_block(then
);
3816 if let Some(expr
) = opt_else
{
3817 self.visit_expr(expr
);
3821 ExprKind
::Loop(ref block
, label
) => self.resolve_labeled_block(label
, expr
.id
, &block
),
3823 ExprKind
::While(ref cond
, ref block
, label
) => {
3824 self.with_resolved_label(label
, expr
.id
, |this
| {
3825 this
.with_rib(ValueNS
, NormalRibKind
, |this
| {
3826 let old
= this
.diagnostic_metadata
.in_if_condition
.replace(cond
);
3827 this
.visit_expr(cond
);
3828 this
.diagnostic_metadata
.in_if_condition
= old
;
3829 this
.visit_block(block
);
3834 ExprKind
::ForLoop(ref pat
, ref iter_expr
, ref block
, label
) => {
3835 self.visit_expr(iter_expr
);
3836 self.with_rib(ValueNS
, NormalRibKind
, |this
| {
3837 this
.resolve_pattern_top(pat
, PatternSource
::For
);
3838 this
.resolve_labeled_block(label
, expr
.id
, block
);
3842 ExprKind
::Block(ref block
, label
) => self.resolve_labeled_block(label
, block
.id
, block
),
3844 // Equivalent to `visit::walk_expr` + passing some context to children.
3845 ExprKind
::Field(ref subexpression
, _
) => {
3846 self.resolve_expr(subexpression
, Some(expr
));
3848 ExprKind
::MethodCall(ref segment
, ref receiver
, ref arguments
, _
) => {
3849 self.resolve_expr(receiver
, Some(expr
));
3850 for argument
in arguments
{
3851 self.resolve_expr(argument
, None
);
3853 self.visit_path_segment(segment
);
3856 ExprKind
::Call(ref callee
, ref arguments
) => {
3857 self.resolve_expr(callee
, Some(expr
));
3858 let const_args
= self.r
.legacy_const_generic_args(callee
).unwrap_or_default();
3859 for (idx
, argument
) in arguments
.iter().enumerate() {
3860 // Constant arguments need to be treated as AnonConst since
3861 // that is how they will be later lowered to HIR.
3862 if const_args
.contains(&idx
) {
3863 self.with_constant_rib(
3865 if argument
.is_potential_trivial_const_param() {
3866 ConstantHasGenerics
::Yes
3868 ConstantHasGenerics
::No
3872 this
.resolve_expr(argument
, None
);
3876 self.resolve_expr(argument
, None
);
3880 ExprKind
::Type(ref type_expr
, ref ty
) => {
3881 // `ParseSess::type_ascription_path_suggestions` keeps spans of colon tokens in
3882 // type ascription. Here we are trying to retrieve the span of the colon token as
3883 // well, but only if it's written without spaces `expr:Ty` and therefore confusable
3884 // with `expr::Ty`, only in this case it will match the span from
3885 // `type_ascription_path_suggestions`.
3886 self.diagnostic_metadata
3887 .current_type_ascription
3888 .push(type_expr
.span
.between(ty
.span
));
3889 visit
::walk_expr(self, expr
);
3890 self.diagnostic_metadata
.current_type_ascription
.pop();
3892 // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
3893 // resolve the arguments within the proper scopes so that usages of them inside the
3894 // closure are detected as upvars rather than normal closure arg usages.
3895 ExprKind
::Closure(_
, _
, Async
::Yes { .. }
, _
, ref fn_decl
, ref body
, _span
) => {
3896 self.with_rib(ValueNS
, NormalRibKind
, |this
| {
3897 this
.with_label_rib(ClosureOrAsyncRibKind
, |this
| {
3898 // Resolve arguments:
3899 this
.resolve_params(&fn_decl
.inputs
);
3900 // No need to resolve return type --
3901 // the outer closure return type is `FnRetTy::Default`.
3903 // Now resolve the inner closure
3905 // No need to resolve arguments: the inner closure has none.
3906 // Resolve the return type:
3907 visit
::walk_fn_ret_ty(this
, &fn_decl
.output
);
3909 this
.visit_expr(body
);
3914 // For closures, ClosureOrAsyncRibKind is added in visit_fn
3915 ExprKind
::Closure(ClosureBinder
::For { ref generic_params, span }
, ..) => {
3916 self.with_generic_param_rib(
3919 LifetimeRibKind
::Generics
{
3921 kind
: LifetimeBinderKind
::Closure
,
3924 |this
| visit
::walk_expr(this
, expr
),
3927 ExprKind
::Closure(..) => visit
::walk_expr(self, expr
),
3928 ExprKind
::Async(..) => {
3929 self.with_label_rib(ClosureOrAsyncRibKind
, |this
| visit
::walk_expr(this
, expr
));
3931 ExprKind
::Repeat(ref elem
, ref ct
) => {
3932 self.visit_expr(elem
);
3933 self.with_lifetime_rib(LifetimeRibKind
::AnonConst
, |this
| {
3934 this
.with_lifetime_rib(LifetimeRibKind
::Elided(LifetimeRes
::Static
), |this
| {
3935 this
.resolve_anon_const(ct
, IsRepeatExpr
::Yes
)
3939 ExprKind
::ConstBlock(ref ct
) => {
3940 self.resolve_inline_const(ct
);
3942 ExprKind
::Index(ref elem
, ref idx
) => {
3943 self.resolve_expr(elem
, Some(expr
));
3944 self.visit_expr(idx
);
3946 ExprKind
::Assign(..) => {
3947 let old
= self.diagnostic_metadata
.in_assignment
.replace(expr
);
3948 visit
::walk_expr(self, expr
);
3949 self.diagnostic_metadata
.in_assignment
= old
;
3952 visit
::walk_expr(self, expr
);
3957 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr
: &'ast Expr
) {
3959 ExprKind
::Field(_
, ident
) => {
3960 // FIXME(#6890): Even though you can't treat a method like a
3961 // field, we need to add any trait methods we find that match
3962 // the field name so that we can do some nice error reporting
3963 // later on in typeck.
3964 let traits
= self.traits_in_scope(ident
, ValueNS
);
3965 self.r
.trait_map
.insert(expr
.id
, traits
);
3967 ExprKind
::MethodCall(ref segment
, ..) => {
3968 debug
!("(recording candidate traits for expr) recording traits for {}", expr
.id
);
3969 let traits
= self.traits_in_scope(segment
.ident
, ValueNS
);
3970 self.r
.trait_map
.insert(expr
.id
, traits
);
3978 fn traits_in_scope(&mut self, ident
: Ident
, ns
: Namespace
) -> Vec
<TraitCandidate
> {
3979 self.r
.traits_in_scope(
3980 self.current_trait_ref
.as_ref().map(|(module
, _
)| *module
),
3983 Some((ident
.name
, ns
)),
3987 /// Construct the list of in-scope lifetime parameters for async lowering.
3988 /// We include all lifetime parameters, either named or "Fresh".
3989 /// The order of those parameters does not matter, as long as it is
3991 fn record_lifetime_params_for_async(
3994 async_node_id
: Option
<(NodeId
, Span
)>,
3996 if let Some((async_node_id
, span
)) = async_node_id
{
3997 let mut extra_lifetime_params
=
3998 self.r
.extra_lifetime_params_map
.get(&fn_id
).cloned().unwrap_or_default();
3999 for rib
in self.lifetime_ribs
.iter().rev() {
4000 extra_lifetime_params
.extend(
4001 rib
.bindings
.iter().map(|(&ident
, &(node_id
, res
))| (ident
, node_id
, res
)),
4004 LifetimeRibKind
::Item
=> break,
4005 LifetimeRibKind
::AnonymousCreateParameter { binder, .. }
=> {
4006 if let Some(earlier_fresh
) = self.r
.extra_lifetime_params_map
.get(&binder
) {
4007 extra_lifetime_params
.extend(earlier_fresh
);
4010 LifetimeRibKind
::Generics { .. }
=> {}
4012 // We are in a function definition. We should only find `Generics`
4013 // and `AnonymousCreateParameter` inside the innermost `Item`.
4014 span_bug
!(span
, "unexpected rib kind: {:?}", rib
.kind
)
4018 self.r
.extra_lifetime_params_map
.insert(async_node_id
, extra_lifetime_params
);
4023 struct LifetimeCountVisitor
<'a
, 'b
> {
4024 r
: &'b
mut Resolver
<'a
>,
4027 /// Walks the whole crate in DFS order, visiting each item, counting the declared number of
4028 /// lifetime generic parameters.
4029 impl<'ast
> Visitor
<'ast
> for LifetimeCountVisitor
<'_
, '_
> {
4030 fn visit_item(&mut self, item
: &'ast Item
) {
4032 ItemKind
::TyAlias(box TyAlias { ref generics, .. }
)
4033 | ItemKind
::Fn(box Fn { ref generics, .. }
)
4034 | ItemKind
::Enum(_
, ref generics
)
4035 | ItemKind
::Struct(_
, ref generics
)
4036 | ItemKind
::Union(_
, ref generics
)
4037 | ItemKind
::Impl(box Impl { ref generics, .. }
)
4038 | ItemKind
::Trait(box Trait { ref generics, .. }
)
4039 | ItemKind
::TraitAlias(ref generics
, _
) => {
4040 let def_id
= self.r
.local_def_id(item
.id
);
4041 let count
= generics
4044 .filter(|param
| matches
!(param
.kind
, ast
::GenericParamKind
::Lifetime { .. }
))
4046 self.r
.item_generics_num_lifetimes
.insert(def_id
, count
);
4050 | ItemKind
::ForeignMod(..)
4051 | ItemKind
::Static(..)
4052 | ItemKind
::Const(..)
4054 | ItemKind
::ExternCrate(..)
4055 | ItemKind
::MacroDef(..)
4056 | ItemKind
::GlobalAsm(..)
4057 | ItemKind
::MacCall(..) => {}
4059 visit
::walk_item(self, item
)
4063 impl<'a
> Resolver
<'a
> {
4064 pub(crate) fn late_resolve_crate(&mut self, krate
: &Crate
) {
4065 visit
::walk_crate(&mut LifetimeCountVisitor { r: self }
, krate
);
4066 let mut late_resolution_visitor
= LateResolutionVisitor
::new(self);
4067 visit
::walk_crate(&mut late_resolution_visitor
, krate
);
4068 for (id
, span
) in late_resolution_visitor
.diagnostic_metadata
.unused_labels
.iter() {
4069 self.lint_buffer
.buffer_lint(lint
::builtin
::UNUSED_LABELS
, *id
, *span
, "unused label");