1 // ignore-tidy-filelength
3 //! This crate is responsible for the part of name resolution that doesn't require type checker.
5 //! Module structure of the crate is built here.
6 //! Paths in macros, imports, expressions, types, patterns are resolved here.
7 //! Label and lifetime names are resolved here as well.
9 //! Type-relative name resolution (methods, fields, associated items) happens in `rustc_typeck`.
11 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
12 #![feature(box_patterns)]
13 #![feature(bool_to_option)]
14 #![feature(crate_visibility_modifier)]
15 #![feature(format_args_capture)]
18 #![recursion_limit = "256"]
19 #![allow(rustdoc::private_intra_doc_links)]
21 pub use rustc_hir
::def
::{Namespace, PerNS}
;
25 use rustc_arena
::{DroplessArena, TypedArena}
;
26 use rustc_ast
::node_id
::NodeMap
;
27 use rustc_ast
::ptr
::P
;
28 use rustc_ast
::visit
::{self, Visitor}
;
29 use rustc_ast
::{self as ast, NodeId}
;
30 use rustc_ast
::{Crate, CRATE_NODE_ID}
;
31 use rustc_ast
::{Expr, ExprKind, LitKind}
;
32 use rustc_ast
::{ItemKind, ModKind, Path}
;
33 use rustc_ast_lowering
::ResolverAstLowering
;
34 use rustc_ast_pretty
::pprust
;
35 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet, FxIndexMap}
;
36 use rustc_data_structures
::ptr_key
::PtrKey
;
37 use rustc_data_structures
::sync
::Lrc
;
38 use rustc_errors
::{struct_span_err, Applicability, DiagnosticBuilder}
;
39 use rustc_expand
::base
::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}
;
40 use rustc_hir
::def
::Namespace
::*;
41 use rustc_hir
::def
::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}
;
42 use rustc_hir
::def_id
::{CrateNum, DefId, DefIdMap, DefPathHash, LocalDefId, CRATE_DEF_INDEX}
;
43 use rustc_hir
::definitions
::{DefKey, DefPathData, Definitions}
;
44 use rustc_hir
::TraitCandidate
;
45 use rustc_index
::vec
::IndexVec
;
46 use rustc_metadata
::creader
::{CStore, CrateLoader}
;
47 use rustc_middle
::hir
::exports
::ExportMap
;
48 use rustc_middle
::middle
::cstore
::{CrateStore, MetadataLoaderDyn}
;
49 use rustc_middle
::span_bug
;
50 use rustc_middle
::ty
::query
::Providers
;
51 use rustc_middle
::ty
::{self, DefIdTree, MainDefinition, ResolverOutputs}
;
52 use rustc_session
::lint
;
53 use rustc_session
::lint
::{BuiltinLintDiagnostics, LintBuffer}
;
54 use rustc_session
::Session
;
55 use rustc_span
::edition
::Edition
;
56 use rustc_span
::hygiene
::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext, Transparency}
;
57 use rustc_span
::source_map
::{CachingSourceMapView, Spanned}
;
58 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
59 use rustc_span
::{Span, DUMMY_SP}
;
61 use smallvec
::{smallvec, SmallVec}
;
62 use std
::cell
::{Cell, RefCell}
;
63 use std
::collections
::{BTreeMap, BTreeSet}
;
64 use std
::ops
::ControlFlow
;
65 use std
::{cmp, fmt, iter, ptr}
;
68 use diagnostics
::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding}
;
69 use diagnostics
::{ImportSuggestion, LabelSuggestion, Suggestion}
;
70 use imports
::{Import, ImportKind, ImportResolver, NameResolution}
;
71 use late
::{ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind::*}
;
72 use macros
::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}
;
74 type Res
= def
::Res
<NodeId
>;
76 mod build_reduced_graph
;
89 #[derive(Copy, Clone, PartialEq, Debug)]
90 pub enum Determinacy
{
96 fn determined(determined
: bool
) -> Determinacy
{
97 if determined { Determinacy::Determined }
else { Determinacy::Undetermined }
101 /// A specific scope in which a name can be looked up.
102 /// This enum is currently used only for early resolution (imports and macros),
103 /// but not for late resolution yet.
104 #[derive(Clone, Copy)]
106 DeriveHelpers(LocalExpnId
),
108 MacroRules(MacroRulesScopeRef
<'a
>),
110 // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
111 // lint if it should be reported.
112 Module(Module
<'a
>, Option
<NodeId
>),
122 /// Names from different contexts may want to visit different subsets of all specific scopes
123 /// with different restrictions when looking up the resolution.
124 /// This enum is currently used only for early resolution (imports and macros),
125 /// but not for late resolution yet.
126 #[derive(Clone, Copy)]
128 /// All scopes with the given namespace.
129 All(Namespace
, /*is_import*/ bool
),
130 /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
131 AbsolutePath(Namespace
),
132 /// All scopes with macro namespace and the given macro kind restriction.
134 /// All scopes with the given namespace, used for partially performing late resolution.
135 /// The node id enables lints and is used for reporting them.
136 Late(Namespace
, Module
<'a
>, Option
<NodeId
>),
139 /// Everything you need to know about a name's location to resolve it.
140 /// Serves as a starting point for the scope visitor.
141 /// This struct is currently used only for early resolution (imports and macros),
142 /// but not for late resolution yet.
143 #[derive(Clone, Copy, Debug)]
144 pub struct ParentScope
<'a
> {
146 expansion
: LocalExpnId
,
147 macro_rules
: MacroRulesScopeRef
<'a
>,
148 derives
: &'a
[ast
::Path
],
151 impl<'a
> ParentScope
<'a
> {
152 /// Creates a parent scope with the passed argument used as the module scope component,
153 /// and other scope components set to default empty values.
154 pub fn module(module
: Module
<'a
>, resolver
: &Resolver
<'a
>) -> ParentScope
<'a
> {
157 expansion
: LocalExpnId
::ROOT
,
158 macro_rules
: resolver
.arenas
.alloc_macro_rules_scope(MacroRulesScope
::Empty
),
164 #[derive(Copy, Debug, Clone)]
165 enum ImplTraitContext
{
167 Universal(LocalDefId
),
171 struct BindingError
{
173 origin
: BTreeSet
<Span
>,
174 target
: BTreeSet
<Span
>,
178 impl PartialOrd
for BindingError
{
179 fn partial_cmp(&self, other
: &BindingError
) -> Option
<cmp
::Ordering
> {
180 Some(self.cmp(other
))
184 impl PartialEq
for BindingError
{
185 fn eq(&self, other
: &BindingError
) -> bool
{
186 self.name
== other
.name
190 impl Ord
for BindingError
{
191 fn cmp(&self, other
: &BindingError
) -> cmp
::Ordering
{
192 self.name
.cmp(&other
.name
)
196 enum ResolutionError
<'a
> {
197 /// Error E0401: can't use type or const parameters from outer function.
198 GenericParamsFromOuterFunction(Res
, HasGenericParams
),
199 /// Error E0403: the name is already used for a type or const parameter in this generic
201 NameAlreadyUsedInParameterList(Symbol
, Span
),
202 /// Error E0407: method is not a member of trait.
203 MethodNotMemberOfTrait(Symbol
, &'a
str),
204 /// Error E0437: type is not a member of trait.
205 TypeNotMemberOfTrait(Symbol
, &'a
str),
206 /// Error E0438: const is not a member of trait.
207 ConstNotMemberOfTrait(Symbol
, &'a
str),
208 /// Error E0408: variable `{}` is not bound in all patterns.
209 VariableNotBoundInPattern(&'a BindingError
),
210 /// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.
211 VariableBoundWithDifferentMode(Symbol
, Span
),
212 /// Error E0415: identifier is bound more than once in this parameter list.
213 IdentifierBoundMoreThanOnceInParameterList(Symbol
),
214 /// Error E0416: identifier is bound more than once in the same pattern.
215 IdentifierBoundMoreThanOnceInSamePattern(Symbol
),
216 /// Error E0426: use of undeclared label.
217 UndeclaredLabel { name: Symbol, suggestion: Option<LabelSuggestion> }
,
218 /// Error E0429: `self` imports are only allowed within a `{ }` list.
219 SelfImportsOnlyAllowedWithin { root: bool, span_with_rename: Span }
,
220 /// Error E0430: `self` import can only appear once in the list.
221 SelfImportCanOnlyAppearOnceInTheList
,
222 /// Error E0431: `self` import can only appear in an import list with a non-empty prefix.
223 SelfImportOnlyInImportListWithNonEmptyPrefix
,
224 /// Error E0433: failed to resolve.
225 FailedToResolve { label: String, suggestion: Option<Suggestion> }
,
226 /// Error E0434: can't capture dynamic environment in a fn item.
227 CannotCaptureDynamicEnvironmentInFnItem
,
228 /// Error E0435: attempt to use a non-constant value in a constant.
229 AttemptToUseNonConstantValueInConstant(
231 /* suggestion */ &'
static str,
232 /* current */ &'
static str,
234 /// Error E0530: `X` bindings cannot shadow `Y`s.
235 BindingShadowsSomethingUnacceptable
{
236 shadowing_binding_descr
: &'
static str,
238 participle
: &'
static str,
239 article
: &'
static str,
240 shadowed_binding_descr
: &'
static str,
241 shadowed_binding_span
: Span
,
243 /// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
244 ForwardDeclaredGenericParam
,
245 /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
246 ParamInTyOfConstParam(Symbol
),
247 /// generic parameters must not be used inside const evaluations.
249 /// This error is only emitted when using `min_const_generics`.
250 ParamInNonTrivialAnonConst { name: Symbol, is_type: bool }
,
251 /// Error E0735: generic parameters with a default cannot use `Self`
252 SelfInGenericParamDefault
,
253 /// Error E0767: use of unreachable label
254 UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> }
,
257 enum VisResolutionError
<'a
> {
258 Relative2018(Span
, &'a ast
::Path
),
260 FailedToResolve(Span
, String
, Option
<Suggestion
>),
261 ExpectedFound(Span
, String
, Res
),
266 /// A minimal representation of a path segment. We use this in resolve because we synthesize 'path
267 /// segments' which don't have the rest of an AST or HIR `PathSegment`.
268 #[derive(Clone, Copy, Debug)]
272 /// Signals whether this `PathSegment` has generic arguments. Used to avoid providing
273 /// nonsensical suggestions.
274 has_generic_args
: bool
,
278 fn from_path(path
: &Path
) -> Vec
<Segment
> {
279 path
.segments
.iter().map(|s
| s
.into()).collect()
282 fn from_ident(ident
: Ident
) -> Segment
{
283 Segment { ident, id: None, has_generic_args: false }
286 fn names_to_string(segments
: &[Segment
]) -> String
{
287 names_to_string(&segments
.iter().map(|seg
| seg
.ident
.name
).collect
::<Vec
<_
>>())
291 impl<'a
> From
<&'a ast
::PathSegment
> for Segment
{
292 fn from(seg
: &'a ast
::PathSegment
) -> Segment
{
293 Segment { ident: seg.ident, id: Some(seg.id), has_generic_args: seg.args.is_some() }
297 struct UsePlacementFinder
{
298 target_module
: NodeId
,
303 impl UsePlacementFinder
{
304 fn check(krate
: &Crate
, target_module
: NodeId
) -> (Option
<Span
>, bool
) {
305 let mut finder
= UsePlacementFinder { target_module, span: None, found_use: false }
;
306 if let ControlFlow
::Continue(..) = finder
.check_mod(&krate
.items
, CRATE_NODE_ID
) {
307 visit
::walk_crate(&mut finder
, krate
);
309 (finder
.span
, finder
.found_use
)
312 fn check_mod(&mut self, items
: &[P
<ast
::Item
>], node_id
: NodeId
) -> ControlFlow
<()> {
313 if self.span
.is_some() {
314 return ControlFlow
::Break(());
316 if node_id
!= self.target_module
{
317 return ControlFlow
::Continue(());
319 // find a use statement
322 ItemKind
::Use(..) => {
323 // don't suggest placing a use before the prelude
324 // import or other generated ones
325 if !item
.span
.from_expansion() {
326 self.span
= Some(item
.span
.shrink_to_lo());
327 self.found_use
= true;
328 return ControlFlow
::Break(());
331 // don't place use before extern crate
332 ItemKind
::ExternCrate(_
) => {}
333 // but place them before the first other item
335 if self.span
.map_or(true, |span
| item
.span
< span
)
336 && !item
.span
.from_expansion()
338 self.span
= Some(item
.span
.shrink_to_lo());
339 // don't insert between attributes and an item
340 // find the first attribute on the item
341 // FIXME: This is broken for active attributes.
342 for attr
in &item
.attrs
{
343 if !attr
.span
.is_dummy()
344 && self.span
.map_or(true, |span
| attr
.span
< span
)
346 self.span
= Some(attr
.span
.shrink_to_lo());
353 ControlFlow
::Continue(())
357 impl<'tcx
> Visitor
<'tcx
> for UsePlacementFinder
{
358 fn visit_item(&mut self, item
: &'tcx ast
::Item
) {
359 if let ItemKind
::Mod(_
, ModKind
::Loaded(items
, ..)) = &item
.kind
{
360 if let ControlFlow
::Break(..) = self.check_mod(items
, item
.id
) {
364 visit
::walk_item(self, item
);
368 /// An intermediate resolution result.
370 /// This refers to the thing referred by a name. The difference between `Res` and `Item` is that
371 /// items are visible in their whole block, while `Res`es only from the place they are defined
374 enum LexicalScopeBinding
<'a
> {
375 Item(&'a NameBinding
<'a
>),
379 impl<'a
> LexicalScopeBinding
<'a
> {
380 fn res(self) -> Res
{
382 LexicalScopeBinding
::Item(binding
) => binding
.res(),
383 LexicalScopeBinding
::Res(res
) => res
,
388 #[derive(Copy, Clone, Debug)]
389 enum ModuleOrUniformRoot
<'a
> {
393 /// Virtual module that denotes resolution in crate root with fallback to extern prelude.
394 CrateRootAndExternPrelude
,
396 /// Virtual module that denotes resolution in extern prelude.
397 /// Used for paths starting with `::` on 2018 edition.
400 /// Virtual module that denotes resolution in current scope.
401 /// Used only for resolving single-segment imports. The reason it exists is that import paths
402 /// are always split into two parts, the first of which should be some kind of module.
406 impl ModuleOrUniformRoot
<'_
> {
407 fn same_def(lhs
: Self, rhs
: Self) -> bool
{
409 (ModuleOrUniformRoot
::Module(lhs
), ModuleOrUniformRoot
::Module(rhs
)) => {
410 lhs
.def_id() == rhs
.def_id()
413 ModuleOrUniformRoot
::CrateRootAndExternPrelude
,
414 ModuleOrUniformRoot
::CrateRootAndExternPrelude
,
416 | (ModuleOrUniformRoot
::ExternPrelude
, ModuleOrUniformRoot
::ExternPrelude
)
417 | (ModuleOrUniformRoot
::CurrentScope
, ModuleOrUniformRoot
::CurrentScope
) => true,
423 #[derive(Clone, Debug)]
424 enum PathResult
<'a
> {
425 Module(ModuleOrUniformRoot
<'a
>),
426 NonModule(PartialRes
),
431 suggestion
: Option
<Suggestion
>,
432 is_error_from_last_segment
: bool
,
438 /// An anonymous module; e.g., just a block.
443 /// { // This is an anonymous module
444 /// f(); // This resolves to (2) as we are inside the block.
447 /// f(); // Resolves to (1)
451 /// Any module with a name.
455 /// * A normal module – either `mod from_file;` or `mod from_block { }` –
456 /// or the crate root (which is conceptually a top-level module).
457 /// Note that the crate root's [name][Self::name] will be [`kw::Empty`].
458 /// * A trait or an enum (it implicitly contains associated types, methods and variant
460 Def(DefKind
, DefId
, Symbol
),
464 /// Get name of the module.
465 pub fn name(&self) -> Option
<Symbol
> {
467 ModuleKind
::Block(..) => None
,
468 ModuleKind
::Def(.., name
) => Some(*name
),
473 /// A key that identifies a binding in a given `Module`.
475 /// Multiple bindings in the same module can have the same key (in a valid
476 /// program) if all but one of them come from glob imports.
477 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
479 /// The identifier for the binding, aways the `normalize_to_macros_2_0` version of the
483 /// 0 if ident is not `_`, otherwise a value that's unique to the specific
484 /// `_` in the expanded AST that introduced this binding.
488 type Resolutions
<'a
> = RefCell
<FxIndexMap
<BindingKey
, &'a RefCell
<NameResolution
<'a
>>>>;
490 /// One node in the tree of modules.
492 /// Note that a "module" in resolve is broader than a `mod` that you declare in Rust code. It may be one of these:
495 /// * crate root (aka, top-level anonymous module)
498 /// * curly-braced block with statements
500 /// You can use [`ModuleData::kind`] to determine the kind of module this is.
501 pub struct ModuleData
<'a
> {
502 /// The direct parent module (it may not be a `mod`, however).
503 parent
: Option
<Module
<'a
>>,
504 /// What kind of module this is, because this may not be a `mod`.
507 /// The [`DefId`] of the nearest `mod` item ancestor (which may be this module).
508 /// This may be the crate root.
509 nearest_parent_mod
: DefId
,
511 /// Mapping between names and their (possibly in-progress) resolutions in this module.
512 /// Resolutions in modules from other crates are not populated until accessed.
513 lazy_resolutions
: Resolutions
<'a
>,
514 /// True if this is a module from other crate that needs to be populated on access.
515 populate_on_access
: Cell
<bool
>,
517 /// Macro invocations that can expand into items in this module.
518 unexpanded_invocations
: RefCell
<FxHashSet
<LocalExpnId
>>,
520 /// Whether `#[no_implicit_prelude]` is active.
521 no_implicit_prelude
: bool
,
523 glob_importers
: RefCell
<Vec
<&'a Import
<'a
>>>,
524 globs
: RefCell
<Vec
<&'a Import
<'a
>>>,
526 /// Used to memoize the traits in this module for faster searches through all traits in scope.
527 traits
: RefCell
<Option
<Box
<[(Ident
, &'a NameBinding
<'a
>)]>>>,
529 /// Span of the module itself. Used for error reporting.
535 type Module
<'a
> = &'a ModuleData
<'a
>;
537 impl<'a
> ModuleData
<'a
> {
539 parent
: Option
<Module
<'a
>>,
541 nearest_parent_mod
: DefId
,
549 lazy_resolutions
: Default
::default(),
550 populate_on_access
: Cell
::new(!nearest_parent_mod
.is_local()),
551 unexpanded_invocations
: Default
::default(),
552 no_implicit_prelude
: false,
553 glob_importers
: RefCell
::new(Vec
::new()),
554 globs
: RefCell
::new(Vec
::new()),
555 traits
: RefCell
::new(None
),
561 fn for_each_child
<R
, F
>(&'a
self, resolver
: &mut R
, mut f
: F
)
563 R
: AsMut
<Resolver
<'a
>>,
564 F
: FnMut(&mut R
, Ident
, Namespace
, &'a NameBinding
<'a
>),
566 for (key
, name_resolution
) in resolver
.as_mut().resolutions(self).borrow().iter() {
567 if let Some(binding
) = name_resolution
.borrow().binding
{
568 f(resolver
, key
.ident
, key
.ns
, binding
);
573 /// This modifies `self` in place. The traits will be stored in `self.traits`.
574 fn ensure_traits
<R
>(&'a
self, resolver
: &mut R
)
576 R
: AsMut
<Resolver
<'a
>>,
578 let mut traits
= self.traits
.borrow_mut();
579 if traits
.is_none() {
580 let mut collected_traits
= Vec
::new();
581 self.for_each_child(resolver
, |_
, name
, ns
, binding
| {
585 if let Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
) = binding
.res() {
586 collected_traits
.push((name
, binding
))
589 *traits
= Some(collected_traits
.into_boxed_slice());
593 fn res(&self) -> Option
<Res
> {
595 ModuleKind
::Def(kind
, def_id
, _
) => Some(Res
::Def(kind
, def_id
)),
600 fn def_id(&self) -> Option
<DefId
> {
602 ModuleKind
::Def(_
, def_id
, _
) => Some(def_id
),
607 // `self` resolves to the first module ancestor that `is_normal`.
608 fn is_normal(&self) -> bool
{
609 matches
!(self.kind
, ModuleKind
::Def(DefKind
::Mod
, _
, _
))
612 fn is_trait(&self) -> bool
{
613 matches
!(self.kind
, ModuleKind
::Def(DefKind
::Trait
, _
, _
))
616 fn nearest_item_scope(&'a
self) -> Module
<'a
> {
618 ModuleKind
::Def(DefKind
::Enum
| DefKind
::Trait
, ..) => {
619 self.parent
.expect("enum or trait module without a parent")
625 fn is_ancestor_of(&self, mut other
: &Self) -> bool
{
626 while !ptr
::eq(self, other
) {
627 if let Some(parent
) = other
.parent
{
637 impl<'a
> fmt
::Debug
for ModuleData
<'a
> {
638 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
639 write
!(f
, "{:?}", self.res())
643 /// Records a possibly-private value, type, or module definition.
644 #[derive(Clone, Debug)]
645 pub struct NameBinding
<'a
> {
646 kind
: NameBindingKind
<'a
>,
647 ambiguity
: Option
<(&'a NameBinding
<'a
>, AmbiguityKind
)>,
648 expansion
: LocalExpnId
,
653 pub trait ToNameBinding
<'a
> {
654 fn to_name_binding(self, arenas
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
>;
657 impl<'a
> ToNameBinding
<'a
> for &'a NameBinding
<'a
> {
658 fn to_name_binding(self, _
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
> {
663 #[derive(Clone, Debug)]
664 enum NameBindingKind
<'a
> {
665 Res(Res
, /* is_macro_export */ bool
),
667 Import { binding: &'a NameBinding<'a>, import: &'a Import<'a>, used: Cell<bool> }
,
670 impl<'a
> NameBindingKind
<'a
> {
671 /// Is this a name binding of an import?
672 fn is_import(&self) -> bool
{
673 matches
!(*self, NameBindingKind
::Import { .. }
)
677 struct PrivacyError
<'a
> {
679 binding
: &'a NameBinding
<'a
>,
683 struct UseError
<'a
> {
684 err
: DiagnosticBuilder
<'a
>,
685 /// Candidates which user could `use` to access the missing type.
686 candidates
: Vec
<ImportSuggestion
>,
687 /// The `DefId` of the module to place the use-statements in.
689 /// Whether the diagnostic should say "instead" (as in `consider importing ... instead`).
691 /// Extra free-form suggestion.
692 suggestion
: Option
<(Span
, &'
static str, String
, Applicability
)>,
695 #[derive(Clone, Copy, PartialEq, Debug)]
700 MacroRulesVsModularized
,
708 fn descr(self) -> &'
static str {
710 AmbiguityKind
::Import
=> "name vs any other name during import resolution",
711 AmbiguityKind
::BuiltinAttr
=> "built-in attribute vs any other name",
712 AmbiguityKind
::DeriveHelper
=> "derive helper attribute vs any other name",
713 AmbiguityKind
::MacroRulesVsModularized
=> {
714 "`macro_rules` vs non-`macro_rules` from other module"
716 AmbiguityKind
::GlobVsOuter
=> {
717 "glob import vs any other name from outer scope during import/macro resolution"
719 AmbiguityKind
::GlobVsGlob
=> "glob import vs glob import in the same module",
720 AmbiguityKind
::GlobVsExpanded
=> {
721 "glob import vs macro-expanded name in the same \
722 module during import/macro resolution"
724 AmbiguityKind
::MoreExpandedVsOuter
=> {
725 "macro-expanded name vs less macro-expanded name \
726 from outer scope during import/macro resolution"
732 /// Miscellaneous bits of metadata for better ambiguity error reporting.
733 #[derive(Clone, Copy, PartialEq)]
734 enum AmbiguityErrorMisc
{
741 struct AmbiguityError
<'a
> {
744 b1
: &'a NameBinding
<'a
>,
745 b2
: &'a NameBinding
<'a
>,
746 misc1
: AmbiguityErrorMisc
,
747 misc2
: AmbiguityErrorMisc
,
750 impl<'a
> NameBinding
<'a
> {
751 fn module(&self) -> Option
<Module
<'a
>> {
753 NameBindingKind
::Module(module
) => Some(module
),
754 NameBindingKind
::Import { binding, .. }
=> binding
.module(),
759 fn res(&self) -> Res
{
761 NameBindingKind
::Res(res
, _
) => res
,
762 NameBindingKind
::Module(module
) => module
.res().unwrap(),
763 NameBindingKind
::Import { binding, .. }
=> binding
.res(),
767 fn is_ambiguity(&self) -> bool
{
768 self.ambiguity
.is_some()
770 NameBindingKind
::Import { binding, .. }
=> binding
.is_ambiguity(),
775 fn is_possibly_imported_variant(&self) -> bool
{
777 NameBindingKind
::Import { binding, .. }
=> binding
.is_possibly_imported_variant(),
778 NameBindingKind
::Res(
779 Res
::Def(DefKind
::Variant
| DefKind
::Ctor(CtorOf
::Variant
, ..), _
),
782 NameBindingKind
::Res(..) | NameBindingKind
::Module(..) => false,
786 fn is_extern_crate(&self) -> bool
{
788 NameBindingKind
::Import
{
789 import
: &Import { kind: ImportKind::ExternCrate { .. }
, .. },
792 NameBindingKind
::Module(&ModuleData
{
793 kind
: ModuleKind
::Def(DefKind
::Mod
, def_id
, _
),
795 }) => def_id
.index
== CRATE_DEF_INDEX
,
800 fn is_import(&self) -> bool
{
801 matches
!(self.kind
, NameBindingKind
::Import { .. }
)
804 fn is_glob_import(&self) -> bool
{
806 NameBindingKind
::Import { import, .. }
=> import
.is_glob(),
811 fn is_importable(&self) -> bool
{
814 Res
::Def(DefKind
::AssocConst
| DefKind
::AssocFn
| DefKind
::AssocTy
, _
)
818 fn is_macro_def(&self) -> bool
{
819 matches
!(self.kind
, NameBindingKind
::Res(Res
::Def(DefKind
::Macro(..), _
), _
))
822 fn macro_kind(&self) -> Option
<MacroKind
> {
823 self.res().macro_kind()
826 // Suppose that we resolved macro invocation with `invoc_parent_expansion` to binding `binding`
827 // at some expansion round `max(invoc, binding)` when they both emerged from macros.
828 // Then this function returns `true` if `self` may emerge from a macro *after* that
829 // in some later round and screw up our previously found resolution.
830 // See more detailed explanation in
831 // https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049
834 invoc_parent_expansion
: LocalExpnId
,
835 binding
: &NameBinding
<'_
>,
837 // self > max(invoc, binding) => !(self <= invoc || self <= binding)
838 // Expansions are partially ordered, so "may appear after" is an inversion of
839 // "certainly appears before or simultaneously" and includes unordered cases.
840 let self_parent_expansion
= self.expansion
;
841 let other_parent_expansion
= binding
.expansion
;
842 let certainly_before_other_or_simultaneously
=
843 other_parent_expansion
.is_descendant_of(self_parent_expansion
);
844 let certainly_before_invoc_or_simultaneously
=
845 invoc_parent_expansion
.is_descendant_of(self_parent_expansion
);
846 !(certainly_before_other_or_simultaneously
|| certainly_before_invoc_or_simultaneously
)
850 #[derive(Debug, Default, Clone)]
851 pub struct ExternPreludeEntry
<'a
> {
852 extern_crate_item
: Option
<&'a NameBinding
<'a
>>,
853 pub introduced_by_item
: bool
,
856 /// Used for better errors for E0773
857 enum BuiltinMacroState
{
858 NotYetSeen(SyntaxExtensionKind
),
863 resolutions
: DeriveResolutions
,
864 helper_attrs
: Vec
<(usize, Ident
)>,
865 has_derive_copy
: bool
,
868 /// The main resolver class.
870 /// This is the visitor that walks the whole crate.
871 pub struct Resolver
<'a
> {
872 session
: &'a Session
,
874 definitions
: Definitions
,
876 graph_root
: Module
<'a
>,
878 prelude
: Option
<Module
<'a
>>,
879 extern_prelude
: FxHashMap
<Ident
, ExternPreludeEntry
<'a
>>,
881 /// N.B., this is used only for better diagnostics, not name resolution itself.
882 has_self
: FxHashSet
<DefId
>,
884 /// Names of fields of an item `DefId` accessible with dot syntax.
885 /// Used for hints during error reporting.
886 field_names
: FxHashMap
<DefId
, Vec
<Spanned
<Symbol
>>>,
888 /// All imports known to succeed or fail.
889 determined_imports
: Vec
<&'a Import
<'a
>>,
891 /// All non-determined imports.
892 indeterminate_imports
: Vec
<&'a Import
<'a
>>,
894 /// FIXME: Refactor things so that these fields are passed through arguments and not resolver.
895 /// We are resolving a last import segment during import validation.
896 last_import_segment
: bool
,
897 /// This binding should be ignored during in-module resolution, so that we don't get
898 /// "self-confirming" import resolutions during import validation.
899 unusable_binding
: Option
<&'a NameBinding
<'a
>>,
901 // Spans for local variables found during pattern resolution.
902 // Used for suggestions during error reporting.
903 pat_span_map
: NodeMap
<Span
>,
905 /// Resolutions for nodes that have a single resolution.
906 partial_res_map
: NodeMap
<PartialRes
>,
907 /// Resolutions for import nodes, which have multiple resolutions in different namespaces.
908 import_res_map
: NodeMap
<PerNS
<Option
<Res
>>>,
909 /// Resolutions for labels (node IDs of their corresponding blocks or loops).
910 label_res_map
: NodeMap
<NodeId
>,
912 /// `CrateNum` resolutions of `extern crate` items.
913 extern_crate_map
: FxHashMap
<LocalDefId
, CrateNum
>,
914 export_map
: ExportMap
<LocalDefId
>,
915 trait_map
: Option
<NodeMap
<Vec
<TraitCandidate
>>>,
917 /// A map from nodes to anonymous modules.
918 /// Anonymous modules are pseudo-modules that are implicitly created around items
919 /// contained within blocks.
921 /// For example, if we have this:
929 /// There will be an anonymous module created around `g` with the ID of the
930 /// entry block for `f`.
931 block_map
: NodeMap
<Module
<'a
>>,
932 /// A fake module that contains no definition and no prelude. Used so that
933 /// some AST passes can generate identifiers that only resolve to local or
935 empty_module
: Module
<'a
>,
936 module_map
: FxHashMap
<LocalDefId
, Module
<'a
>>,
937 extern_module_map
: FxHashMap
<DefId
, Module
<'a
>>,
938 binding_parent_modules
: FxHashMap
<PtrKey
<'a
, NameBinding
<'a
>>, Module
<'a
>>,
939 underscore_disambiguator
: u32,
941 /// Maps glob imports to the names of items actually imported.
942 glob_map
: FxHashMap
<LocalDefId
, FxHashSet
<Symbol
>>,
943 /// Visibilities in "lowered" form, for all entities that have them.
944 visibilities
: FxHashMap
<LocalDefId
, ty
::Visibility
>,
945 used_imports
: FxHashSet
<NodeId
>,
946 maybe_unused_trait_imports
: FxHashSet
<LocalDefId
>,
947 maybe_unused_extern_crates
: Vec
<(LocalDefId
, Span
)>,
949 /// Privacy errors are delayed until the end in order to deduplicate them.
950 privacy_errors
: Vec
<PrivacyError
<'a
>>,
951 /// Ambiguity errors are delayed for deduplication.
952 ambiguity_errors
: Vec
<AmbiguityError
<'a
>>,
953 /// `use` injections are delayed for better placement and deduplication.
954 use_injections
: Vec
<UseError
<'a
>>,
955 /// Crate-local macro expanded `macro_export` referred to by a module-relative path.
956 macro_expanded_macro_export_errors
: BTreeSet
<(Span
, Span
)>,
958 arenas
: &'a ResolverArenas
<'a
>,
959 dummy_binding
: &'a NameBinding
<'a
>,
961 crate_loader
: CrateLoader
<'a
>,
962 macro_names
: FxHashSet
<Ident
>,
963 builtin_macros
: FxHashMap
<Symbol
, BuiltinMacroState
>,
964 registered_attrs
: FxHashSet
<Ident
>,
965 registered_tools
: FxHashSet
<Ident
>,
966 macro_use_prelude
: FxHashMap
<Symbol
, &'a NameBinding
<'a
>>,
967 all_macros
: FxHashMap
<Symbol
, Res
>,
968 macro_map
: FxHashMap
<DefId
, Lrc
<SyntaxExtension
>>,
969 dummy_ext_bang
: Lrc
<SyntaxExtension
>,
970 dummy_ext_derive
: Lrc
<SyntaxExtension
>,
971 non_macro_attr
: Lrc
<SyntaxExtension
>,
972 local_macro_def_scopes
: FxHashMap
<LocalDefId
, Module
<'a
>>,
973 ast_transform_scopes
: FxHashMap
<LocalExpnId
, Module
<'a
>>,
974 unused_macros
: FxHashMap
<LocalDefId
, (NodeId
, Span
)>,
975 proc_macro_stubs
: FxHashSet
<LocalDefId
>,
976 /// Traces collected during macro resolution and validated when it's complete.
977 single_segment_macro_resolutions
:
978 Vec
<(Ident
, MacroKind
, ParentScope
<'a
>, Option
<&'a NameBinding
<'a
>>)>,
979 multi_segment_macro_resolutions
:
980 Vec
<(Vec
<Segment
>, Span
, MacroKind
, ParentScope
<'a
>, Option
<Res
>)>,
981 builtin_attrs
: Vec
<(Ident
, ParentScope
<'a
>)>,
982 /// `derive(Copy)` marks items they are applied to so they are treated specially later.
983 /// Derive macros cannot modify the item themselves and have to store the markers in the global
984 /// context, so they attach the markers to derive container IDs using this resolver table.
985 containers_deriving_copy
: FxHashSet
<LocalExpnId
>,
986 /// Parent scopes in which the macros were invoked.
987 /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
988 invocation_parent_scopes
: FxHashMap
<LocalExpnId
, ParentScope
<'a
>>,
989 /// `macro_rules` scopes *produced* by expanding the macro invocations,
990 /// include all the `macro_rules` items and other invocations generated by them.
991 output_macro_rules_scopes
: FxHashMap
<LocalExpnId
, MacroRulesScopeRef
<'a
>>,
992 /// Helper attributes that are in scope for the given expansion.
993 helper_attrs
: FxHashMap
<LocalExpnId
, Vec
<Ident
>>,
994 /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute
995 /// with the given `ExpnId`.
996 derive_data
: FxHashMap
<LocalExpnId
, DeriveData
>,
998 /// Avoid duplicated errors for "name already defined".
999 name_already_seen
: FxHashMap
<Symbol
, Span
>,
1001 potentially_unused_imports
: Vec
<&'a Import
<'a
>>,
1003 /// Table for mapping struct IDs into struct constructor IDs,
1004 /// it's not used during normal resolution, only for better error reporting.
1005 /// Also includes of list of each fields visibility
1006 struct_constructors
: DefIdMap
<(Res
, ty
::Visibility
, Vec
<ty
::Visibility
>)>,
1008 /// Features enabled for this crate.
1009 active_features
: FxHashSet
<Symbol
>,
1011 lint_buffer
: LintBuffer
,
1013 next_node_id
: NodeId
,
1015 def_id_to_span
: IndexVec
<LocalDefId
, Span
>,
1017 node_id_to_def_id
: FxHashMap
<ast
::NodeId
, LocalDefId
>,
1018 def_id_to_node_id
: IndexVec
<LocalDefId
, ast
::NodeId
>,
1020 /// Indices of unnamed struct or variant fields with unresolved attributes.
1021 placeholder_field_indices
: FxHashMap
<NodeId
, usize>,
1022 /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
1023 /// we know what parent node that fragment should be attached to thanks to this table,
1024 /// and how the `impl Trait` fragments were introduced.
1025 invocation_parents
: FxHashMap
<LocalExpnId
, (LocalDefId
, ImplTraitContext
)>,
1027 next_disambiguator
: FxHashMap
<(LocalDefId
, DefPathData
), u32>,
1028 /// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
1029 /// FIXME: Replace with a more general AST map (together with some other fields).
1030 trait_impl_items
: FxHashSet
<LocalDefId
>,
1032 legacy_const_generic_args
: FxHashMap
<DefId
, Option
<Vec
<usize>>>,
1033 /// Amount of lifetime parameters for each item in the crate.
1034 item_generics_num_lifetimes
: FxHashMap
<LocalDefId
, usize>,
1036 main_def
: Option
<MainDefinition
>,
1037 trait_impls
: BTreeMap
<DefId
, Vec
<LocalDefId
>>,
1038 /// A list of proc macro LocalDefIds, written out in the order in which
1039 /// they are declared in the static array generated by proc_macro_harness.
1040 proc_macros
: Vec
<NodeId
>,
1043 /// Nothing really interesting here; it just provides memory for the rest of the crate.
1045 pub struct ResolverArenas
<'a
> {
1046 modules
: TypedArena
<ModuleData
<'a
>>,
1047 local_modules
: RefCell
<Vec
<Module
<'a
>>>,
1048 imports
: TypedArena
<Import
<'a
>>,
1049 name_resolutions
: TypedArena
<RefCell
<NameResolution
<'a
>>>,
1050 ast_paths
: TypedArena
<ast
::Path
>,
1051 dropless
: DroplessArena
,
1054 impl<'a
> ResolverArenas
<'a
> {
1055 fn alloc_module(&'a
self, module
: ModuleData
<'a
>) -> Module
<'a
> {
1056 let module
= self.modules
.alloc(module
);
1057 if module
.def_id().map_or(true, |def_id
| def_id
.is_local()) {
1058 self.local_modules
.borrow_mut().push(module
);
1062 fn local_modules(&'a
self) -> std
::cell
::Ref
<'a
, Vec
<Module
<'a
>>> {
1063 self.local_modules
.borrow()
1065 fn alloc_name_binding(&'a
self, name_binding
: NameBinding
<'a
>) -> &'a NameBinding
<'a
> {
1066 self.dropless
.alloc(name_binding
)
1068 fn alloc_import(&'a
self, import
: Import
<'a
>) -> &'a Import
<'_
> {
1069 self.imports
.alloc(import
)
1071 fn alloc_name_resolution(&'a
self) -> &'a RefCell
<NameResolution
<'a
>> {
1072 self.name_resolutions
.alloc(Default
::default())
1074 fn alloc_macro_rules_scope(&'a
self, scope
: MacroRulesScope
<'a
>) -> MacroRulesScopeRef
<'a
> {
1075 PtrKey(self.dropless
.alloc(Cell
::new(scope
)))
1077 fn alloc_macro_rules_binding(
1079 binding
: MacroRulesBinding
<'a
>,
1080 ) -> &'a MacroRulesBinding
<'a
> {
1081 self.dropless
.alloc(binding
)
1083 fn alloc_ast_paths(&'a
self, paths
: &[ast
::Path
]) -> &'a
[ast
::Path
] {
1084 self.ast_paths
.alloc_from_iter(paths
.iter().cloned())
1086 fn alloc_pattern_spans(&'a
self, spans
: impl Iterator
<Item
= Span
>) -> &'a
[Span
] {
1087 self.dropless
.alloc_from_iter(spans
)
1091 impl<'a
> AsMut
<Resolver
<'a
>> for Resolver
<'a
> {
1092 fn as_mut(&mut self) -> &mut Resolver
<'a
> {
1097 impl<'a
, 'b
> DefIdTree
for &'a Resolver
<'b
> {
1098 fn parent(self, id
: DefId
) -> Option
<DefId
> {
1099 match id
.as_local() {
1100 Some(id
) => self.definitions
.def_key(id
).parent
,
1101 None
=> self.cstore().def_key(id
).parent
,
1103 .map(|index
| DefId { index, ..id }
)
1107 /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
1108 /// the resolver is no longer needed as all the relevant information is inline.
1109 impl ResolverAstLowering
for Resolver
<'_
> {
1110 fn def_key(&mut self, id
: DefId
) -> DefKey
{
1111 if let Some(id
) = id
.as_local() {
1112 self.definitions().def_key(id
)
1114 self.cstore().def_key(id
)
1118 fn item_generics_num_lifetimes(&self, def_id
: DefId
) -> usize {
1119 if let Some(def_id
) = def_id
.as_local() {
1120 self.item_generics_num_lifetimes
[&def_id
]
1122 self.cstore().item_generics_num_lifetimes(def_id
, self.session
)
1126 fn legacy_const_generic_args(&mut self, expr
: &Expr
) -> Option
<Vec
<usize>> {
1127 self.legacy_const_generic_args(expr
)
1130 fn get_partial_res(&mut self, id
: NodeId
) -> Option
<PartialRes
> {
1131 self.partial_res_map
.get(&id
).cloned()
1134 fn get_import_res(&mut self, id
: NodeId
) -> PerNS
<Option
<Res
>> {
1135 self.import_res_map
.get(&id
).cloned().unwrap_or_default()
1138 fn get_label_res(&mut self, id
: NodeId
) -> Option
<NodeId
> {
1139 self.label_res_map
.get(&id
).cloned()
1142 fn definitions(&mut self) -> &mut Definitions
{
1143 &mut self.definitions
1146 fn lint_buffer(&mut self) -> &mut LintBuffer
{
1147 &mut self.lint_buffer
1150 fn next_node_id(&mut self) -> NodeId
{
1154 fn take_trait_map(&mut self) -> NodeMap
<Vec
<TraitCandidate
>> {
1155 std
::mem
::replace(&mut self.trait_map
, None
).unwrap()
1158 fn opt_local_def_id(&self, node
: NodeId
) -> Option
<LocalDefId
> {
1159 self.node_id_to_def_id
.get(&node
).copied()
1162 fn local_def_id(&self, node
: NodeId
) -> LocalDefId
{
1163 self.opt_local_def_id(node
).unwrap_or_else(|| panic
!("no entry for node id: `{:?}`", node
))
1166 fn def_path_hash(&self, def_id
: DefId
) -> DefPathHash
{
1167 match def_id
.as_local() {
1168 Some(def_id
) => self.definitions
.def_path_hash(def_id
),
1169 None
=> self.cstore().def_path_hash(def_id
),
1173 /// Adds a definition with a parent definition.
1177 node_id
: ast
::NodeId
,
1183 !self.node_id_to_def_id
.contains_key(&node_id
),
1184 "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
1187 self.definitions
.def_key(self.node_id_to_def_id
[&node_id
]),
1190 // Find the next free disambiguator for this key.
1191 let next_disambiguator
= &mut self.next_disambiguator
;
1192 let next_disambiguator
= |parent
, data
| {
1193 let next_disamb
= next_disambiguator
.entry((parent
, data
)).or_insert(0);
1194 let disambiguator
= *next_disamb
;
1195 *next_disamb
= next_disamb
.checked_add(1).expect("disambiguator overflow");
1199 let def_id
= self.definitions
.create_def(parent
, data
, expn_id
, next_disambiguator
);
1201 assert_eq
!(self.def_id_to_span
.push(span
), def_id
);
1203 // Some things for which we allocate `LocalDefId`s don't correspond to
1204 // anything in the AST, so they don't have a `NodeId`. For these cases
1205 // we don't need a mapping from `NodeId` to `LocalDefId`.
1206 if node_id
!= ast
::DUMMY_NODE_ID
{
1207 debug
!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id
, node_id
);
1208 self.node_id_to_def_id
.insert(node_id
, def_id
);
1210 assert_eq
!(self.def_id_to_node_id
.push(node_id
), def_id
);
1216 struct ExpandHasher
<'a
, 'b
> {
1217 source_map
: CachingSourceMapView
<'a
>,
1218 resolver
: &'a Resolver
<'b
>,
1221 impl<'a
, 'b
> rustc_span
::HashStableContext
for ExpandHasher
<'a
, 'b
> {
1223 fn hash_spans(&self) -> bool
{
1228 fn def_path_hash(&self, def_id
: DefId
) -> DefPathHash
{
1229 self.resolver
.def_path_hash(def_id
)
1233 fn span_data_to_lines_and_cols(
1235 span
: &rustc_span
::SpanData
,
1236 ) -> Option
<(Lrc
<rustc_span
::SourceFile
>, usize, rustc_span
::BytePos
, usize, rustc_span
::BytePos
)>
1238 self.source_map
.span_data_to_lines_and_cols(span
)
1242 impl<'a
> Resolver
<'a
> {
1244 session
: &'a Session
,
1247 metadata_loader
: Box
<MetadataLoaderDyn
>,
1248 arenas
: &'a ResolverArenas
<'a
>,
1250 let root_local_def_id
= LocalDefId { local_def_index: CRATE_DEF_INDEX }
;
1251 let root_def_id
= root_local_def_id
.to_def_id();
1252 let root_module_kind
= ModuleKind
::Def(DefKind
::Mod
, root_def_id
, kw
::Empty
);
1253 let graph_root
= arenas
.alloc_module(ModuleData
{
1254 no_implicit_prelude
: session
.contains_name(&krate
.attrs
, sym
::no_implicit_prelude
),
1255 ..ModuleData
::new(None
, root_module_kind
, root_def_id
, ExpnId
::root(), krate
.span
)
1257 let empty_module_kind
= ModuleKind
::Def(DefKind
::Mod
, root_def_id
, kw
::Empty
);
1258 let empty_module
= arenas
.alloc_module(ModuleData
{
1259 no_implicit_prelude
: true,
1268 let mut module_map
= FxHashMap
::default();
1269 module_map
.insert(root_local_def_id
, graph_root
);
1271 let definitions
= Definitions
::new(session
.local_stable_crate_id());
1272 let root
= definitions
.get_root_def();
1274 let mut visibilities
= FxHashMap
::default();
1275 visibilities
.insert(root_local_def_id
, ty
::Visibility
::Public
);
1277 let mut def_id_to_span
= IndexVec
::default();
1278 assert_eq
!(def_id_to_span
.push(rustc_span
::DUMMY_SP
), root
);
1279 let mut def_id_to_node_id
= IndexVec
::default();
1280 assert_eq
!(def_id_to_node_id
.push(CRATE_NODE_ID
), root
);
1281 let mut node_id_to_def_id
= FxHashMap
::default();
1282 node_id_to_def_id
.insert(CRATE_NODE_ID
, root
);
1284 let mut invocation_parents
= FxHashMap
::default();
1285 invocation_parents
.insert(LocalExpnId
::ROOT
, (root
, ImplTraitContext
::Existential
));
1287 let mut extern_prelude
: FxHashMap
<Ident
, ExternPreludeEntry
<'_
>> = session
1291 .filter(|(_
, entry
)| entry
.add_prelude
)
1292 .map(|(name
, _
)| (Ident
::from_str(name
), Default
::default()))
1295 if !session
.contains_name(&krate
.attrs
, sym
::no_core
) {
1296 extern_prelude
.insert(Ident
::with_dummy_span(sym
::core
), Default
::default());
1297 if !session
.contains_name(&krate
.attrs
, sym
::no_std
) {
1298 extern_prelude
.insert(Ident
::with_dummy_span(sym
::std
), Default
::default());
1302 let (registered_attrs
, registered_tools
) =
1303 macros
::registered_attrs_and_tools(session
, &krate
.attrs
);
1305 let features
= session
.features_untracked();
1307 let mut resolver
= Resolver
{
1312 // The outermost module has def ID 0; this is not reflected in the
1318 has_self
: FxHashSet
::default(),
1319 field_names
: FxHashMap
::default(),
1321 determined_imports
: Vec
::new(),
1322 indeterminate_imports
: Vec
::new(),
1324 last_import_segment
: false,
1325 unusable_binding
: None
,
1327 pat_span_map
: Default
::default(),
1328 partial_res_map
: Default
::default(),
1329 import_res_map
: Default
::default(),
1330 label_res_map
: Default
::default(),
1331 extern_crate_map
: Default
::default(),
1332 export_map
: FxHashMap
::default(),
1333 trait_map
: Some(NodeMap
::default()),
1334 underscore_disambiguator
: 0,
1337 block_map
: Default
::default(),
1338 extern_module_map
: FxHashMap
::default(),
1339 binding_parent_modules
: FxHashMap
::default(),
1340 ast_transform_scopes
: FxHashMap
::default(),
1342 glob_map
: Default
::default(),
1344 used_imports
: FxHashSet
::default(),
1345 maybe_unused_trait_imports
: Default
::default(),
1346 maybe_unused_extern_crates
: Vec
::new(),
1348 privacy_errors
: Vec
::new(),
1349 ambiguity_errors
: Vec
::new(),
1350 use_injections
: Vec
::new(),
1351 macro_expanded_macro_export_errors
: BTreeSet
::new(),
1354 dummy_binding
: arenas
.alloc_name_binding(NameBinding
{
1355 kind
: NameBindingKind
::Res(Res
::Err
, false),
1357 expansion
: LocalExpnId
::ROOT
,
1359 vis
: ty
::Visibility
::Public
,
1362 crate_loader
: CrateLoader
::new(session
, metadata_loader
, crate_name
),
1363 macro_names
: FxHashSet
::default(),
1364 builtin_macros
: Default
::default(),
1367 macro_use_prelude
: FxHashMap
::default(),
1368 all_macros
: FxHashMap
::default(),
1369 macro_map
: FxHashMap
::default(),
1370 dummy_ext_bang
: Lrc
::new(SyntaxExtension
::dummy_bang(session
.edition())),
1371 dummy_ext_derive
: Lrc
::new(SyntaxExtension
::dummy_derive(session
.edition())),
1372 non_macro_attr
: Lrc
::new(SyntaxExtension
::non_macro_attr(session
.edition())),
1373 invocation_parent_scopes
: Default
::default(),
1374 output_macro_rules_scopes
: Default
::default(),
1375 helper_attrs
: Default
::default(),
1376 derive_data
: Default
::default(),
1377 local_macro_def_scopes
: FxHashMap
::default(),
1378 name_already_seen
: FxHashMap
::default(),
1379 potentially_unused_imports
: Vec
::new(),
1380 struct_constructors
: Default
::default(),
1381 unused_macros
: Default
::default(),
1382 proc_macro_stubs
: Default
::default(),
1383 single_segment_macro_resolutions
: Default
::default(),
1384 multi_segment_macro_resolutions
: Default
::default(),
1385 builtin_attrs
: Default
::default(),
1386 containers_deriving_copy
: Default
::default(),
1387 active_features
: features
1388 .declared_lib_features
1390 .map(|(feat
, ..)| *feat
)
1391 .chain(features
.declared_lang_features
.iter().map(|(feat
, ..)| *feat
))
1393 lint_buffer
: LintBuffer
::default(),
1394 next_node_id
: NodeId
::from_u32(1),
1398 placeholder_field_indices
: Default
::default(),
1400 next_disambiguator
: Default
::default(),
1401 trait_impl_items
: Default
::default(),
1402 legacy_const_generic_args
: Default
::default(),
1403 item_generics_num_lifetimes
: Default
::default(),
1404 main_def
: Default
::default(),
1405 trait_impls
: Default
::default(),
1406 proc_macros
: Default
::default(),
1409 let root_parent_scope
= ParentScope
::module(graph_root
, &resolver
);
1410 resolver
.invocation_parent_scopes
.insert(LocalExpnId
::ROOT
, root_parent_scope
);
1415 fn create_stable_hashing_context(&self) -> ExpandHasher
<'_
, 'a
> {
1417 source_map
: CachingSourceMapView
::new(self.session
.source_map()),
1422 pub fn next_node_id(&mut self) -> NodeId
{
1427 .expect("input too large; ran out of NodeIds");
1428 self.next_node_id
= ast
::NodeId
::from_usize(next
);
1432 pub fn lint_buffer(&mut self) -> &mut LintBuffer
{
1433 &mut self.lint_buffer
1436 pub fn arenas() -> ResolverArenas
<'a
> {
1440 pub fn into_outputs(self) -> ResolverOutputs
{
1441 let proc_macros
= self.proc_macros
.iter().map(|id
| self.local_def_id(*id
)).collect();
1442 let definitions
= self.definitions
;
1443 let visibilities
= self.visibilities
;
1444 let extern_crate_map
= self.extern_crate_map
;
1445 let export_map
= self.export_map
;
1446 let maybe_unused_trait_imports
= self.maybe_unused_trait_imports
;
1447 let maybe_unused_extern_crates
= self.maybe_unused_extern_crates
;
1448 let glob_map
= self.glob_map
;
1449 let main_def
= self.main_def
;
1452 cstore
: Box
::new(self.crate_loader
.into_cstore()),
1457 maybe_unused_trait_imports
,
1458 maybe_unused_extern_crates
,
1459 extern_prelude
: self
1462 .map(|(ident
, entry
)| (ident
.name
, entry
.introduced_by_item
))
1465 trait_impls
: self.trait_impls
,
1470 pub fn clone_outputs(&self) -> ResolverOutputs
{
1471 let proc_macros
= self.proc_macros
.iter().map(|id
| self.local_def_id(*id
)).collect();
1473 definitions
: self.definitions
.clone(),
1474 cstore
: Box
::new(self.cstore().clone()),
1475 visibilities
: self.visibilities
.clone(),
1476 extern_crate_map
: self.extern_crate_map
.clone(),
1477 export_map
: self.export_map
.clone(),
1478 glob_map
: self.glob_map
.clone(),
1479 maybe_unused_trait_imports
: self.maybe_unused_trait_imports
.clone(),
1480 maybe_unused_extern_crates
: self.maybe_unused_extern_crates
.clone(),
1481 extern_prelude
: self
1484 .map(|(ident
, entry
)| (ident
.name
, entry
.introduced_by_item
))
1486 main_def
: self.main_def
.clone(),
1487 trait_impls
: self.trait_impls
.clone(),
1492 pub fn cstore(&self) -> &CStore
{
1493 self.crate_loader
.cstore()
1496 fn dummy_ext(&self, macro_kind
: MacroKind
) -> Lrc
<SyntaxExtension
> {
1498 MacroKind
::Bang
=> self.dummy_ext_bang
.clone(),
1499 MacroKind
::Derive
=> self.dummy_ext_derive
.clone(),
1500 MacroKind
::Attr
=> self.non_macro_attr
.clone(),
1504 /// Runs the function on each namespace.
1505 fn per_ns
<F
: FnMut(&mut Self, Namespace
)>(&mut self, mut f
: F
) {
1511 fn is_builtin_macro(&mut self, res
: Res
) -> bool
{
1512 self.get_macro(res
).map_or(false, |ext
| ext
.builtin_name
.is_some())
1515 fn macro_def(&self, mut ctxt
: SyntaxContext
) -> DefId
{
1517 match ctxt
.outer_expn_data().macro_def_id
{
1518 Some(def_id
) => return def_id
,
1519 None
=> ctxt
.remove_mark(),
1524 /// Entry point to crate resolution.
1525 pub fn resolve_crate(&mut self, krate
: &Crate
) {
1526 self.session
.time("resolve_crate", || {
1527 self.session
.time("finalize_imports", || ImportResolver { r: self }
.finalize_imports());
1528 self.session
.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
1529 self.session
.time("late_resolve_crate", || self.late_resolve_crate(krate
));
1530 self.session
.time("resolve_main", || self.resolve_main());
1531 self.session
.time("resolve_check_unused", || self.check_unused(krate
));
1532 self.session
.time("resolve_report_errors", || self.report_errors(krate
));
1533 self.session
.time("resolve_postprocess", || self.crate_loader
.postprocess(krate
));
1537 pub fn traits_in_scope(
1539 current_trait
: Option
<Module
<'a
>>,
1540 parent_scope
: &ParentScope
<'a
>,
1541 ctxt
: SyntaxContext
,
1542 assoc_item
: Option
<(Symbol
, Namespace
)>,
1543 ) -> Vec
<TraitCandidate
> {
1544 let mut found_traits
= Vec
::new();
1546 if let Some(module
) = current_trait
{
1547 if self.trait_may_have_item(Some(module
), assoc_item
) {
1548 let def_id
= module
.def_id().unwrap();
1549 found_traits
.push(TraitCandidate { def_id, import_ids: smallvec![] }
);
1553 self.visit_scopes(ScopeSet
::All(TypeNS
, false), parent_scope
, ctxt
, |this
, scope
, _
, _
| {
1555 Scope
::Module(module
, _
) => {
1556 this
.traits_in_module(module
, assoc_item
, &mut found_traits
);
1558 Scope
::StdLibPrelude
=> {
1559 if let Some(module
) = this
.prelude
{
1560 this
.traits_in_module(module
, assoc_item
, &mut found_traits
);
1563 Scope
::ExternPrelude
| Scope
::ToolPrelude
| Scope
::BuiltinTypes
=> {}
1564 _
=> unreachable
!(),
1572 fn traits_in_module(
1575 assoc_item
: Option
<(Symbol
, Namespace
)>,
1576 found_traits
: &mut Vec
<TraitCandidate
>,
1578 module
.ensure_traits(self);
1579 let traits
= module
.traits
.borrow();
1580 for (trait_name
, trait_binding
) in traits
.as_ref().unwrap().iter() {
1581 if self.trait_may_have_item(trait_binding
.module(), assoc_item
) {
1582 let def_id
= trait_binding
.res().def_id();
1583 let import_ids
= self.find_transitive_imports(&trait_binding
.kind
, *trait_name
);
1584 found_traits
.push(TraitCandidate { def_id, import_ids }
);
1589 // List of traits in scope is pruned on best effort basis. We reject traits not having an
1590 // associated item with the given name and namespace (if specified). This is a conservative
1591 // optimization, proper hygienic type-based resolution of associated items is done in typeck.
1592 // We don't reject trait aliases (`trait_module == None`) because we don't have access to their
1593 // associated items.
1594 fn trait_may_have_item(
1596 trait_module
: Option
<Module
<'a
>>,
1597 assoc_item
: Option
<(Symbol
, Namespace
)>,
1599 match (trait_module
, assoc_item
) {
1600 (Some(trait_module
), Some((name
, ns
))) => {
1601 self.resolutions(trait_module
).borrow().iter().any(|resolution
| {
1602 let (&BindingKey { ident: assoc_ident, ns: assoc_ns, .. }
, _
) = resolution
;
1603 assoc_ns
== ns
&& assoc_ident
.name
== name
1610 fn find_transitive_imports(
1612 mut kind
: &NameBindingKind
<'_
>,
1614 ) -> SmallVec
<[LocalDefId
; 1]> {
1615 let mut import_ids
= smallvec
![];
1616 while let NameBindingKind
::Import { import, binding, .. }
= kind
{
1617 let id
= self.local_def_id(import
.id
);
1618 self.maybe_unused_trait_imports
.insert(id
);
1619 self.add_to_glob_map(&import
, trait_name
);
1620 import_ids
.push(id
);
1621 kind
= &binding
.kind
;
1630 nearest_parent_mod
: DefId
,
1634 let module
= ModuleData
::new(Some(parent
), kind
, nearest_parent_mod
, expn_id
, span
);
1635 self.arenas
.alloc_module(module
)
1638 fn new_key(&mut self, ident
: Ident
, ns
: Namespace
) -> BindingKey
{
1639 let ident
= ident
.normalize_to_macros_2_0();
1640 let disambiguator
= if ident
.name
== kw
::Underscore
{
1641 self.underscore_disambiguator
+= 1;
1642 self.underscore_disambiguator
1646 BindingKey { ident, ns, disambiguator }
1649 fn resolutions(&mut self, module
: Module
<'a
>) -> &'a Resolutions
<'a
> {
1650 if module
.populate_on_access
.get() {
1651 module
.populate_on_access
.set(false);
1652 self.build_reduced_graph_external(module
);
1654 &module
.lazy_resolutions
1661 ) -> &'a RefCell
<NameResolution
<'a
>> {
1663 .resolutions(module
)
1666 .or_insert_with(|| self.arenas
.alloc_name_resolution())
1672 used_binding
: &'a NameBinding
<'a
>,
1673 is_lexical_scope
: bool
,
1675 if let Some((b2
, kind
)) = used_binding
.ambiguity
{
1676 self.ambiguity_errors
.push(AmbiguityError
{
1681 misc1
: AmbiguityErrorMisc
::None
,
1682 misc2
: AmbiguityErrorMisc
::None
,
1685 if let NameBindingKind
::Import { import, binding, ref used }
= used_binding
.kind
{
1686 // Avoid marking `extern crate` items that refer to a name from extern prelude,
1687 // but not introduce it, as used if they are accessed from lexical scope.
1688 if is_lexical_scope
{
1689 if let Some(entry
) = self.extern_prelude
.get(&ident
.normalize_to_macros_2_0()) {
1690 if let Some(crate_item
) = entry
.extern_crate_item
{
1691 if ptr
::eq(used_binding
, crate_item
) && !entry
.introduced_by_item
{
1698 import
.used
.set(true);
1699 self.used_imports
.insert(import
.id
);
1700 self.add_to_glob_map(&import
, ident
);
1701 self.record_use(ident
, binding
, false);
1706 fn add_to_glob_map(&mut self, import
: &Import
<'_
>, ident
: Ident
) {
1707 if import
.is_glob() {
1708 let def_id
= self.local_def_id(import
.id
);
1709 self.glob_map
.entry(def_id
).or_default().insert(ident
.name
);
1713 /// A generic scope visitor.
1714 /// Visits scopes in order to resolve some identifier in them or perform other actions.
1715 /// If the callback returns `Some` result, we stop visiting scopes and return it.
1718 scope_set
: ScopeSet
<'a
>,
1719 parent_scope
: &ParentScope
<'a
>,
1720 ctxt
: SyntaxContext
,
1721 mut visitor
: impl FnMut(
1724 /*use_prelude*/ bool
,
1728 // General principles:
1729 // 1. Not controlled (user-defined) names should have higher priority than controlled names
1730 // built into the language or standard library. This way we can add new names into the
1731 // language or standard library without breaking user code.
1732 // 2. "Closed set" below means new names cannot appear after the current resolution attempt.
1733 // Places to search (in order of decreasing priority):
1735 // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet
1736 // (open set, not controlled).
1737 // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
1738 // (open, not controlled).
1739 // 3. Extern prelude (open, the open part is from macro expansions, not controlled).
1740 // 4. Tool modules (closed, controlled right now, but not in the future).
1741 // 5. Standard library prelude (de-facto closed, controlled).
1742 // 6. Language prelude (closed, controlled).
1744 // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet
1745 // (open set, not controlled).
1746 // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
1747 // (open, not controlled).
1748 // 3. Standard library prelude (de-facto closed, controlled).
1750 // 1-3. Derive helpers (open, not controlled). All ambiguities with other names
1751 // are currently reported as errors. They should be higher in priority than preludes
1752 // and probably even names in modules according to the "general principles" above. They
1753 // also should be subject to restricted shadowing because are effectively produced by
1754 // derives (you need to resolve the derive first to add helpers into scope), but they
1755 // should be available before the derive is expanded for compatibility.
1756 // It's mess in general, so we are being conservative for now.
1757 // 1-3. `macro_rules` (open, not controlled), loop through `macro_rules` scopes. Have higher
1758 // priority than prelude macros, but create ambiguities with macros in modules.
1759 // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
1760 // (open, not controlled). Have higher priority than prelude macros, but create
1761 // ambiguities with `macro_rules`.
1762 // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
1763 // 4a. User-defined prelude from macro-use
1764 // (open, the open part is from macro expansions, not controlled).
1765 // 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).
1766 // 4c. Standard library prelude (de-facto closed, controlled).
1767 // 6. Language prelude: builtin attributes (closed, controlled).
1769 let rust_2015
= ctxt
.edition() == Edition
::Edition2015
;
1770 let (ns
, macro_kind
, is_absolute_path
) = match scope_set
{
1771 ScopeSet
::All(ns
, _
) => (ns
, None
, false),
1772 ScopeSet
::AbsolutePath(ns
) => (ns
, None
, true),
1773 ScopeSet
::Macro(macro_kind
) => (MacroNS
, Some(macro_kind
), false),
1774 ScopeSet
::Late(ns
, ..) => (ns
, None
, false),
1776 let module
= match scope_set
{
1777 // Start with the specified module.
1778 ScopeSet
::Late(_
, module
, _
) => module
,
1779 // Jump out of trait or enum modules, they do not act as scopes.
1780 _
=> parent_scope
.module
.nearest_item_scope(),
1782 let mut scope
= match ns
{
1783 _
if is_absolute_path
=> Scope
::CrateRoot
,
1784 TypeNS
| ValueNS
=> Scope
::Module(module
, None
),
1785 MacroNS
=> Scope
::DeriveHelpers(parent_scope
.expansion
),
1787 let mut ctxt
= ctxt
.normalize_to_macros_2_0();
1788 let mut use_prelude
= !module
.no_implicit_prelude
;
1791 let visit
= match scope
{
1792 // Derive helpers are not in scope when resolving derives in the same container.
1793 Scope
::DeriveHelpers(expn_id
) => {
1794 !(expn_id
== parent_scope
.expansion
&& macro_kind
== Some(MacroKind
::Derive
))
1796 Scope
::DeriveHelpersCompat
=> true,
1797 Scope
::MacroRules(macro_rules_scope
) => {
1798 // Use "path compression" on `macro_rules` scope chains. This is an optimization
1799 // used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.
1800 // As another consequence of this optimization visitors never observe invocation
1801 // scopes for macros that were already expanded.
1802 while let MacroRulesScope
::Invocation(invoc_id
) = macro_rules_scope
.get() {
1803 if let Some(next_scope
) = self.output_macro_rules_scopes
.get(&invoc_id
) {
1804 macro_rules_scope
.set(next_scope
.get());
1811 Scope
::CrateRoot
=> true,
1812 Scope
::Module(..) => true,
1813 Scope
::RegisteredAttrs
=> use_prelude
,
1814 Scope
::MacroUsePrelude
=> use_prelude
|| rust_2015
,
1815 Scope
::BuiltinAttrs
=> true,
1816 Scope
::ExternPrelude
=> use_prelude
|| is_absolute_path
,
1817 Scope
::ToolPrelude
=> use_prelude
,
1818 Scope
::StdLibPrelude
=> use_prelude
|| ns
== MacroNS
,
1819 Scope
::BuiltinTypes
=> true,
1823 if let break_result @
Some(..) = visitor(self, scope
, use_prelude
, ctxt
) {
1824 return break_result
;
1828 scope
= match scope
{
1829 Scope
::DeriveHelpers(LocalExpnId
::ROOT
) => Scope
::DeriveHelpersCompat
,
1830 Scope
::DeriveHelpers(expn_id
) => {
1831 // Derive helpers are not visible to code generated by bang or derive macros.
1832 let expn_data
= expn_id
.expn_data();
1833 match expn_data
.kind
{
1835 | ExpnKind
::Macro(MacroKind
::Bang
| MacroKind
::Derive
, _
) => {
1836 Scope
::DeriveHelpersCompat
1838 _
=> Scope
::DeriveHelpers(expn_data
.parent
.expect_local()),
1841 Scope
::DeriveHelpersCompat
=> Scope
::MacroRules(parent_scope
.macro_rules
),
1842 Scope
::MacroRules(macro_rules_scope
) => match macro_rules_scope
.get() {
1843 MacroRulesScope
::Binding(binding
) => {
1844 Scope
::MacroRules(binding
.parent_macro_rules_scope
)
1846 MacroRulesScope
::Invocation(invoc_id
) => {
1847 Scope
::MacroRules(self.invocation_parent_scopes
[&invoc_id
].macro_rules
)
1849 MacroRulesScope
::Empty
=> Scope
::Module(module
, None
),
1851 Scope
::CrateRoot
=> match ns
{
1853 ctxt
.adjust(ExpnId
::root());
1854 Scope
::ExternPrelude
1856 ValueNS
| MacroNS
=> break,
1858 Scope
::Module(module
, prev_lint_id
) => {
1859 use_prelude
= !module
.no_implicit_prelude
;
1860 let derive_fallback_lint_id
= match scope_set
{
1861 ScopeSet
::Late(.., lint_id
) => lint_id
,
1864 match self.hygienic_lexical_parent(module
, &mut ctxt
, derive_fallback_lint_id
) {
1865 Some((parent_module
, lint_id
)) => {
1866 Scope
::Module(parent_module
, lint_id
.or(prev_lint_id
))
1869 ctxt
.adjust(ExpnId
::root());
1871 TypeNS
=> Scope
::ExternPrelude
,
1872 ValueNS
=> Scope
::StdLibPrelude
,
1873 MacroNS
=> Scope
::RegisteredAttrs
,
1878 Scope
::RegisteredAttrs
=> Scope
::MacroUsePrelude
,
1879 Scope
::MacroUsePrelude
=> Scope
::StdLibPrelude
,
1880 Scope
::BuiltinAttrs
=> break, // nowhere else to search
1881 Scope
::ExternPrelude
if is_absolute_path
=> break,
1882 Scope
::ExternPrelude
=> Scope
::ToolPrelude
,
1883 Scope
::ToolPrelude
=> Scope
::StdLibPrelude
,
1884 Scope
::StdLibPrelude
=> match ns
{
1885 TypeNS
=> Scope
::BuiltinTypes
,
1886 ValueNS
=> break, // nowhere else to search
1887 MacroNS
=> Scope
::BuiltinAttrs
,
1889 Scope
::BuiltinTypes
=> break, // nowhere else to search
1896 /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
1897 /// More specifically, we proceed up the hierarchy of scopes and return the binding for
1898 /// `ident` in the first scope that defines it (or None if no scopes define it).
1900 /// A block's items are above its local variables in the scope hierarchy, regardless of where
1901 /// the items are defined in the block. For example,
1904 /// g(); // Since there are no local variables in scope yet, this resolves to the item.
1907 /// g(); // This resolves to the local variable `g` since it shadows the item.
1911 /// Invariant: This must only be called during main resolution, not during
1912 /// import resolution.
1913 fn resolve_ident_in_lexical_scope(
1917 parent_scope
: &ParentScope
<'a
>,
1918 record_used_id
: Option
<NodeId
>,
1921 ) -> Option
<LexicalScopeBinding
<'a
>> {
1922 assert
!(ns
== TypeNS
|| ns
== ValueNS
);
1923 let orig_ident
= ident
;
1924 if ident
.name
== kw
::Empty
{
1925 return Some(LexicalScopeBinding
::Res(Res
::Err
));
1927 let (general_span
, normalized_span
) = if ident
.name
== kw
::SelfUpper
{
1928 // FIXME(jseyfried) improve `Self` hygiene
1929 let empty_span
= ident
.span
.with_ctxt(SyntaxContext
::root());
1930 (empty_span
, empty_span
)
1931 } else if ns
== TypeNS
{
1932 let normalized_span
= ident
.span
.normalize_to_macros_2_0();
1933 (normalized_span
, normalized_span
)
1935 (ident
.span
.normalize_to_macro_rules(), ident
.span
.normalize_to_macros_2_0())
1937 ident
.span
= general_span
;
1938 let normalized_ident
= Ident { span: normalized_span, ..ident }
;
1940 // Walk backwards up the ribs in scope.
1941 let record_used
= record_used_id
.is_some();
1942 let mut module
= self.graph_root
;
1943 for i
in (0..ribs
.len()).rev() {
1944 debug
!("walk rib\n{:?}", ribs
[i
].bindings
);
1945 // Use the rib kind to determine whether we are resolving parameters
1946 // (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
1947 let rib_ident
= if ribs
[i
].kind
.contains_params() { normalized_ident }
else { ident }
;
1948 if let Some((original_rib_ident_def
, res
)) = ribs
[i
].bindings
.get_key_value(&rib_ident
)
1950 // The ident resolves to a type parameter or local variable.
1951 return Some(LexicalScopeBinding
::Res(self.validate_res_from_ribs(
1957 *original_rib_ident_def
,
1962 module
= match ribs
[i
].kind
{
1963 ModuleRibKind(module
) => module
,
1964 MacroDefinition(def
) if def
== self.macro_def(ident
.span
.ctxt()) => {
1965 // If an invocation of this macro created `ident`, give up on `ident`
1966 // and switch to `ident`'s source from the macro definition.
1967 ident
.span
.remove_mark();
1974 ModuleKind
::Block(..) => {}
// We can see through blocks
1978 let item
= self.resolve_ident_in_module_unadjusted(
1979 ModuleOrUniformRoot
::Module(module
),
1986 if let Ok(binding
) = item
{
1987 // The ident resolves to an item.
1988 return Some(LexicalScopeBinding
::Item(binding
));
1991 self.early_resolve_ident_in_lexical_scope(
1993 ScopeSet
::Late(ns
, module
, record_used_id
),
2000 .map(LexicalScopeBinding
::Item
)
2003 fn hygienic_lexical_parent(
2006 ctxt
: &mut SyntaxContext
,
2007 derive_fallback_lint_id
: Option
<NodeId
>,
2008 ) -> Option
<(Module
<'a
>, Option
<NodeId
>)> {
2009 if !module
.expansion
.outer_expn_is_descendant_of(*ctxt
) {
2010 return Some((self.macro_def_scope(ctxt
.remove_mark()), None
));
2013 if let ModuleKind
::Block(..) = module
.kind
{
2014 return Some((module
.parent
.unwrap().nearest_item_scope(), None
));
2017 // We need to support the next case under a deprecation warning
2020 // ---- begin: this comes from a proc macro derive
2021 // mod implementation_details {
2022 // // Note that `MyStruct` is not in scope here.
2023 // impl SomeTrait for MyStruct { ... }
2027 // So we have to fall back to the module's parent during lexical resolution in this case.
2028 if derive_fallback_lint_id
.is_some() {
2029 if let Some(parent
) = module
.parent
{
2030 // Inner module is inside the macro, parent module is outside of the macro.
2031 if module
.expansion
!= parent
.expansion
2032 && module
.expansion
.is_descendant_of(parent
.expansion
)
2034 // The macro is a proc macro derive
2035 if let Some(def_id
) = module
.expansion
.expn_data().macro_def_id
{
2036 let ext
= self.get_macro_by_def_id(def_id
);
2037 if ext
.builtin_name
.is_none()
2038 && ext
.macro_kind() == MacroKind
::Derive
2039 && parent
.expansion
.outer_expn_is_descendant_of(*ctxt
)
2041 return Some((parent
, derive_fallback_lint_id
));
2051 fn resolve_ident_in_module(
2053 module
: ModuleOrUniformRoot
<'a
>,
2056 parent_scope
: &ParentScope
<'a
>,
2059 ) -> Result
<&'a NameBinding
<'a
>, Determinacy
> {
2060 self.resolve_ident_in_module_ext(module
, ident
, ns
, parent_scope
, record_used
, path_span
)
2061 .map_err(|(determinacy
, _
)| determinacy
)
2064 fn resolve_ident_in_module_ext(
2066 module
: ModuleOrUniformRoot
<'a
>,
2069 parent_scope
: &ParentScope
<'a
>,
2072 ) -> Result
<&'a NameBinding
<'a
>, (Determinacy
, Weak
)> {
2073 let tmp_parent_scope
;
2074 let mut adjusted_parent_scope
= parent_scope
;
2076 ModuleOrUniformRoot
::Module(m
) => {
2077 if let Some(def
) = ident
.span
.normalize_to_macros_2_0_and_adjust(m
.expansion
) {
2079 ParentScope { module: self.macro_def_scope(def), ..*parent_scope }
;
2080 adjusted_parent_scope
= &tmp_parent_scope
;
2083 ModuleOrUniformRoot
::ExternPrelude
=> {
2084 ident
.span
.normalize_to_macros_2_0_and_adjust(ExpnId
::root());
2086 ModuleOrUniformRoot
::CrateRootAndExternPrelude
| ModuleOrUniformRoot
::CurrentScope
=> {
2090 self.resolve_ident_in_module_unadjusted_ext(
2094 adjusted_parent_scope
,
2101 fn resolve_crate_root(&mut self, ident
: Ident
) -> Module
<'a
> {
2102 debug
!("resolve_crate_root({:?})", ident
);
2103 let mut ctxt
= ident
.span
.ctxt();
2104 let mark
= if ident
.name
== kw
::DollarCrate
{
2105 // When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
2106 // we don't want to pretend that the `macro_rules!` definition is in the `macro`
2107 // as described in `SyntaxContext::apply_mark`, so we ignore prepended opaque marks.
2108 // FIXME: This is only a guess and it doesn't work correctly for `macro_rules!`
2109 // definitions actually produced by `macro` and `macro` definitions produced by
2110 // `macro_rules!`, but at least such configurations are not stable yet.
2111 ctxt
= ctxt
.normalize_to_macro_rules();
2113 "resolve_crate_root: marks={:?}",
2114 ctxt
.marks().into_iter().map(|(i
, t
)| (i
.expn_data(), t
)).collect
::<Vec
<_
>>()
2116 let mut iter
= ctxt
.marks().into_iter().rev().peekable();
2117 let mut result
= None
;
2118 // Find the last opaque mark from the end if it exists.
2119 while let Some(&(mark
, transparency
)) = iter
.peek() {
2120 if transparency
== Transparency
::Opaque
{
2121 result
= Some(mark
);
2128 "resolve_crate_root: found opaque mark {:?} {:?}",
2130 result
.map(|r
| r
.expn_data())
2132 // Then find the last semi-transparent mark from the end if it exists.
2133 for (mark
, transparency
) in iter
{
2134 if transparency
== Transparency
::SemiTransparent
{
2135 result
= Some(mark
);
2141 "resolve_crate_root: found semi-transparent mark {:?} {:?}",
2143 result
.map(|r
| r
.expn_data())
2147 debug
!("resolve_crate_root: not DollarCrate");
2148 ctxt
= ctxt
.normalize_to_macros_2_0();
2149 ctxt
.adjust(ExpnId
::root())
2151 let module
= match mark
{
2152 Some(def
) => self.macro_def_scope(def
),
2155 "resolve_crate_root({:?}): found no mark (ident.span = {:?})",
2158 return self.graph_root
;
2161 let module
= self.get_module(DefId { index: CRATE_DEF_INDEX, ..module.nearest_parent_mod }
);
2163 "resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})",
2172 fn resolve_self(&mut self, ctxt
: &mut SyntaxContext
, module
: Module
<'a
>) -> Module
<'a
> {
2173 let mut module
= self.get_module(module
.nearest_parent_mod
);
2174 while module
.span
.ctxt().normalize_to_macros_2_0() != *ctxt
{
2175 let parent
= module
.parent
.unwrap_or_else(|| self.macro_def_scope(ctxt
.remove_mark()));
2176 module
= self.get_module(parent
.nearest_parent_mod
);
2184 opt_ns
: Option
<Namespace
>, // `None` indicates a module path in import
2185 parent_scope
: &ParentScope
<'a
>,
2188 crate_lint
: CrateLint
,
2189 ) -> PathResult
<'a
> {
2190 self.resolve_path_with_ribs(
2201 fn resolve_path_with_ribs(
2204 opt_ns
: Option
<Namespace
>, // `None` indicates a module path in import
2205 parent_scope
: &ParentScope
<'a
>,
2208 crate_lint
: CrateLint
,
2209 ribs
: Option
<&PerNS
<Vec
<Rib
<'a
>>>>,
2210 ) -> PathResult
<'a
> {
2211 let mut module
= None
;
2212 let mut allow_super
= true;
2213 let mut second_binding
= None
;
2216 "resolve_path(path={:?}, opt_ns={:?}, record_used={:?}, \
2217 path_span={:?}, crate_lint={:?})",
2218 path
, opt_ns
, record_used
, path_span
, crate_lint
,
2221 for (i
, &Segment { ident, id, has_generic_args: _ }
) in path
.iter().enumerate() {
2222 debug
!("resolve_path ident {} {:?} {:?}", i
, ident
, id
);
2223 let record_segment_res
= |this
: &mut Self, res
| {
2225 if let Some(id
) = id
{
2226 if !this
.partial_res_map
.contains_key(&id
) {
2227 assert
!(id
!= ast
::DUMMY_NODE_ID
, "Trying to resolve dummy id");
2228 this
.record_partial_res(id
, PartialRes
::new(res
));
2234 let is_last
= i
== path
.len() - 1;
2235 let ns
= if is_last { opt_ns.unwrap_or(TypeNS) }
else { TypeNS }
;
2236 let name
= ident
.name
;
2238 allow_super
&= ns
== TypeNS
&& (name
== kw
::SelfLower
|| name
== kw
::Super
);
2241 if allow_super
&& name
== kw
::Super
{
2242 let mut ctxt
= ident
.span
.ctxt().normalize_to_macros_2_0();
2243 let self_module
= match i
{
2244 0 => Some(self.resolve_self(&mut ctxt
, parent_scope
.module
)),
2246 Some(ModuleOrUniformRoot
::Module(module
)) => Some(module
),
2250 if let Some(self_module
) = self_module
{
2251 if let Some(parent
) = self_module
.parent
{
2252 module
= Some(ModuleOrUniformRoot
::Module(
2253 self.resolve_self(&mut ctxt
, parent
),
2258 let msg
= "there are too many leading `super` keywords".to_string();
2259 return PathResult
::Failed
{
2263 is_error_from_last_segment
: false,
2267 if name
== kw
::SelfLower
{
2268 let mut ctxt
= ident
.span
.ctxt().normalize_to_macros_2_0();
2269 module
= Some(ModuleOrUniformRoot
::Module(
2270 self.resolve_self(&mut ctxt
, parent_scope
.module
),
2274 if name
== kw
::PathRoot
&& ident
.span
.rust_2018() {
2275 module
= Some(ModuleOrUniformRoot
::ExternPrelude
);
2278 if name
== kw
::PathRoot
&& ident
.span
.rust_2015() && self.session
.rust_2018() {
2279 // `::a::b` from 2015 macro on 2018 global edition
2280 module
= Some(ModuleOrUniformRoot
::CrateRootAndExternPrelude
);
2283 if name
== kw
::PathRoot
|| name
== kw
::Crate
|| name
== kw
::DollarCrate
{
2284 // `::a::b`, `crate::a::b` or `$crate::a::b`
2285 module
= Some(ModuleOrUniformRoot
::Module(self.resolve_crate_root(ident
)));
2291 // Report special messages for path segment keywords in wrong positions.
2292 if ident
.is_path_segment_keyword() && i
!= 0 {
2293 let name_str
= if name
== kw
::PathRoot
{
2294 "crate root".to_string()
2296 format
!("`{}`", name
)
2298 let label
= if i
== 1 && path
[0].ident
.name
== kw
::PathRoot
{
2299 format
!("global paths cannot start with {}", name_str
)
2301 format
!("{} in paths can only be used in start position", name_str
)
2303 return PathResult
::Failed
{
2307 is_error_from_last_segment
: false,
2311 enum FindBindingResult
<'a
> {
2312 Binding(Result
<&'a NameBinding
<'a
>, Determinacy
>),
2313 PathResult(PathResult
<'a
>),
2315 let find_binding_in_ns
= |this
: &mut Self, ns
| {
2316 let binding
= if let Some(module
) = module
{
2317 this
.resolve_ident_in_module(
2325 } else if ribs
.is_none() || opt_ns
.is_none() || opt_ns
== Some(MacroNS
) {
2326 let scopes
= ScopeSet
::All(ns
, opt_ns
.is_none());
2327 this
.early_resolve_ident_in_lexical_scope(
2336 let record_used_id
= if record_used
{
2337 crate_lint
.node_id().or(Some(CRATE_NODE_ID
))
2341 match this
.resolve_ident_in_lexical_scope(
2349 // we found a locally-imported or available item/module
2350 Some(LexicalScopeBinding
::Item(binding
)) => Ok(binding
),
2351 // we found a local variable or type param
2352 Some(LexicalScopeBinding
::Res(res
))
2353 if opt_ns
== Some(TypeNS
) || opt_ns
== Some(ValueNS
) =>
2355 record_segment_res(this
, res
);
2356 return FindBindingResult
::PathResult(PathResult
::NonModule(
2357 PartialRes
::with_unresolved_segments(res
, path
.len() - 1),
2360 _
=> Err(Determinacy
::determined(record_used
)),
2363 FindBindingResult
::Binding(binding
)
2365 let binding
= match find_binding_in_ns(self, ns
) {
2366 FindBindingResult
::PathResult(x
) => return x
,
2367 FindBindingResult
::Binding(binding
) => binding
,
2372 second_binding
= Some(binding
);
2374 let res
= binding
.res();
2375 let maybe_assoc
= opt_ns
!= Some(MacroNS
) && PathSource
::Type
.is_expected(res
);
2376 if let Some(next_module
) = binding
.module() {
2377 module
= Some(ModuleOrUniformRoot
::Module(next_module
));
2378 record_segment_res(self, res
);
2379 } else if res
== Res
::ToolMod
&& i
+ 1 != path
.len() {
2380 if binding
.is_import() {
2384 "cannot use a tool module through an import",
2386 .span_note(binding
.span
, "the tool module imported here")
2389 let res
= Res
::NonMacroAttr(NonMacroAttrKind
::Tool
);
2390 return PathResult
::NonModule(PartialRes
::new(res
));
2391 } else if res
== Res
::Err
{
2392 return PathResult
::NonModule(PartialRes
::new(Res
::Err
));
2393 } else if opt_ns
.is_some() && (is_last
|| maybe_assoc
) {
2394 self.lint_if_path_starts_with_module(
2400 return PathResult
::NonModule(PartialRes
::with_unresolved_segments(
2405 let label
= format
!(
2406 "`{}` is {} {}, not a module",
2412 return PathResult
::Failed
{
2416 is_error_from_last_segment
: is_last
,
2420 Err(Undetermined
) => return PathResult
::Indeterminate
,
2421 Err(Determined
) => {
2422 if let Some(ModuleOrUniformRoot
::Module(module
)) = module
{
2423 if opt_ns
.is_some() && !module
.is_normal() {
2424 return PathResult
::NonModule(PartialRes
::with_unresolved_segments(
2425 module
.res().unwrap(),
2430 let module_res
= match module
{
2431 Some(ModuleOrUniformRoot
::Module(module
)) => module
.res(),
2434 let (label
, suggestion
) = if module_res
== self.graph_root
.res() {
2435 let is_mod
= |res
| matches
!(res
, Res
::Def(DefKind
::Mod
, _
));
2436 // Don't look up import candidates if this is a speculative resolve
2437 let mut candidates
= if record_used
{
2438 self.lookup_import_candidates(ident
, TypeNS
, parent_scope
, is_mod
)
2442 candidates
.sort_by_cached_key(|c
| {
2443 (c
.path
.segments
.len(), pprust
::path_to_string(&c
.path
))
2445 if let Some(candidate
) = candidates
.get(0) {
2447 String
::from("unresolved import"),
2449 vec
![(ident
.span
, pprust
::path_to_string(&candidate
.path
))],
2450 String
::from("a similar path exists"),
2451 Applicability
::MaybeIncorrect
,
2454 } else if self.session
.edition() == Edition
::Edition2015
{
2455 (format
!("maybe a missing crate `{}`?", ident
), None
)
2457 (format
!("could not find `{}` in the crate root", ident
), None
)
2465 .map_or(false, |c
| c
.is_ascii_uppercase())
2467 // Check whether the name refers to an item in the value namespace.
2468 let suggestion
= if ribs
.is_some() {
2469 let match_span
= match self.resolve_ident_in_lexical_scope(
2475 &ribs
.unwrap()[ValueNS
],
2477 // Name matches a local variable. For example:
2480 // let Foo: &str = "";
2481 // println!("{}", Foo::Bar); // Name refers to local
2482 // // variable `Foo`.
2485 Some(LexicalScopeBinding
::Res(Res
::Local(id
))) => {
2486 Some(*self.pat_span_map
.get(&id
).unwrap())
2489 // Name matches item from a local name binding
2490 // created by `use` declaration. For example:
2492 // pub Foo: &str = "";
2496 // println!("{}", Foo::Bar); // Name refers to local
2497 // // binding `Foo`.
2500 Some(LexicalScopeBinding
::Item(name_binding
)) => {
2501 Some(name_binding
.span
)
2506 if let Some(span
) = match_span
{
2508 vec
![(span
, String
::from(""))],
2509 format
!("`{}` is defined here, but is not a type", ident
),
2510 Applicability
::MaybeIncorrect
,
2519 (format
!("use of undeclared type `{}`", ident
), suggestion
)
2521 (format
!("use of undeclared crate or module `{}`", ident
), None
)
2524 let parent
= path
[i
- 1].ident
.name
;
2525 let parent
= match parent
{
2526 // ::foo is mounted at the crate root for 2015, and is the extern
2527 // prelude for 2018+
2528 kw
::PathRoot
if self.session
.edition() > Edition
::Edition2015
=> {
2529 "the list of imported crates".to_owned()
2531 kw
::PathRoot
| kw
::Crate
=> "the crate root".to_owned(),
2533 format
!("`{}`", parent
)
2537 let mut msg
= format
!("could not find `{}` in {}", ident
, parent
);
2538 if ns
== TypeNS
|| ns
== ValueNS
{
2539 let ns_to_try
= if ns
== TypeNS { ValueNS }
else { TypeNS }
;
2540 if let FindBindingResult
::Binding(Ok(binding
)) =
2541 find_binding_in_ns(self, ns_to_try
)
2543 let mut found
= |what
| {
2545 "expected {}, found {} `{}` in {}",
2552 if binding
.module().is_some() {
2555 match binding
.res() {
2556 def
::Res
::<NodeId
>::Def(kind
, id
) => found(kind
.descr(id
)),
2557 _
=> found(ns_to_try
.descr()),
2564 return PathResult
::Failed
{
2568 is_error_from_last_segment
: is_last
,
2574 self.lint_if_path_starts_with_module(crate_lint
, path
, path_span
, second_binding
);
2576 PathResult
::Module(match module
{
2577 Some(module
) => module
,
2578 None
if path
.is_empty() => ModuleOrUniformRoot
::CurrentScope
,
2579 _
=> span_bug
!(path_span
, "resolve_path: non-empty path `{:?}` has no module", path
),
2583 fn lint_if_path_starts_with_module(
2585 crate_lint
: CrateLint
,
2588 second_binding
: Option
<&NameBinding
<'_
>>,
2590 let (diag_id
, diag_span
) = match crate_lint
{
2591 CrateLint
::No
=> return,
2592 CrateLint
::SimplePath(id
) => (id
, path_span
),
2593 CrateLint
::UsePath { root_id, root_span }
=> (root_id
, root_span
),
2594 CrateLint
::QPathTrait { qpath_id, qpath_span }
=> (qpath_id
, qpath_span
),
2597 let first_name
= match path
.get(0) {
2598 // In the 2018 edition this lint is a hard error, so nothing to do
2599 Some(seg
) if seg
.ident
.span
.rust_2015() && self.session
.rust_2015() => seg
.ident
.name
,
2603 // We're only interested in `use` paths which should start with
2604 // `{{root}}` currently.
2605 if first_name
!= kw
::PathRoot
{
2610 // If this import looks like `crate::...` it's already good
2611 Some(Segment { ident, .. }
) if ident
.name
== kw
::Crate
=> return,
2612 // Otherwise go below to see if it's an extern crate
2614 // If the path has length one (and it's `PathRoot` most likely)
2615 // then we don't know whether we're gonna be importing a crate or an
2616 // item in our crate. Defer this lint to elsewhere
2620 // If the first element of our path was actually resolved to an
2621 // `ExternCrate` (also used for `crate::...`) then no need to issue a
2622 // warning, this looks all good!
2623 if let Some(binding
) = second_binding
{
2624 if let NameBindingKind
::Import { import, .. }
= binding
.kind
{
2625 // Careful: we still want to rewrite paths from renamed extern crates.
2626 if let ImportKind
::ExternCrate { source: None, .. }
= import
.kind
{
2632 let diag
= BuiltinLintDiagnostics
::AbsPathWithModule(diag_span
);
2633 self.lint_buffer
.buffer_lint_with_diagnostic(
2634 lint
::builtin
::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE
,
2637 "absolute paths must start with `self`, `super`, \
2638 `crate`, or an external crate name in the 2018 edition",
2643 // Validate a local resolution (from ribs).
2644 fn validate_res_from_ribs(
2651 original_rib_ident_def
: Ident
,
2652 all_ribs
: &[Rib
<'a
>],
2654 const CG_BUG_STR
: &str = "min_const_generics resolve check didn't stop compilation";
2655 debug
!("validate_res_from_ribs({:?})", res
);
2656 let ribs
= &all_ribs
[rib_index
+ 1..];
2658 // An invalid forward use of a generic parameter from a previous default.
2659 if let ForwardGenericParamBanRibKind
= all_ribs
[rib_index
].kind
{
2661 let res_error
= if rib_ident
.name
== kw
::SelfUpper
{
2662 ResolutionError
::SelfInGenericParamDefault
2664 ResolutionError
::ForwardDeclaredGenericParam
2666 self.report_error(span
, res_error
);
2668 assert_eq
!(res
, Res
::Err
);
2674 use ResolutionError
::*;
2675 let mut res_err
= None
;
2680 | ClosureOrAsyncRibKind
2682 | MacroDefinition(..)
2683 | ForwardGenericParamBanRibKind
=> {
2684 // Nothing to do. Continue.
2686 ItemRibKind(_
) | FnItemRibKind
| AssocItemRibKind
=> {
2687 // This was an attempt to access an upvar inside a
2688 // named function item. This is not allowed, so we
2691 // We don't immediately trigger a resolve error, because
2692 // we want certain other resolution errors (namely those
2693 // emitted for `ConstantItemRibKind` below) to take
2695 res_err
= Some(CannotCaptureDynamicEnvironmentInFnItem
);
2698 ConstantItemRibKind(_
, item
) => {
2699 // Still doesn't deal with upvars
2701 let (span
, resolution_error
) =
2702 if let Some((ident
, constant_item_kind
)) = item
{
2703 let kind_str
= match constant_item_kind
{
2704 ConstantItemKind
::Const
=> "const",
2705 ConstantItemKind
::Static
=> "static",
2709 AttemptToUseNonConstantValueInConstant(
2710 ident
, "let", kind_str
,
2716 AttemptToUseNonConstantValueInConstant(
2717 original_rib_ident_def
,
2723 self.report_error(span
, resolution_error
);
2727 ConstParamTyRibKind
=> {
2729 self.report_error(span
, ParamInTyOfConstParam(rib_ident
.name
));
2735 if let Some(res_err
) = res_err
{
2736 self.report_error(span
, res_err
);
2740 Res
::Def(DefKind
::TyParam
, _
) | Res
::SelfTy(..) => {
2742 let has_generic_params
: HasGenericParams
= match rib
.kind
{
2744 | ClosureOrAsyncRibKind
2747 | MacroDefinition(..)
2748 | ForwardGenericParamBanRibKind
=> {
2749 // Nothing to do. Continue.
2753 ConstantItemRibKind(trivial
, _
) => {
2754 let features
= self.session
.features_untracked();
2755 // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
2756 if !(trivial
|| features
.generic_const_exprs
) {
2757 // HACK(min_const_generics): If we encounter `Self` in an anonymous constant
2758 // we can't easily tell if it's generic at this stage, so we instead remember
2759 // this and then enforce the self type to be concrete later on.
2760 if let Res
::SelfTy(trait_def
, Some((impl_def
, _
))) = res
{
2761 res
= Res
::SelfTy(trait_def
, Some((impl_def
, true)));
2766 ResolutionError
::ParamInNonTrivialAnonConst
{
2767 name
: rib_ident
.name
,
2773 self.session
.delay_span_bug(span
, CG_BUG_STR
);
2781 // This was an attempt to use a type parameter outside its scope.
2782 ItemRibKind(has_generic_params
) => has_generic_params
,
2783 FnItemRibKind
=> HasGenericParams
::Yes
,
2784 ConstParamTyRibKind
=> {
2788 ResolutionError
::ParamInTyOfConstParam(rib_ident
.name
),
2798 ResolutionError
::GenericParamsFromOuterFunction(
2807 Res
::Def(DefKind
::ConstParam
, _
) => {
2808 let mut ribs
= ribs
.iter().peekable();
2809 if let Some(Rib { kind: FnItemRibKind, .. }
) = ribs
.peek() {
2810 // When declaring const parameters inside function signatures, the first rib
2811 // is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
2812 // (spuriously) conflicting with the const param.
2817 let has_generic_params
= match rib
.kind
{
2819 | ClosureOrAsyncRibKind
2822 | MacroDefinition(..)
2823 | ForwardGenericParamBanRibKind
=> continue,
2825 ConstantItemRibKind(trivial
, _
) => {
2826 let features
= self.session
.features_untracked();
2827 // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
2828 if !(trivial
|| features
.generic_const_exprs
) {
2832 ResolutionError
::ParamInNonTrivialAnonConst
{
2833 name
: rib_ident
.name
,
2839 self.session
.delay_span_bug(span
, CG_BUG_STR
);
2846 ItemRibKind(has_generic_params
) => has_generic_params
,
2847 FnItemRibKind
=> HasGenericParams
::Yes
,
2848 ConstParamTyRibKind
=> {
2852 ResolutionError
::ParamInTyOfConstParam(rib_ident
.name
),
2859 // This was an attempt to use a const parameter outside its scope.
2863 ResolutionError
::GenericParamsFromOuterFunction(
2877 fn record_partial_res(&mut self, node_id
: NodeId
, resolution
: PartialRes
) {
2878 debug
!("(recording res) recording {:?} for {}", resolution
, node_id
);
2879 if let Some(prev_res
) = self.partial_res_map
.insert(node_id
, resolution
) {
2880 panic
!("path resolved multiple times ({:?} before, {:?} now)", prev_res
, resolution
);
2884 fn record_pat_span(&mut self, node
: NodeId
, span
: Span
) {
2885 debug
!("(recording pat) recording {:?} for {:?}", node
, span
);
2886 self.pat_span_map
.insert(node
, span
);
2889 fn is_accessible_from(&self, vis
: ty
::Visibility
, module
: Module
<'a
>) -> bool
{
2890 vis
.is_accessible_from(module
.nearest_parent_mod
, self)
2893 fn set_binding_parent_module(&mut self, binding
: &'a NameBinding
<'a
>, module
: Module
<'a
>) {
2894 if let Some(old_module
) = self.binding_parent_modules
.insert(PtrKey(binding
), module
) {
2895 if !ptr
::eq(module
, old_module
) {
2896 span_bug
!(binding
.span
, "parent module is reset for binding");
2901 fn disambiguate_macro_rules_vs_modularized(
2903 macro_rules
: &'a NameBinding
<'a
>,
2904 modularized
: &'a NameBinding
<'a
>,
2906 // Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules"
2907 // is disambiguated to mitigate regressions from macro modularization.
2908 // Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
2910 self.binding_parent_modules
.get(&PtrKey(macro_rules
)),
2911 self.binding_parent_modules
.get(&PtrKey(modularized
)),
2913 (Some(macro_rules
), Some(modularized
)) => {
2914 macro_rules
.nearest_parent_mod
== modularized
.nearest_parent_mod
2915 && modularized
.is_ancestor_of(macro_rules
)
2921 fn report_errors(&mut self, krate
: &Crate
) {
2922 self.report_with_use_injections(krate
);
2924 for &(span_use
, span_def
) in &self.macro_expanded_macro_export_errors
{
2925 let msg
= "macro-expanded `macro_export` macros from the current crate \
2926 cannot be referred to by absolute paths";
2927 self.lint_buffer
.buffer_lint_with_diagnostic(
2928 lint
::builtin
::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS
,
2932 BuiltinLintDiagnostics
::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def
),
2936 for ambiguity_error
in &self.ambiguity_errors
{
2937 self.report_ambiguity_error(ambiguity_error
);
2940 let mut reported_spans
= FxHashSet
::default();
2941 for error
in &self.privacy_errors
{
2942 if reported_spans
.insert(error
.dedup_span
) {
2943 self.report_privacy_error(error
);
2948 fn report_with_use_injections(&mut self, krate
: &Crate
) {
2949 for UseError { mut err, candidates, def_id, instead, suggestion }
in
2950 self.use_injections
.drain(..)
2952 let (span
, found_use
) = if let Some(def_id
) = def_id
.as_local() {
2953 UsePlacementFinder
::check(krate
, self.def_id_to_node_id
[def_id
])
2957 if !candidates
.is_empty() {
2958 diagnostics
::show_candidates(&mut err
, span
, &candidates
, instead
, found_use
);
2959 } else if let Some((span
, msg
, sugg
, appl
)) = suggestion
{
2960 err
.span_suggestion(span
, msg
, sugg
, appl
);
2966 fn report_conflict
<'b
>(
2971 new_binding
: &NameBinding
<'b
>,
2972 old_binding
: &NameBinding
<'b
>,
2974 // Error on the second of two conflicting names
2975 if old_binding
.span
.lo() > new_binding
.span
.lo() {
2976 return self.report_conflict(parent
, ident
, ns
, old_binding
, new_binding
);
2979 let container
= match parent
.kind
{
2980 ModuleKind
::Def(kind
, _
, _
) => kind
.descr(parent
.def_id().unwrap()),
2981 ModuleKind
::Block(..) => "block",
2984 let old_noun
= match old_binding
.is_import() {
2986 false => "definition",
2989 let new_participle
= match new_binding
.is_import() {
2995 (ident
.name
, self.session
.source_map().guess_head_span(new_binding
.span
));
2997 if let Some(s
) = self.name_already_seen
.get(&name
) {
3003 let old_kind
= match (ns
, old_binding
.module()) {
3004 (ValueNS
, _
) => "value",
3005 (MacroNS
, _
) => "macro",
3006 (TypeNS
, _
) if old_binding
.is_extern_crate() => "extern crate",
3007 (TypeNS
, Some(module
)) if module
.is_normal() => "module",
3008 (TypeNS
, Some(module
)) if module
.is_trait() => "trait",
3009 (TypeNS
, _
) => "type",
3012 let msg
= format
!("the name `{}` is defined multiple times", name
);
3014 let mut err
= match (old_binding
.is_extern_crate(), new_binding
.is_extern_crate()) {
3015 (true, true) => struct_span_err
!(self.session
, span
, E0259
, "{}", msg
),
3016 (true, _
) | (_
, true) => match new_binding
.is_import() && old_binding
.is_import() {
3017 true => struct_span_err
!(self.session
, span
, E0254
, "{}", msg
),
3018 false => struct_span_err
!(self.session
, span
, E0260
, "{}", msg
),
3020 _
=> match (old_binding
.is_import(), new_binding
.is_import()) {
3021 (false, false) => struct_span_err
!(self.session
, span
, E0428
, "{}", msg
),
3022 (true, true) => struct_span_err
!(self.session
, span
, E0252
, "{}", msg
),
3023 _
=> struct_span_err
!(self.session
, span
, E0255
, "{}", msg
),
3028 "`{}` must be defined only once in the {} namespace of this {}",
3034 err
.span_label(span
, format
!("`{}` re{} here", name
, new_participle
));
3036 self.session
.source_map().guess_head_span(old_binding
.span
),
3037 format
!("previous {} of the {} `{}` here", old_noun
, old_kind
, name
),
3040 // See https://github.com/rust-lang/rust/issues/32354
3041 use NameBindingKind
::Import
;
3042 let import
= match (&new_binding
.kind
, &old_binding
.kind
) {
3043 // If there are two imports where one or both have attributes then prefer removing the
3044 // import without attributes.
3045 (Import { import: new, .. }
, Import { import: old, .. }
)
3047 !new_binding
.span
.is_dummy()
3048 && !old_binding
.span
.is_dummy()
3049 && (new
.has_attributes
|| old
.has_attributes
)
3052 if old
.has_attributes
{
3053 Some((new
, new_binding
.span
, true))
3055 Some((old
, old_binding
.span
, true))
3058 // Otherwise prioritize the new binding.
3059 (Import { import, .. }
, other
) if !new_binding
.span
.is_dummy() => {
3060 Some((import
, new_binding
.span
, other
.is_import()))
3062 (other
, Import { import, .. }
) if !old_binding
.span
.is_dummy() => {
3063 Some((import
, old_binding
.span
, other
.is_import()))
3068 // Check if the target of the use for both bindings is the same.
3069 let duplicate
= new_binding
.res().opt_def_id() == old_binding
.res().opt_def_id();
3070 let has_dummy_span
= new_binding
.span
.is_dummy() || old_binding
.span
.is_dummy();
3072 self.extern_prelude
.get(&ident
).map_or(true, |entry
| entry
.introduced_by_item
);
3073 // Only suggest removing an import if both bindings are to the same def, if both spans
3074 // aren't dummy spans. Further, if both bindings are imports, then the ident must have
3075 // been introduced by an item.
3076 let should_remove_import
= duplicate
3078 && ((new_binding
.is_extern_crate() || old_binding
.is_extern_crate()) || from_item
);
3081 Some((import
, span
, true)) if should_remove_import
&& import
.is_nested() => {
3082 self.add_suggestion_for_duplicate_nested_use(&mut err
, import
, span
)
3084 Some((import
, _
, true)) if should_remove_import
&& !import
.is_glob() => {
3085 // Simple case - remove the entire import. Due to the above match arm, this can
3086 // only be a single use so just remove it entirely.
3087 err
.tool_only_span_suggestion(
3088 import
.use_span_with_attributes
,
3089 "remove unnecessary import",
3091 Applicability
::MaybeIncorrect
,
3094 Some((import
, span
, _
)) => {
3095 self.add_suggestion_for_rename_of_use(&mut err
, name
, import
, span
)
3101 self.name_already_seen
.insert(name
, span
);
3104 /// This function adds a suggestion to change the binding name of a new import that conflicts
3105 /// with an existing import.
3107 /// ```text,ignore (diagnostic)
3108 /// help: you can use `as` to change the binding name of the import
3110 /// LL | use foo::bar as other_bar;
3111 /// | ^^^^^^^^^^^^^^^^^^^^^
3113 fn add_suggestion_for_rename_of_use(
3115 err
: &mut DiagnosticBuilder
<'_
>,
3117 import
: &Import
<'_
>,
3120 let suggested_name
= if name
.as_str().chars().next().unwrap().is_uppercase() {
3121 format
!("Other{}", name
)
3123 format
!("other_{}", name
)
3126 let mut suggestion
= None
;
3128 ImportKind
::Single { type_ns_only: true, .. }
=> {
3129 suggestion
= Some(format
!("self as {}", suggested_name
))
3131 ImportKind
::Single { source, .. }
=> {
3133 source
.span
.hi().0.checked_sub(binding_span
.lo().0).map(|pos
| pos
as usize)
3135 if let Ok(snippet
) = self.session
.source_map().span_to_snippet(binding_span
) {
3136 if pos
<= snippet
.len() {
3137 suggestion
= Some(format
!(
3141 if snippet
.ends_with('
;'
) { ";" }
else { "" }
3147 ImportKind
::ExternCrate { source, target, .. }
=> {
3148 suggestion
= Some(format
!(
3149 "extern crate {} as {};",
3150 source
.unwrap_or(target
.name
),
3154 _
=> unreachable
!(),
3157 let rename_msg
= "you can use `as` to change the binding name of the import";
3158 if let Some(suggestion
) = suggestion
{
3159 err
.span_suggestion(
3163 Applicability
::MaybeIncorrect
,
3166 err
.span_label(binding_span
, rename_msg
);
3170 /// This function adds a suggestion to remove an unnecessary binding from an import that is
3171 /// nested. In the following example, this function will be invoked to remove the `a` binding
3172 /// in the second use statement:
3174 /// ```ignore (diagnostic)
3175 /// use issue_52891::a;
3176 /// use issue_52891::{d, a, e};
3179 /// The following suggestion will be added:
3181 /// ```ignore (diagnostic)
3182 /// use issue_52891::{d, a, e};
3183 /// ^-- help: remove unnecessary import
3186 /// If the nested use contains only one import then the suggestion will remove the entire
3189 /// It is expected that the provided import is nested - this isn't checked by the
3190 /// function. If this invariant is not upheld, this function's behaviour will be unexpected
3191 /// as characters expected by span manipulations won't be present.
3192 fn add_suggestion_for_duplicate_nested_use(
3194 err
: &mut DiagnosticBuilder
<'_
>,
3195 import
: &Import
<'_
>,
3198 assert
!(import
.is_nested());
3199 let message
= "remove unnecessary import";
3201 // Two examples will be used to illustrate the span manipulations we're doing:
3203 // - Given `use issue_52891::{d, a, e};` where `a` is a duplicate then `binding_span` is
3204 // `a` and `import.use_span` is `issue_52891::{d, a, e};`.
3205 // - Given `use issue_52891::{d, e, a};` where `a` is a duplicate then `binding_span` is
3206 // `a` and `import.use_span` is `issue_52891::{d, e, a};`.
3208 let (found_closing_brace
, span
) =
3209 find_span_of_binding_until_next_binding(self.session
, binding_span
, import
.use_span
);
3211 // If there was a closing brace then identify the span to remove any trailing commas from
3212 // previous imports.
3213 if found_closing_brace
{
3214 if let Some(span
) = extend_span_to_previous_binding(self.session
, span
) {
3215 err
.tool_only_span_suggestion(
3219 Applicability
::MaybeIncorrect
,
3222 // Remove the entire line if we cannot extend the span back, this indicates an
3223 // `issue_52891::{self}` case.
3224 err
.span_suggestion(
3225 import
.use_span_with_attributes
,
3228 Applicability
::MaybeIncorrect
,
3235 err
.span_suggestion(span
, message
, String
::new(), Applicability
::MachineApplicable
);
3238 fn extern_prelude_get(
3242 ) -> Option
<&'a NameBinding
<'a
>> {
3243 if ident
.is_path_segment_keyword() {
3244 // Make sure `self`, `super` etc produce an error when passed to here.
3247 self.extern_prelude
.get(&ident
.normalize_to_macros_2_0()).cloned().and_then(|entry
| {
3248 if let Some(binding
) = entry
.extern_crate_item
{
3249 if !speculative
&& entry
.introduced_by_item
{
3250 self.record_use(ident
, binding
, false);
3254 let crate_id
= if !speculative
{
3255 self.crate_loader
.process_path_extern(ident
.name
, ident
.span
)
3257 self.crate_loader
.maybe_process_path_extern(ident
.name
)?
3259 let crate_root
= self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }
);
3261 (crate_root
, ty
::Visibility
::Public
, DUMMY_SP
, LocalExpnId
::ROOT
)
3262 .to_name_binding(self.arenas
),
3268 /// Rustdoc uses this to resolve things in a recoverable way. `ResolutionError<'a>`
3269 /// isn't something that can be returned because it can't be made to live that long,
3270 /// and also it's a private type. Fortunately rustdoc doesn't need to know the error,
3271 /// just that an error occurred.
3272 // FIXME(Manishearth): intra-doc links won't get warned of epoch changes.
3273 pub fn resolve_str_path_error(
3279 ) -> Result
<(ast
::Path
, Res
), ()> {
3280 let path
= if path_str
.starts_with("::") {
3283 segments
: iter
::once(Ident
::with_dummy_span(kw
::PathRoot
))
3284 .chain(path_str
.split("::").skip(1).map(Ident
::from_str
))
3285 .map(|i
| self.new_ast_path_segment(i
))
3294 .map(Ident
::from_str
)
3295 .map(|i
| self.new_ast_path_segment(i
))
3300 let module
= self.get_module(module_id
);
3301 let parent_scope
= &ParentScope
::module(module
, self);
3302 let res
= self.resolve_ast_path(&path
, ns
, parent_scope
).map_err(|_
| ())?
;
3306 // Resolve a path passed from rustdoc or HIR lowering.
3307 fn resolve_ast_path(
3311 parent_scope
: &ParentScope
<'a
>,
3312 ) -> Result
<Res
, (Span
, ResolutionError
<'a
>)> {
3313 match self.resolve_path(
3314 &Segment
::from_path(path
),
3321 PathResult
::Module(ModuleOrUniformRoot
::Module(module
)) => Ok(module
.res().unwrap()),
3322 PathResult
::NonModule(path_res
) if path_res
.unresolved_segments() == 0 => {
3323 Ok(path_res
.base_res())
3325 PathResult
::NonModule(..) => Err((
3327 ResolutionError
::FailedToResolve
{
3328 label
: String
::from("type-relative paths are not supported in this context"),
3332 PathResult
::Module(..) | PathResult
::Indeterminate
=> unreachable
!(),
3333 PathResult
::Failed { span, label, suggestion, .. }
=> {
3334 Err((span
, ResolutionError
::FailedToResolve { label, suggestion }
))
3339 fn new_ast_path_segment(&mut self, ident
: Ident
) -> ast
::PathSegment
{
3340 let mut seg
= ast
::PathSegment
::from_ident(ident
);
3341 seg
.id
= self.next_node_id();
3346 pub fn graph_root(&self) -> Module
<'a
> {
3351 pub fn all_macros(&self) -> &FxHashMap
<Symbol
, Res
> {
3355 /// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
3357 pub fn opt_span(&self, def_id
: DefId
) -> Option
<Span
> {
3358 if let Some(def_id
) = def_id
.as_local() { Some(self.def_id_to_span[def_id]) }
else { None }
3361 /// Checks if an expression refers to a function marked with
3362 /// `#[rustc_legacy_const_generics]` and returns the argument index list
3363 /// from the attribute.
3364 pub fn legacy_const_generic_args(&mut self, expr
: &Expr
) -> Option
<Vec
<usize>> {
3365 if let ExprKind
::Path(None
, path
) = &expr
.kind
{
3366 // Don't perform legacy const generics rewriting if the path already
3367 // has generic arguments.
3368 if path
.segments
.last().unwrap().args
.is_some() {
3372 let partial_res
= self.partial_res_map
.get(&expr
.id
)?
;
3373 if partial_res
.unresolved_segments() != 0 {
3377 if let Res
::Def(def
::DefKind
::Fn
, def_id
) = partial_res
.base_res() {
3378 // We only support cross-crate argument rewriting. Uses
3379 // within the same crate should be updated to use the new
3380 // const generics style.
3381 if def_id
.is_local() {
3385 if let Some(v
) = self.legacy_const_generic_args
.get(&def_id
) {
3389 let parse_attrs
= || {
3390 let attrs
= self.cstore().item_attrs(def_id
, self.session
);
3392 attrs
.iter().find(|a
| a
.has_name(sym
::rustc_legacy_const_generics
))?
;
3393 let mut ret
= vec
![];
3394 for meta
in attr
.meta_item_list()?
{
3395 match meta
.literal()?
.kind
{
3396 LitKind
::Int(a
, _
) => {
3397 ret
.push(a
as usize);
3399 _
=> panic
!("invalid arg index"),
3405 // Cache the lookup to avoid parsing attributes for an iterm
3407 let ret
= parse_attrs();
3408 self.legacy_const_generic_args
.insert(def_id
, ret
.clone());
3415 fn resolve_main(&mut self) {
3416 let module
= self.graph_root
;
3417 let ident
= Ident
::with_dummy_span(sym
::main
);
3418 let parent_scope
= &ParentScope
::module(module
, self);
3420 let name_binding
= match self.resolve_ident_in_module(
3421 ModuleOrUniformRoot
::Module(module
),
3428 Ok(name_binding
) => name_binding
,
3432 let res
= name_binding
.res();
3433 let is_import
= name_binding
.is_import();
3434 let span
= name_binding
.span
;
3435 if let Res
::Def(DefKind
::Fn
, _
) = res
{
3436 self.record_use(ident
, name_binding
, false);
3438 self.main_def
= Some(MainDefinition { res, is_import, span }
);
3442 fn names_to_string(names
: &[Symbol
]) -> String
{
3443 let mut result
= String
::new();
3444 for (i
, name
) in names
.iter().filter(|name
| **name
!= kw
::PathRoot
).enumerate() {
3446 result
.push_str("::");
3448 if Ident
::with_dummy_span(*name
).is_raw_guess() {
3449 result
.push_str("r#");
3451 result
.push_str(&name
.as_str());
3456 fn path_names_to_string(path
: &Path
) -> String
{
3457 names_to_string(&path
.segments
.iter().map(|seg
| seg
.ident
.name
).collect
::<Vec
<_
>>())
3460 /// A somewhat inefficient routine to obtain the name of a module.
3461 fn module_to_string(module
: Module
<'_
>) -> Option
<String
> {
3462 let mut names
= Vec
::new();
3464 fn collect_mod(names
: &mut Vec
<Symbol
>, module
: Module
<'_
>) {
3465 if let ModuleKind
::Def(.., name
) = module
.kind
{
3466 if let Some(parent
) = module
.parent
{
3468 collect_mod(names
, parent
);
3471 names
.push(Symbol
::intern("<opaque>"));
3472 collect_mod(names
, module
.parent
.unwrap());
3475 collect_mod(&mut names
, module
);
3477 if names
.is_empty() {
3481 Some(names_to_string(&names
))
3484 #[derive(Copy, Clone, Debug)]
3486 /// Do not issue the lint.
3489 /// This lint applies to some arbitrary path; e.g., `impl ::foo::Bar`.
3490 /// In this case, we can take the span of that path.
3493 /// This lint comes from a `use` statement. In this case, what we
3494 /// care about really is the *root* `use` statement; e.g., if we
3495 /// have nested things like `use a::{b, c}`, we care about the
3497 UsePath { root_id: NodeId, root_span: Span }
,
3499 /// This is the "trait item" from a fully qualified path. For example,
3500 /// we might be resolving `X::Y::Z` from a path like `<T as X::Y>::Z`.
3501 /// The `path_span` is the span of the to the trait itself (`X::Y`).
3502 QPathTrait { qpath_id: NodeId, qpath_span: Span }
,
3506 fn node_id(&self) -> Option
<NodeId
> {
3508 CrateLint
::No
=> None
,
3509 CrateLint
::SimplePath(id
)
3510 | CrateLint
::UsePath { root_id: id, .. }
3511 | CrateLint
::QPathTrait { qpath_id: id, .. }
=> Some(id
),
3516 pub fn provide(providers
: &mut Providers
) {
3517 late
::lifetimes
::provide(providers
);