]>
Commit | Line | Data |
---|---|---|
e1599b0c XL |
1 | //! This crate is responsible for the part of name resolution that doesn't require type checker. |
2 | //! | |
3 | //! Module structure of the crate is built here. | |
4 | //! Paths in macros, imports, expressions, types, patterns are resolved here. | |
dfeec247 | 5 | //! Label and lifetime names are resolved here as well. |
e1599b0c | 6 | //! |
2b03887a | 7 | //! Type-relative name resolution (methods, fields, associated items) happens in `rustc_hir_analysis`. |
e1599b0c | 8 | |
1b1a35ee | 9 | #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] |
f2b60f7d | 10 | #![feature(assert_matches)] |
5869c6ff | 11 | #![feature(box_patterns)] |
c295e0f8 | 12 | #![feature(drain_filter)] |
04454e1e | 13 | #![feature(if_let_guard)] |
064997fb | 14 | #![feature(iter_intersperse)] |
5e7ed085 | 15 | #![feature(let_chains)] |
c295e0f8 | 16 | #![feature(never_type)] |
dfeec247 | 17 | #![recursion_limit = "256"] |
cdc7bbd5 | 18 | #![allow(rustdoc::private_intra_doc_links)] |
5e7ed085 | 19 | #![allow(rustc::potential_query_instability)] |
7cac9316 | 20 | |
c295e0f8 XL |
21 | #[macro_use] |
22 | extern crate tracing; | |
23 | ||
dfeec247 | 24 | pub use rustc_hir::def::{Namespace, PerNS}; |
94b46f34 | 25 | |
29967ef6 | 26 | use rustc_arena::{DroplessArena, TypedArena}; |
f9f354fc | 27 | use rustc_ast::node_id::NodeMap; |
04454e1e FG |
28 | use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID}; |
29 | use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path}; | |
923072b8 | 30 | use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; |
5099ac24 | 31 | use rustc_data_structures::intern::Interned; |
dfeec247 | 32 | use rustc_data_structures::sync::Lrc; |
04454e1e | 33 | use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed}; |
cdc7bbd5 | 34 | use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; |
dfeec247 | 35 | use rustc_hir::def::Namespace::*; |
923072b8 FG |
36 | use rustc_hir::def::{self, CtorOf, DefKind, LifetimeRes, PartialRes}; |
37 | use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId}; | |
04454e1e | 38 | use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; |
923072b8 | 39 | use rustc_hir::definitions::{DefPathData, Definitions}; |
cdc7bbd5 | 40 | use rustc_hir::TraitCandidate; |
f035d41b | 41 | use rustc_index::vec::IndexVec; |
dfeec247 | 42 | use rustc_metadata::creader::{CStore, CrateLoader}; |
5099ac24 | 43 | use rustc_middle::metadata::ModChild; |
2b03887a | 44 | use rustc_middle::middle::privacy::EffectiveVisibilities; |
04454e1e | 45 | use rustc_middle::span_bug; |
2b03887a FG |
46 | use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools}; |
47 | use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs}; | |
3c0e092e | 48 | use rustc_query_system::ich::StableHashingContext; |
2b03887a | 49 | use rustc_session::cstore::{CrateStore, MetadataLoaderDyn}; |
04454e1e | 50 | use rustc_session::lint::LintBuffer; |
dfeec247 | 51 | use rustc_session::Session; |
04454e1e | 52 | use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; |
3c0e092e | 53 | use rustc_span::source_map::Spanned; |
f9f354fc | 54 | use rustc_span::symbol::{kw, sym, Ident, Symbol}; |
dfeec247 | 55 | use rustc_span::{Span, DUMMY_SP}; |
1a4d82fc | 56 | |
3dfed10e | 57 | use smallvec::{smallvec, SmallVec}; |
1a4d82fc | 58 | use std::cell::{Cell, RefCell}; |
5099ac24 | 59 | use std::collections::BTreeSet; |
f2b60f7d | 60 | use std::{fmt, ptr}; |
85aaf69f | 61 | |
f035d41b | 62 | use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; |
74b04a01 | 63 | use imports::{Import, ImportKind, ImportResolver, NameResolution}; |
064997fb | 64 | use late::{HasGenericParams, PathSource, PatternSource}; |
29967ef6 | 65 | use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; |
c34b1796 | 66 | |
2b03887a | 67 | use crate::effective_visibilities::EffectiveVisibilitiesVisitor; |
5099ac24 | 68 | |
48663c56 XL |
69 | type Res = def::Res<NodeId>; |
70 | ||
dfeec247 XL |
71 | mod build_reduced_graph; |
72 | mod check_unused; | |
60c5eb7d | 73 | mod def_collector; |
54a0048b | 74 | mod diagnostics; |
2b03887a | 75 | mod effective_visibilities; |
487cf647 | 76 | mod errors; |
04454e1e | 77 | mod ident; |
dfeec247 | 78 | mod imports; |
416331ca | 79 | mod late; |
9e0c209e | 80 | mod macros; |
1a4d82fc | 81 | |
13cf67c4 XL |
82 | enum Weak { |
83 | Yes, | |
84 | No, | |
85 | } | |
86 | ||
416331ca XL |
87 | #[derive(Copy, Clone, PartialEq, Debug)] |
88 | pub enum Determinacy { | |
89 | Determined, | |
90 | Undetermined, | |
91 | } | |
92 | ||
93 | impl Determinacy { | |
94 | fn determined(determined: bool) -> Determinacy { | |
95 | if determined { Determinacy::Determined } else { Determinacy::Undetermined } | |
96 | } | |
97 | } | |
98 | ||
99 | /// A specific scope in which a name can be looked up. | |
100 | /// This enum is currently used only for early resolution (imports and macros), | |
101 | /// but not for late resolution yet. | |
102 | #[derive(Clone, Copy)] | |
103 | enum Scope<'a> { | |
136023e0 | 104 | DeriveHelpers(LocalExpnId), |
60c5eb7d | 105 | DeriveHelpersCompat, |
29967ef6 | 106 | MacroRules(MacroRulesScopeRef<'a>), |
416331ca | 107 | CrateRoot, |
cdc7bbd5 XL |
108 | // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` |
109 | // lint if it should be reported. | |
110 | Module(Module<'a>, Option<NodeId>), | |
416331ca XL |
111 | MacroUsePrelude, |
112 | BuiltinAttrs, | |
416331ca XL |
113 | ExternPrelude, |
114 | ToolPrelude, | |
115 | StdLibPrelude, | |
116 | BuiltinTypes, | |
117 | } | |
118 | ||
119 | /// Names from different contexts may want to visit different subsets of all specific scopes | |
120 | /// with different restrictions when looking up the resolution. | |
121 | /// This enum is currently used only for early resolution (imports and macros), | |
122 | /// but not for late resolution yet. | |
cdc7bbd5 XL |
123 | #[derive(Clone, Copy)] |
124 | enum ScopeSet<'a> { | |
416331ca XL |
125 | /// All scopes with the given namespace. |
126 | All(Namespace, /*is_import*/ bool), | |
127 | /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros). | |
13cf67c4 | 128 | AbsolutePath(Namespace), |
416331ca | 129 | /// All scopes with macro namespace and the given macro kind restriction. |
13cf67c4 | 130 | Macro(MacroKind), |
cdc7bbd5 XL |
131 | /// All scopes with the given namespace, used for partially performing late resolution. |
132 | /// The node id enables lints and is used for reporting them. | |
133 | Late(Namespace, Module<'a>, Option<NodeId>), | |
13cf67c4 XL |
134 | } |
135 | ||
416331ca XL |
136 | /// Everything you need to know about a name's location to resolve it. |
137 | /// Serves as a starting point for the scope visitor. | |
138 | /// This struct is currently used only for early resolution (imports and macros), | |
139 | /// but not for late resolution yet. | |
e1599b0c | 140 | #[derive(Clone, Copy, Debug)] |
416331ca | 141 | pub struct ParentScope<'a> { |
04454e1e | 142 | pub module: Module<'a>, |
136023e0 | 143 | expansion: LocalExpnId, |
04454e1e | 144 | pub macro_rules: MacroRulesScopeRef<'a>, |
e1599b0c XL |
145 | derives: &'a [ast::Path], |
146 | } | |
147 | ||
148 | impl<'a> ParentScope<'a> { | |
149 | /// Creates a parent scope with the passed argument used as the module scope component, | |
150 | /// and other scope components set to default empty values. | |
29967ef6 | 151 | pub fn module(module: Module<'a>, resolver: &Resolver<'a>) -> ParentScope<'a> { |
ba9703b0 XL |
152 | ParentScope { |
153 | module, | |
136023e0 | 154 | expansion: LocalExpnId::ROOT, |
29967ef6 | 155 | macro_rules: resolver.arenas.alloc_macro_rules_scope(MacroRulesScope::Empty), |
ba9703b0 XL |
156 | derives: &[], |
157 | } | |
e1599b0c | 158 | } |
7453a54e SL |
159 | } |
160 | ||
6a06907d XL |
161 | #[derive(Copy, Debug, Clone)] |
162 | enum ImplTraitContext { | |
163 | Existential, | |
164 | Universal(LocalDefId), | |
165 | } | |
166 | ||
8bb4bdeb | 167 | struct BindingError { |
f9f354fc | 168 | name: Symbol, |
8bb4bdeb XL |
169 | origin: BTreeSet<Span>, |
170 | target: BTreeSet<Span>, | |
dfeec247 | 171 | could_be_path: bool, |
0731742a XL |
172 | } |
173 | ||
54a0048b | 174 | enum ResolutionError<'a> { |
9fa01778 | 175 | /// Error E0401: can't use type or const parameters from outer function. |
e74abb32 | 176 | GenericParamsFromOuterFunction(Res, HasGenericParams), |
9fa01778 XL |
177 | /// Error E0403: the name is already used for a type or const parameter in this generic |
178 | /// parameter list. | |
f9f354fc | 179 | NameAlreadyUsedInParameterList(Symbol, Span), |
9fa01778 | 180 | /// Error E0407: method is not a member of trait. |
04454e1e | 181 | MethodNotMemberOfTrait(Ident, String, Option<Symbol>), |
9fa01778 | 182 | /// Error E0437: type is not a member of trait. |
04454e1e | 183 | TypeNotMemberOfTrait(Ident, String, Option<Symbol>), |
9fa01778 | 184 | /// Error E0438: const is not a member of trait. |
04454e1e | 185 | ConstNotMemberOfTrait(Ident, String, Option<Symbol>), |
9fa01778 | 186 | /// Error E0408: variable `{}` is not bound in all patterns. |
04454e1e | 187 | VariableNotBoundInPattern(BindingError, ParentScope<'a>), |
9fa01778 | 188 | /// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm. |
f9f354fc | 189 | VariableBoundWithDifferentMode(Symbol, Span), |
9fa01778 | 190 | /// Error E0415: identifier is bound more than once in this parameter list. |
3dfed10e | 191 | IdentifierBoundMoreThanOnceInParameterList(Symbol), |
9fa01778 | 192 | /// Error E0416: identifier is bound more than once in the same pattern. |
3dfed10e | 193 | IdentifierBoundMoreThanOnceInSamePattern(Symbol), |
9fa01778 | 194 | /// Error E0426: use of undeclared label. |
3dfed10e | 195 | UndeclaredLabel { name: Symbol, suggestion: Option<LabelSuggestion> }, |
9fa01778 | 196 | /// Error E0429: `self` imports are only allowed within a `{ }` list. |
f9f354fc | 197 | SelfImportsOnlyAllowedWithin { root: bool, span_with_rename: Span }, |
9fa01778 | 198 | /// Error E0430: `self` import can only appear once in the list. |
c1a9b12d | 199 | SelfImportCanOnlyAppearOnceInTheList, |
9fa01778 | 200 | /// Error E0431: `self` import can only appear in an import list with a non-empty prefix. |
c1a9b12d | 201 | SelfImportOnlyInImportListWithNonEmptyPrefix, |
9fa01778 | 202 | /// Error E0433: failed to resolve. |
532ac7d7 | 203 | FailedToResolve { label: String, suggestion: Option<Suggestion> }, |
9fa01778 | 204 | /// Error E0434: can't capture dynamic environment in a fn item. |
c1a9b12d | 205 | CannotCaptureDynamicEnvironmentInFnItem, |
9fa01778 | 206 | /// Error E0435: attempt to use a non-constant value in a constant. |
5869c6ff XL |
207 | AttemptToUseNonConstantValueInConstant( |
208 | Ident, | |
209 | /* suggestion */ &'static str, | |
210 | /* current */ &'static str, | |
211 | ), | |
9fa01778 | 212 | /// Error E0530: `X` bindings cannot shadow `Y`s. |
17df50a5 | 213 | BindingShadowsSomethingUnacceptable { |
064997fb | 214 | shadowing_binding: PatternSource, |
17df50a5 XL |
215 | name: Symbol, |
216 | participle: &'static str, | |
217 | article: &'static str, | |
064997fb | 218 | shadowed_binding: Res, |
17df50a5 XL |
219 | shadowed_binding_span: Span, |
220 | }, | |
cdc7bbd5 | 221 | /// Error E0128: generic parameters with a default cannot use forward-declared identifiers. |
17df50a5 | 222 | ForwardDeclaredGenericParam, |
3dfed10e XL |
223 | /// ERROR E0770: the type of const parameters must not depend on other generic parameters. |
224 | ParamInTyOfConstParam(Symbol), | |
29967ef6 | 225 | /// generic parameters must not be used inside const evaluations. |
3dfed10e XL |
226 | /// |
227 | /// This error is only emitted when using `min_const_generics`. | |
1b1a35ee | 228 | ParamInNonTrivialAnonConst { name: Symbol, is_type: bool }, |
cdc7bbd5 | 229 | /// Error E0735: generic parameters with a default cannot use `Self` |
136023e0 | 230 | SelfInGenericParamDefault, |
f035d41b | 231 | /// Error E0767: use of unreachable label |
3dfed10e | 232 | UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> }, |
5099ac24 FG |
233 | /// Error E0323, E0324, E0325: mismatch between trait item and impl item. |
234 | TraitImplMismatch { | |
235 | name: Symbol, | |
236 | kind: &'static str, | |
237 | trait_path: String, | |
238 | trait_item_span: Span, | |
239 | code: rustc_errors::DiagnosticId, | |
240 | }, | |
2b03887a FG |
241 | /// Error E0201: multiple impl items for the same trait item. |
242 | TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span }, | |
04454e1e FG |
243 | /// Inline asm `sym` operand must refer to a `fn` or `static`. |
244 | InvalidAsmSym, | |
e74abb32 XL |
245 | } |
246 | ||
247 | enum VisResolutionError<'a> { | |
248 | Relative2018(Span, &'a ast::Path), | |
249 | AncestorOnly(Span), | |
250 | FailedToResolve(Span, String, Option<Suggestion>), | |
251 | ExpectedFound(Span, String, Res), | |
252 | Indeterminate(Span), | |
253 | ModuleOnly(Span), | |
9cc50fc6 SL |
254 | } |
255 | ||
f035d41b XL |
256 | /// A minimal representation of a path segment. We use this in resolve because we synthesize 'path |
257 | /// segments' which don't have the rest of an AST or HIR `PathSegment`. | |
13cf67c4 XL |
258 | #[derive(Clone, Copy, Debug)] |
259 | pub struct Segment { | |
260 | ident: Ident, | |
261 | id: Option<NodeId>, | |
f035d41b XL |
262 | /// Signals whether this `PathSegment` has generic arguments. Used to avoid providing |
263 | /// nonsensical suggestions. | |
264 | has_generic_args: bool, | |
04454e1e FG |
265 | /// Signals whether this `PathSegment` has lifetime arguments. |
266 | has_lifetime_args: bool, | |
267 | args_span: Span, | |
13cf67c4 XL |
268 | } |
269 | ||
270 | impl Segment { | |
271 | fn from_path(path: &Path) -> Vec<Segment> { | |
272 | path.segments.iter().map(|s| s.into()).collect() | |
273 | } | |
274 | ||
275 | fn from_ident(ident: Ident) -> Segment { | |
04454e1e FG |
276 | Segment { |
277 | ident, | |
278 | id: None, | |
279 | has_generic_args: false, | |
280 | has_lifetime_args: false, | |
281 | args_span: DUMMY_SP, | |
282 | } | |
283 | } | |
284 | ||
285 | fn from_ident_and_id(ident: Ident, id: NodeId) -> Segment { | |
286 | Segment { | |
287 | ident, | |
288 | id: Some(id), | |
289 | has_generic_args: false, | |
290 | has_lifetime_args: false, | |
291 | args_span: DUMMY_SP, | |
292 | } | |
13cf67c4 XL |
293 | } |
294 | ||
295 | fn names_to_string(segments: &[Segment]) -> String { | |
dfeec247 | 296 | names_to_string(&segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>()) |
13cf67c4 XL |
297 | } |
298 | } | |
299 | ||
300 | impl<'a> From<&'a ast::PathSegment> for Segment { | |
301 | fn from(seg: &'a ast::PathSegment) -> Segment { | |
04454e1e FG |
302 | let has_generic_args = seg.args.is_some(); |
303 | let (args_span, has_lifetime_args) = if let Some(args) = seg.args.as_deref() { | |
304 | match args { | |
305 | GenericArgs::AngleBracketed(args) => { | |
306 | let found_lifetimes = args | |
307 | .args | |
308 | .iter() | |
309 | .any(|arg| matches!(arg, AngleBracketedArg::Arg(GenericArg::Lifetime(_)))); | |
310 | (args.span, found_lifetimes) | |
5e7ed085 | 311 | } |
04454e1e | 312 | GenericArgs::Parenthesized(args) => (args.span, true), |
6a06907d | 313 | } |
5e7ed085 | 314 | } else { |
04454e1e FG |
315 | (DUMMY_SP, false) |
316 | }; | |
317 | Segment { | |
318 | ident: seg.ident, | |
319 | id: Some(seg.id), | |
320 | has_generic_args, | |
321 | has_lifetime_args, | |
322 | args_span, | |
6a06907d | 323 | } |
3b2f2976 XL |
324 | } |
325 | } | |
326 | ||
0531ce1d XL |
327 | /// An intermediate resolution result. |
328 | /// | |
48663c56 XL |
329 | /// This refers to the thing referred by a name. The difference between `Res` and `Item` is that |
330 | /// items are visible in their whole block, while `Res`es only from the place they are defined | |
0531ce1d | 331 | /// forward. |
416331ca | 332 | #[derive(Debug)] |
54a0048b SL |
333 | enum LexicalScopeBinding<'a> { |
334 | Item(&'a NameBinding<'a>), | |
48663c56 | 335 | Res(Res), |
54a0048b SL |
336 | } |
337 | ||
338 | impl<'a> LexicalScopeBinding<'a> { | |
48663c56 | 339 | fn res(self) -> Res { |
32a655c1 | 340 | match self { |
48663c56 XL |
341 | LexicalScopeBinding::Item(binding) => binding.res(), |
342 | LexicalScopeBinding::Res(res) => res, | |
32a655c1 SL |
343 | } |
344 | } | |
476ff2be SL |
345 | } |
346 | ||
b7449926 | 347 | #[derive(Copy, Clone, Debug)] |
13cf67c4 | 348 | enum ModuleOrUniformRoot<'a> { |
b7449926 XL |
349 | /// Regular module. |
350 | Module(Module<'a>), | |
351 | ||
13cf67c4 XL |
352 | /// Virtual module that denotes resolution in crate root with fallback to extern prelude. |
353 | CrateRootAndExternPrelude, | |
354 | ||
355 | /// Virtual module that denotes resolution in extern prelude. | |
0731742a | 356 | /// Used for paths starting with `::` on 2018 edition. |
13cf67c4 XL |
357 | ExternPrelude, |
358 | ||
359 | /// Virtual module that denotes resolution in current scope. | |
360 | /// Used only for resolving single-segment imports. The reason it exists is that import paths | |
361 | /// are always split into two parts, the first of which should be some kind of module. | |
362 | CurrentScope, | |
363 | } | |
364 | ||
69743fb6 XL |
365 | impl ModuleOrUniformRoot<'_> { |
366 | fn same_def(lhs: Self, rhs: Self) -> bool { | |
367 | match (lhs, rhs) { | |
dfeec247 | 368 | (ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) => { |
c295e0f8 | 369 | ptr::eq(lhs, rhs) |
dfeec247 XL |
370 | } |
371 | ( | |
372 | ModuleOrUniformRoot::CrateRootAndExternPrelude, | |
373 | ModuleOrUniformRoot::CrateRootAndExternPrelude, | |
374 | ) | |
375 | | (ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) | |
376 | | (ModuleOrUniformRoot::CurrentScope, ModuleOrUniformRoot::CurrentScope) => true, | |
13cf67c4 XL |
377 | _ => false, |
378 | } | |
379 | } | |
b7449926 XL |
380 | } |
381 | ||
2c00a5a8 | 382 | #[derive(Clone, Debug)] |
476ff2be | 383 | enum PathResult<'a> { |
b7449926 | 384 | Module(ModuleOrUniformRoot<'a>), |
48663c56 | 385 | NonModule(PartialRes), |
476ff2be | 386 | Indeterminate, |
532ac7d7 XL |
387 | Failed { |
388 | span: Span, | |
389 | label: String, | |
390 | suggestion: Option<Suggestion>, | |
391 | is_error_from_last_segment: bool, | |
392 | }, | |
476ff2be SL |
393 | } |
394 | ||
5e7ed085 FG |
395 | impl<'a> PathResult<'a> { |
396 | fn failed( | |
397 | span: Span, | |
398 | is_error_from_last_segment: bool, | |
399 | finalize: bool, | |
400 | label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>), | |
401 | ) -> PathResult<'a> { | |
402 | let (label, suggestion) = | |
403 | if finalize { label_and_suggestion() } else { (String::new(), None) }; | |
404 | PathResult::Failed { span, label, suggestion, is_error_from_last_segment } | |
405 | } | |
406 | } | |
407 | ||
fc512014 | 408 | #[derive(Debug)] |
9e0c209e | 409 | enum ModuleKind { |
9fa01778 | 410 | /// An anonymous module; e.g., just a block. |
0531ce1d XL |
411 | /// |
412 | /// ``` | |
413 | /// fn main() { | |
414 | /// fn f() {} // (1) | |
415 | /// { // This is an anonymous module | |
416 | /// f(); // This resolves to (2) as we are inside the block. | |
417 | /// fn f() {} // (2) | |
418 | /// } | |
419 | /// f(); // Resolves to (1) | |
420 | /// } | |
421 | /// ``` | |
064997fb | 422 | Block, |
0531ce1d XL |
423 | /// Any module with a name. |
424 | /// | |
425 | /// This could be: | |
426 | /// | |
5869c6ff XL |
427 | /// * A normal module – either `mod from_file;` or `mod from_block { }` – |
428 | /// or the crate root (which is conceptually a top-level module). | |
429 | /// Note that the crate root's [name][Self::name] will be [`kw::Empty`]. | |
0531ce1d XL |
430 | /// * A trait or an enum (it implicitly contains associated types, methods and variant |
431 | /// constructors). | |
f9f354fc | 432 | Def(DefKind, DefId, Symbol), |
48663c56 XL |
433 | } |
434 | ||
435 | impl ModuleKind { | |
436 | /// Get name of the module. | |
f9f354fc | 437 | pub fn name(&self) -> Option<Symbol> { |
48663c56 | 438 | match self { |
064997fb | 439 | ModuleKind::Block => None, |
48663c56 XL |
440 | ModuleKind::Def(.., name) => Some(*name), |
441 | } | |
442 | } | |
1a4d82fc JJ |
443 | } |
444 | ||
e74abb32 XL |
445 | /// A key that identifies a binding in a given `Module`. |
446 | /// | |
447 | /// Multiple bindings in the same module can have the same key (in a valid | |
448 | /// program) if all but one of them come from glob imports. | |
3dfed10e | 449 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
e74abb32 | 450 | struct BindingKey { |
5e7ed085 | 451 | /// The identifier for the binding, always the `normalize_to_macros_2_0` version of the |
e74abb32 XL |
452 | /// identifier. |
453 | ident: Ident, | |
454 | ns: Namespace, | |
455 | /// 0 if ident is not `_`, otherwise a value that's unique to the specific | |
456 | /// `_` in the expanded AST that introduced this binding. | |
457 | disambiguator: u32, | |
458 | } | |
459 | ||
460 | type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>; | |
e1599b0c | 461 | |
1a4d82fc | 462 | /// One node in the tree of modules. |
5869c6ff XL |
463 | /// |
464 | /// Note that a "module" in resolve is broader than a `mod` that you declare in Rust code. It may be one of these: | |
465 | /// | |
466 | /// * `mod` | |
467 | /// * crate root (aka, top-level anonymous module) | |
468 | /// * `enum` | |
469 | /// * `trait` | |
470 | /// * curly-braced block with statements | |
471 | /// | |
472 | /// You can use [`ModuleData::kind`] to determine the kind of module this is. | |
32a655c1 | 473 | pub struct ModuleData<'a> { |
5869c6ff | 474 | /// The direct parent module (it may not be a `mod`, however). |
9e0c209e | 475 | parent: Option<Module<'a>>, |
5869c6ff | 476 | /// What kind of module this is, because this may not be a `mod`. |
9e0c209e SL |
477 | kind: ModuleKind, |
478 | ||
5869c6ff XL |
479 | /// Mapping between names and their (possibly in-progress) resolutions in this module. |
480 | /// Resolutions in modules from other crates are not populated until accessed. | |
e1599b0c | 481 | lazy_resolutions: Resolutions<'a>, |
5869c6ff | 482 | /// True if this is a module from other crate that needs to be populated on access. |
e1599b0c | 483 | populate_on_access: Cell<bool>, |
1a4d82fc | 484 | |
5869c6ff | 485 | /// Macro invocations that can expand into items in this module. |
136023e0 | 486 | unexpanded_invocations: RefCell<FxHashSet<LocalExpnId>>, |
1a4d82fc | 487 | |
5869c6ff | 488 | /// Whether `#[no_implicit_prelude]` is active. |
9e0c209e | 489 | no_implicit_prelude: bool, |
1a4d82fc | 490 | |
74b04a01 XL |
491 | glob_importers: RefCell<Vec<&'a Import<'a>>>, |
492 | globs: RefCell<Vec<&'a Import<'a>>>, | |
e9174d1e | 493 | |
5869c6ff | 494 | /// Used to memoize the traits in this module for faster searches through all traits in scope. |
32a655c1 | 495 | traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>, |
e9174d1e | 496 | |
7cac9316 XL |
497 | /// Span of the module itself. Used for error reporting. |
498 | span: Span, | |
499 | ||
416331ca | 500 | expansion: ExpnId, |
1a4d82fc JJ |
501 | } |
502 | ||
3b2f2976 | 503 | type Module<'a> = &'a ModuleData<'a>; |
9cc50fc6 | 504 | |
32a655c1 | 505 | impl<'a> ModuleData<'a> { |
dfeec247 XL |
506 | fn new( |
507 | parent: Option<Module<'a>>, | |
508 | kind: ModuleKind, | |
dfeec247 XL |
509 | expansion: ExpnId, |
510 | span: Span, | |
c295e0f8 | 511 | no_implicit_prelude: bool, |
dfeec247 | 512 | ) -> Self { |
c295e0f8 XL |
513 | let is_foreign = match kind { |
514 | ModuleKind::Def(_, def_id, _) => !def_id.is_local(), | |
064997fb | 515 | ModuleKind::Block => false, |
c295e0f8 | 516 | }; |
32a655c1 | 517 | ModuleData { |
3b2f2976 XL |
518 | parent, |
519 | kind, | |
e1599b0c | 520 | lazy_resolutions: Default::default(), |
c295e0f8 | 521 | populate_on_access: Cell::new(is_foreign), |
e1599b0c | 522 | unexpanded_invocations: Default::default(), |
c295e0f8 | 523 | no_implicit_prelude, |
54a0048b | 524 | glob_importers: RefCell::new(Vec::new()), |
2c00a5a8 | 525 | globs: RefCell::new(Vec::new()), |
54a0048b | 526 | traits: RefCell::new(None), |
3b2f2976 XL |
527 | span, |
528 | expansion, | |
7453a54e SL |
529 | } |
530 | } | |
531 | ||
e1599b0c | 532 | fn for_each_child<R, F>(&'a self, resolver: &mut R, mut f: F) |
dfeec247 XL |
533 | where |
534 | R: AsMut<Resolver<'a>>, | |
535 | F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>), | |
e1599b0c | 536 | { |
e74abb32 | 537 | for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() { |
f9f354fc XL |
538 | if let Some(binding) = name_resolution.borrow().binding { |
539 | f(resolver, key.ident, key.ns, binding); | |
540 | } | |
3b2f2976 XL |
541 | } |
542 | } | |
543 | ||
3dfed10e XL |
544 | /// This modifies `self` in place. The traits will be stored in `self.traits`. |
545 | fn ensure_traits<R>(&'a self, resolver: &mut R) | |
546 | where | |
547 | R: AsMut<Resolver<'a>>, | |
548 | { | |
549 | let mut traits = self.traits.borrow_mut(); | |
550 | if traits.is_none() { | |
551 | let mut collected_traits = Vec::new(); | |
552 | self.for_each_child(resolver, |_, name, ns, binding| { | |
553 | if ns != TypeNS { | |
554 | return; | |
555 | } | |
1b1a35ee XL |
556 | if let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = binding.res() { |
557 | collected_traits.push((name, binding)) | |
3dfed10e XL |
558 | } |
559 | }); | |
560 | *traits = Some(collected_traits.into_boxed_slice()); | |
561 | } | |
562 | } | |
563 | ||
48663c56 | 564 | fn res(&self) -> Option<Res> { |
9e0c209e | 565 | match self.kind { |
48663c56 XL |
566 | ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)), |
567 | _ => None, | |
568 | } | |
569 | } | |
570 | ||
5099ac24 FG |
571 | // Public for rustdoc. |
572 | pub fn def_id(&self) -> DefId { | |
c295e0f8 XL |
573 | self.opt_def_id().expect("`ModuleData::def_id` is called on a block module") |
574 | } | |
575 | ||
576 | fn opt_def_id(&self) -> Option<DefId> { | |
48663c56 XL |
577 | match self.kind { |
578 | ModuleKind::Def(_, def_id, _) => Some(def_id), | |
579 | _ => None, | |
580 | } | |
92a42be0 SL |
581 | } |
582 | ||
a7813a04 | 583 | // `self` resolves to the first module ancestor that `is_normal`. |
7453a54e | 584 | fn is_normal(&self) -> bool { |
29967ef6 | 585 | matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _)) |
1a4d82fc JJ |
586 | } |
587 | ||
7453a54e | 588 | fn is_trait(&self) -> bool { |
29967ef6 | 589 | matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _)) |
e9174d1e | 590 | } |
c30ab7b3 | 591 | |
8bb4bdeb | 592 | fn nearest_item_scope(&'a self) -> Module<'a> { |
e1599b0c | 593 | match self.kind { |
ba9703b0 | 594 | ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => { |
dfeec247 XL |
595 | self.parent.expect("enum or trait module without a parent") |
596 | } | |
e1599b0c XL |
597 | _ => self, |
598 | } | |
8bb4bdeb | 599 | } |
4462d4a0 | 600 | |
c295e0f8 XL |
601 | /// The [`DefId`] of the nearest `mod` item ancestor (which may be this module). |
602 | /// This may be the crate root. | |
603 | fn nearest_parent_mod(&self) -> DefId { | |
604 | match self.kind { | |
605 | ModuleKind::Def(DefKind::Mod, def_id, _) => def_id, | |
606 | _ => self.parent.expect("non-root module without parent").nearest_parent_mod(), | |
607 | } | |
608 | } | |
609 | ||
4462d4a0 XL |
610 | fn is_ancestor_of(&self, mut other: &Self) -> bool { |
611 | while !ptr::eq(self, other) { | |
612 | if let Some(parent) = other.parent { | |
613 | other = parent; | |
614 | } else { | |
615 | return false; | |
616 | } | |
617 | } | |
618 | true | |
619 | } | |
1a4d82fc JJ |
620 | } |
621 | ||
32a655c1 | 622 | impl<'a> fmt::Debug for ModuleData<'a> { |
9fa01778 | 623 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
48663c56 | 624 | write!(f, "{:?}", self.res()) |
1a4d82fc JJ |
625 | } |
626 | } | |
627 | ||
83c7162d | 628 | /// Records a possibly-private value, type, or module definition. |
54a0048b | 629 | #[derive(Clone, Debug)] |
7453a54e | 630 | pub struct NameBinding<'a> { |
7453a54e | 631 | kind: NameBindingKind<'a>, |
0731742a | 632 | ambiguity: Option<(&'a NameBinding<'a>, AmbiguityKind)>, |
136023e0 | 633 | expansion: LocalExpnId, |
a7813a04 | 634 | span: Span, |
f2b60f7d | 635 | vis: ty::Visibility<DefId>, |
1a4d82fc JJ |
636 | } |
637 | ||
5bcae85e | 638 | pub trait ToNameBinding<'a> { |
32a655c1 | 639 | fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a>; |
5bcae85e SL |
640 | } |
641 | ||
32a655c1 SL |
642 | impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> { |
643 | fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { | |
5bcae85e SL |
644 | self |
645 | } | |
646 | } | |
647 | ||
54a0048b | 648 | #[derive(Clone, Debug)] |
7453a54e | 649 | enum NameBindingKind<'a> { |
487cf647 | 650 | Res(Res), |
9cc50fc6 | 651 | Module(Module<'a>), |
74b04a01 | 652 | Import { binding: &'a NameBinding<'a>, import: &'a Import<'a>, used: Cell<bool> }, |
1a4d82fc JJ |
653 | } |
654 | ||
9fa01778 | 655 | impl<'a> NameBindingKind<'a> { |
94222f64 | 656 | /// Is this a name binding of an import? |
9fa01778 | 657 | fn is_import(&self) -> bool { |
29967ef6 | 658 | matches!(*self, NameBindingKind::Import { .. }) |
9fa01778 XL |
659 | } |
660 | } | |
661 | ||
dfeec247 XL |
662 | struct PrivacyError<'a> { |
663 | ident: Ident, | |
664 | binding: &'a NameBinding<'a>, | |
665 | dedup_span: Span, | |
666 | } | |
54a0048b | 667 | |
3b2f2976 | 668 | struct UseError<'a> { |
5e7ed085 | 669 | err: DiagnosticBuilder<'a, ErrorGuaranteed>, |
f035d41b | 670 | /// Candidates which user could `use` to access the missing type. |
3b2f2976 | 671 | candidates: Vec<ImportSuggestion>, |
f035d41b | 672 | /// The `DefId` of the module to place the use-statements in. |
f9f354fc | 673 | def_id: DefId, |
f035d41b XL |
674 | /// Whether the diagnostic should say "instead" (as in `consider importing ... instead`). |
675 | instead: bool, | |
676 | /// Extra free-form suggestion. | |
dfeec247 | 677 | suggestion: Option<(Span, &'static str, String, Applicability)>, |
04454e1e FG |
678 | /// Path `Segment`s at the place of use that failed. Used for accurate suggestion after telling |
679 | /// the user to import the item directly. | |
680 | path: Vec<Segment>, | |
2b03887a FG |
681 | /// Whether the expected source is a call |
682 | is_call: bool, | |
3b2f2976 XL |
683 | } |
684 | ||
13cf67c4 XL |
685 | #[derive(Clone, Copy, PartialEq, Debug)] |
686 | enum AmbiguityKind { | |
687 | Import, | |
13cf67c4 XL |
688 | BuiltinAttr, |
689 | DeriveHelper, | |
ba9703b0 | 690 | MacroRulesVsModularized, |
13cf67c4 XL |
691 | GlobVsOuter, |
692 | GlobVsGlob, | |
693 | GlobVsExpanded, | |
694 | MoreExpandedVsOuter, | |
695 | } | |
696 | ||
697 | impl AmbiguityKind { | |
698 | fn descr(self) -> &'static str { | |
699 | match self { | |
3c0e092e XL |
700 | AmbiguityKind::Import => "multiple potential import sources", |
701 | AmbiguityKind::BuiltinAttr => "a name conflict with a builtin attribute", | |
702 | AmbiguityKind::DeriveHelper => "a name conflict with a derive helper attribute", | |
ba9703b0 | 703 | AmbiguityKind::MacroRulesVsModularized => { |
3c0e092e | 704 | "a conflict between a `macro_rules` name and a non-`macro_rules` name from another module" |
ba9703b0 | 705 | } |
dfeec247 | 706 | AmbiguityKind::GlobVsOuter => { |
3c0e092e | 707 | "a conflict between a name from a glob import and an outer scope during import or macro resolution" |
dfeec247 | 708 | } |
3c0e092e | 709 | AmbiguityKind::GlobVsGlob => "multiple glob imports of a name in the same module", |
dfeec247 | 710 | AmbiguityKind::GlobVsExpanded => { |
3c0e092e | 711 | "a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution" |
dfeec247 XL |
712 | } |
713 | AmbiguityKind::MoreExpandedVsOuter => { | |
3c0e092e | 714 | "a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution" |
dfeec247 | 715 | } |
13cf67c4 XL |
716 | } |
717 | } | |
718 | } | |
719 | ||
720 | /// Miscellaneous bits of metadata for better ambiguity error reporting. | |
721 | #[derive(Clone, Copy, PartialEq)] | |
722 | enum AmbiguityErrorMisc { | |
723 | SuggestCrate, | |
724 | SuggestSelf, | |
725 | FromPrelude, | |
726 | None, | |
727 | } | |
728 | ||
9e0c209e | 729 | struct AmbiguityError<'a> { |
13cf67c4 | 730 | kind: AmbiguityKind, |
b7449926 | 731 | ident: Ident, |
9e0c209e SL |
732 | b1: &'a NameBinding<'a>, |
733 | b2: &'a NameBinding<'a>, | |
13cf67c4 XL |
734 | misc1: AmbiguityErrorMisc, |
735 | misc2: AmbiguityErrorMisc, | |
9e0c209e SL |
736 | } |
737 | ||
7453a54e | 738 | impl<'a> NameBinding<'a> { |
476ff2be | 739 | fn module(&self) -> Option<Module<'a>> { |
7453a54e | 740 | match self.kind { |
476ff2be | 741 | NameBindingKind::Module(module) => Some(module), |
7453a54e | 742 | NameBindingKind::Import { binding, .. } => binding.module(), |
476ff2be | 743 | _ => None, |
1a4d82fc JJ |
744 | } |
745 | } | |
746 | ||
48663c56 | 747 | fn res(&self) -> Res { |
7453a54e | 748 | match self.kind { |
487cf647 | 749 | NameBindingKind::Res(res) => res, |
48663c56 XL |
750 | NameBindingKind::Module(module) => module.res().unwrap(), |
751 | NameBindingKind::Import { binding, .. } => binding.res(), | |
1a4d82fc JJ |
752 | } |
753 | } | |
1a4d82fc | 754 | |
0731742a | 755 | fn is_ambiguity(&self) -> bool { |
dfeec247 XL |
756 | self.ambiguity.is_some() |
757 | || match self.kind { | |
758 | NameBindingKind::Import { binding, .. } => binding.is_ambiguity(), | |
759 | _ => false, | |
760 | } | |
476ff2be SL |
761 | } |
762 | ||
f035d41b XL |
763 | fn is_possibly_imported_variant(&self) -> bool { |
764 | match self.kind { | |
765 | NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(), | |
487cf647 FG |
766 | NameBindingKind::Res(Res::Def( |
767 | DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), | |
ba9703b0 | 768 | _, |
487cf647 | 769 | )) => true, |
6a06907d XL |
770 | NameBindingKind::Res(..) | NameBindingKind::Module(..) => false, |
771 | } | |
92a42be0 SL |
772 | } |
773 | ||
7453a54e | 774 | fn is_extern_crate(&self) -> bool { |
476ff2be SL |
775 | match self.kind { |
776 | NameBindingKind::Import { | |
74b04a01 | 777 | import: &Import { kind: ImportKind::ExternCrate { .. }, .. }, |
dfeec247 | 778 | .. |
476ff2be | 779 | } => true, |
dfeec247 XL |
780 | NameBindingKind::Module(&ModuleData { |
781 | kind: ModuleKind::Def(DefKind::Mod, def_id, _), | |
782 | .. | |
04454e1e | 783 | }) => def_id.is_crate_root(), |
476ff2be SL |
784 | _ => false, |
785 | } | |
92a42be0 | 786 | } |
92a42be0 | 787 | |
7453a54e | 788 | fn is_import(&self) -> bool { |
29967ef6 | 789 | matches!(self.kind, NameBindingKind::Import { .. }) |
c34b1796 | 790 | } |
a7813a04 | 791 | |
487cf647 FG |
792 | /// The binding introduced by `#[macro_export] macro_rules` is a public import, but it might |
793 | /// not be perceived as such by users, so treat it as a non-import in some diagnostics. | |
794 | fn is_import_user_facing(&self) -> bool { | |
795 | matches!(self.kind, NameBindingKind::Import { import, .. } | |
796 | if !matches!(import.kind, ImportKind::MacroExport)) | |
797 | } | |
798 | ||
a7813a04 XL |
799 | fn is_glob_import(&self) -> bool { |
800 | match self.kind { | |
74b04a01 | 801 | NameBindingKind::Import { import, .. } => import.is_glob(), |
a7813a04 XL |
802 | _ => false, |
803 | } | |
804 | } | |
805 | ||
806 | fn is_importable(&self) -> bool { | |
29967ef6 XL |
807 | !matches!( |
808 | self.res(), | |
809 | Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _) | |
810 | ) | |
a7813a04 | 811 | } |
7cac9316 | 812 | |
b7449926 | 813 | fn macro_kind(&self) -> Option<MacroKind> { |
416331ca | 814 | self.res().macro_kind() |
13cf67c4 XL |
815 | } |
816 | ||
b7449926 XL |
817 | // Suppose that we resolved macro invocation with `invoc_parent_expansion` to binding `binding` |
818 | // at some expansion round `max(invoc, binding)` when they both emerged from macros. | |
819 | // Then this function returns `true` if `self` may emerge from a macro *after* that | |
820 | // in some later round and screw up our previously found resolution. | |
821 | // See more detailed explanation in | |
822 | // https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049 | |
136023e0 XL |
823 | fn may_appear_after( |
824 | &self, | |
825 | invoc_parent_expansion: LocalExpnId, | |
826 | binding: &NameBinding<'_>, | |
827 | ) -> bool { | |
b7449926 XL |
828 | // self > max(invoc, binding) => !(self <= invoc || self <= binding) |
829 | // Expansions are partially ordered, so "may appear after" is an inversion of | |
830 | // "certainly appears before or simultaneously" and includes unordered cases. | |
831 | let self_parent_expansion = self.expansion; | |
832 | let other_parent_expansion = binding.expansion; | |
833 | let certainly_before_other_or_simultaneously = | |
834 | other_parent_expansion.is_descendant_of(self_parent_expansion); | |
835 | let certainly_before_invoc_or_simultaneously = | |
836 | invoc_parent_expansion.is_descendant_of(self_parent_expansion); | |
837 | !(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously) | |
838 | } | |
1a4d82fc JJ |
839 | } |
840 | ||
f2b60f7d | 841 | #[derive(Default, Clone)] |
0bf4aa26 XL |
842 | pub struct ExternPreludeEntry<'a> { |
843 | extern_crate_item: Option<&'a NameBinding<'a>>, | |
844 | pub introduced_by_item: bool, | |
845 | } | |
846 | ||
1b1a35ee XL |
847 | /// Used for better errors for E0773 |
848 | enum BuiltinMacroState { | |
5869c6ff | 849 | NotYetSeen(SyntaxExtensionKind), |
1b1a35ee XL |
850 | AlreadySeen(Span), |
851 | } | |
852 | ||
cdc7bbd5 XL |
853 | struct DeriveData { |
854 | resolutions: DeriveResolutions, | |
855 | helper_attrs: Vec<(usize, Ident)>, | |
856 | has_derive_copy: bool, | |
857 | } | |
858 | ||
923072b8 FG |
859 | #[derive(Clone)] |
860 | struct MacroData { | |
861 | ext: Lrc<SyntaxExtension>, | |
862 | macro_rules: bool, | |
863 | } | |
864 | ||
1a4d82fc | 865 | /// The main resolver class. |
0531ce1d XL |
866 | /// |
867 | /// This is the visitor that walks the whole crate. | |
0731742a | 868 | pub struct Resolver<'a> { |
1a4d82fc JJ |
869 | session: &'a Session, |
870 | ||
e74abb32 | 871 | definitions: Definitions, |
923072b8 FG |
872 | /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. |
873 | expn_that_defined: FxHashMap<LocalDefId, ExpnId>, | |
874 | /// Reference span for definitions. | |
875 | source_span: IndexVec<LocalDefId, Span>, | |
1a4d82fc | 876 | |
e74abb32 | 877 | graph_root: Module<'a>, |
1a4d82fc | 878 | |
3157f602 | 879 | prelude: Option<Module<'a>>, |
e74abb32 | 880 | extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>, |
3157f602 | 881 | |
9fa01778 | 882 | /// N.B., this is used only for better diagnostics, not name resolution itself. |
7cac9316 | 883 | has_self: FxHashSet<DefId>, |
1a4d82fc | 884 | |
83c7162d XL |
885 | /// Names of fields of an item `DefId` accessible with dot syntax. |
886 | /// Used for hints during error reporting. | |
f9f354fc | 887 | field_names: FxHashMap<DefId, Vec<Spanned<Symbol>>>, |
1a4d82fc | 888 | |
83c7162d | 889 | /// All imports known to succeed or fail. |
74b04a01 | 890 | determined_imports: Vec<&'a Import<'a>>, |
9e0c209e | 891 | |
83c7162d | 892 | /// All non-determined imports. |
74b04a01 | 893 | indeterminate_imports: Vec<&'a Import<'a>>, |
1a4d82fc | 894 | |
cdc7bbd5 XL |
895 | // Spans for local variables found during pattern resolution. |
896 | // Used for suggestions during error reporting. | |
897 | pat_span_map: NodeMap<Span>, | |
898 | ||
48663c56 XL |
899 | /// Resolutions for nodes that have a single resolution. |
900 | partial_res_map: NodeMap<PartialRes>, | |
901 | /// Resolutions for import nodes, which have multiple resolutions in different namespaces. | |
902 | import_res_map: NodeMap<PerNS<Option<Res>>>, | |
903 | /// Resolutions for labels (node IDs of their corresponding blocks or loops). | |
904 | label_res_map: NodeMap<NodeId>, | |
04454e1e FG |
905 | /// Resolutions for lifetimes. |
906 | lifetimes_res_map: NodeMap<LifetimeRes>, | |
907 | /// Lifetime parameters that lowering will have to introduce. | |
908 | extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>, | |
48663c56 | 909 | |
e74abb32 | 910 | /// `CrateNum` resolutions of `extern crate` items. |
f9f354fc | 911 | extern_crate_map: FxHashMap<LocalDefId, CrateNum>, |
5099ac24 | 912 | reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>, |
3c0e092e | 913 | trait_map: NodeMap<Vec<TraitCandidate>>, |
a7813a04 | 914 | |
83c7162d XL |
915 | /// A map from nodes to anonymous modules. |
916 | /// Anonymous modules are pseudo-modules that are implicitly created around items | |
917 | /// contained within blocks. | |
918 | /// | |
919 | /// For example, if we have this: | |
920 | /// | |
921 | /// fn f() { | |
922 | /// fn g() { | |
923 | /// ... | |
924 | /// } | |
925 | /// } | |
926 | /// | |
927 | /// There will be an anonymous module created around `g` with the ID of the | |
928 | /// entry block for `f`. | |
32a655c1 | 929 | block_map: NodeMap<Module<'a>>, |
e1599b0c XL |
930 | /// A fake module that contains no definition and no prelude. Used so that |
931 | /// some AST passes can generate identifiers that only resolve to local or | |
932 | /// language items. | |
933 | empty_module: Module<'a>, | |
c295e0f8 | 934 | module_map: FxHashMap<DefId, Module<'a>>, |
5099ac24 | 935 | binding_parent_modules: FxHashMap<Interned<'a, NameBinding<'a>>, Module<'a>>, |
e74abb32 | 936 | underscore_disambiguator: u32, |
1a4d82fc | 937 | |
9fa01778 | 938 | /// Maps glob imports to the names of items actually imported. |
f9f354fc | 939 | glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>, |
29967ef6 XL |
940 | /// Visibilities in "lowered" form, for all entities that have them. |
941 | visibilities: FxHashMap<LocalDefId, ty::Visibility>, | |
04454e1e | 942 | has_pub_restricted: bool, |
94222f64 | 943 | used_imports: FxHashSet<NodeId>, |
923072b8 | 944 | maybe_unused_trait_imports: FxIndexSet<LocalDefId>, |
f9f354fc | 945 | maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, |
e9174d1e | 946 | |
9fa01778 | 947 | /// Privacy errors are delayed until the end in order to deduplicate them. |
54a0048b | 948 | privacy_errors: Vec<PrivacyError<'a>>, |
9fa01778 | 949 | /// Ambiguity errors are delayed for deduplication. |
9e0c209e | 950 | ambiguity_errors: Vec<AmbiguityError<'a>>, |
9fa01778 | 951 | /// `use` injections are delayed for better placement and deduplication. |
3b2f2976 | 952 | use_injections: Vec<UseError<'a>>, |
9fa01778 | 953 | /// Crate-local macro expanded `macro_export` referred to by a module-relative path. |
b7449926 | 954 | macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>, |
9cc50fc6 SL |
955 | |
956 | arenas: &'a ResolverArenas<'a>, | |
9e0c209e | 957 | dummy_binding: &'a NameBinding<'a>, |
9e0c209e | 958 | |
e74abb32 | 959 | crate_loader: CrateLoader<'a>, |
7cac9316 | 960 | macro_names: FxHashSet<Ident>, |
1b1a35ee | 961 | builtin_macros: FxHashMap<Symbol, BuiltinMacroState>, |
5e7ed085 FG |
962 | /// A small map keeping true kinds of built-in macros that appear to be fn-like on |
963 | /// the surface (`macro` items in libcore), but are actually attributes or derives. | |
964 | builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>, | |
5099ac24 | 965 | registered_tools: RegisteredTools, |
f9f354fc | 966 | macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>, |
923072b8 | 967 | macro_map: FxHashMap<DefId, MacroData>, |
416331ca XL |
968 | dummy_ext_bang: Lrc<SyntaxExtension>, |
969 | dummy_ext_derive: Lrc<SyntaxExtension>, | |
94222f64 | 970 | non_macro_attr: Lrc<SyntaxExtension>, |
f9f354fc | 971 | local_macro_def_scopes: FxHashMap<LocalDefId, Module<'a>>, |
136023e0 | 972 | ast_transform_scopes: FxHashMap<LocalExpnId, Module<'a>>, |
3c0e092e | 973 | unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>, |
04454e1e | 974 | unused_macro_rules: FxHashMap<(LocalDefId, usize), (Ident, Span)>, |
f9f354fc | 975 | proc_macro_stubs: FxHashSet<LocalDefId>, |
e1599b0c | 976 | /// Traces collected during macro resolution and validated when it's complete. |
dfeec247 XL |
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>)>, | |
e1599b0c | 981 | builtin_attrs: Vec<(Ident, ParentScope<'a>)>, |
60c5eb7d | 982 | /// `derive(Copy)` marks items they are applied to so they are treated specially later. |
416331ca XL |
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. | |
136023e0 | 985 | containers_deriving_copy: FxHashSet<LocalExpnId>, |
e1599b0c XL |
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. | |
136023e0 | 988 | invocation_parent_scopes: FxHashMap<LocalExpnId, ParentScope<'a>>, |
ba9703b0 | 989 | /// `macro_rules` scopes *produced* by expanding the macro invocations, |
e1599b0c | 990 | /// include all the `macro_rules` items and other invocations generated by them. |
136023e0 | 991 | output_macro_rules_scopes: FxHashMap<LocalExpnId, MacroRulesScopeRef<'a>>, |
04454e1e FG |
992 | /// `macro_rules` scopes produced by `macro_rules` item definitions. |
993 | macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'a>>, | |
60c5eb7d | 994 | /// Helper attributes that are in scope for the given expansion. |
136023e0 | 995 | helper_attrs: FxHashMap<LocalExpnId, Vec<Ident>>, |
cdc7bbd5 XL |
996 | /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute |
997 | /// with the given `ExpnId`. | |
136023e0 | 998 | derive_data: FxHashMap<LocalExpnId, DeriveData>, |
476ff2be | 999 | |
83c7162d | 1000 | /// Avoid duplicated errors for "name already defined". |
f9f354fc | 1001 | name_already_seen: FxHashMap<Symbol, Span>, |
32a655c1 | 1002 | |
74b04a01 | 1003 | potentially_unused_imports: Vec<&'a Import<'a>>, |
8bb4bdeb | 1004 | |
9fa01778 | 1005 | /// Table for mapping struct IDs into struct constructor IDs, |
83c7162d | 1006 | /// it's not used during normal resolution, only for better error reporting. |
1b1a35ee | 1007 | /// Also includes of list of each fields visibility |
f2b60f7d | 1008 | struct_constructors: DefIdMap<(Res, ty::Visibility<DefId>, Vec<ty::Visibility<DefId>>)>, |
3b2f2976 | 1009 | |
416331ca | 1010 | /// Features enabled for this crate. |
f9f354fc | 1011 | active_features: FxHashSet<Symbol>, |
e1599b0c | 1012 | |
dfeec247 | 1013 | lint_buffer: LintBuffer, |
60c5eb7d XL |
1014 | |
1015 | next_node_id: NodeId, | |
f035d41b | 1016 | |
f035d41b XL |
1017 | node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>, |
1018 | def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>, | |
1019 | ||
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` | |
6a06907d XL |
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. | |
136023e0 | 1025 | invocation_parents: FxHashMap<LocalExpnId, (LocalDefId, ImplTraitContext)>, |
f035d41b | 1026 | |
29967ef6 XL |
1027 | /// Some way to know that we are in a *trait* impl in `visit_assoc_item`. |
1028 | /// FIXME: Replace with a more general AST map (together with some other fields). | |
1029 | trait_impl_items: FxHashSet<LocalDefId>, | |
6a06907d XL |
1030 | |
1031 | legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>, | |
94222f64 XL |
1032 | /// Amount of lifetime parameters for each item in the crate. |
1033 | item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>, | |
cdc7bbd5 XL |
1034 | |
1035 | main_def: Option<MainDefinition>, | |
5099ac24 | 1036 | trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>, |
94222f64 XL |
1037 | /// A list of proc macro LocalDefIds, written out in the order in which |
1038 | /// they are declared in the static array generated by proc_macro_harness. | |
1039 | proc_macros: Vec<NodeId>, | |
c295e0f8 | 1040 | confused_type_with_std_module: FxHashMap<Span, Span>, |
487cf647 FG |
1041 | /// Whether lifetime elision was successful. |
1042 | lifetime_elision_allowed: FxHashSet<NodeId>, | |
5099ac24 | 1043 | |
2b03887a | 1044 | effective_visibilities: EffectiveVisibilities, |
9cc50fc6 SL |
1045 | } |
1046 | ||
9fa01778 | 1047 | /// Nothing really interesting here; it just provides memory for the rest of the crate. |
0bf4aa26 | 1048 | #[derive(Default)] |
3157f602 | 1049 | pub struct ResolverArenas<'a> { |
f035d41b | 1050 | modules: TypedArena<ModuleData<'a>>, |
a7813a04 | 1051 | local_modules: RefCell<Vec<Module<'a>>>, |
f035d41b XL |
1052 | imports: TypedArena<Import<'a>>, |
1053 | name_resolutions: TypedArena<RefCell<NameResolution<'a>>>, | |
f035d41b | 1054 | ast_paths: TypedArena<ast::Path>, |
29967ef6 | 1055 | dropless: DroplessArena, |
54a0048b SL |
1056 | } |
1057 | ||
1058 | impl<'a> ResolverArenas<'a> { | |
c295e0f8 XL |
1059 | fn new_module( |
1060 | &'a self, | |
1061 | parent: Option<Module<'a>>, | |
1062 | kind: ModuleKind, | |
1063 | expn_id: ExpnId, | |
1064 | span: Span, | |
1065 | no_implicit_prelude: bool, | |
1066 | module_map: &mut FxHashMap<DefId, Module<'a>>, | |
1067 | ) -> Module<'a> { | |
1068 | let module = | |
1069 | self.modules.alloc(ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude)); | |
1070 | let def_id = module.opt_def_id(); | |
1071 | if def_id.map_or(true, |def_id| def_id.is_local()) { | |
a7813a04 XL |
1072 | self.local_modules.borrow_mut().push(module); |
1073 | } | |
c295e0f8 XL |
1074 | if let Some(def_id) = def_id { |
1075 | module_map.insert(def_id, module); | |
1076 | } | |
a7813a04 XL |
1077 | module |
1078 | } | |
9fa01778 | 1079 | fn local_modules(&'a self) -> std::cell::Ref<'a, Vec<Module<'a>>> { |
a7813a04 | 1080 | self.local_modules.borrow() |
54a0048b SL |
1081 | } |
1082 | fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> { | |
29967ef6 | 1083 | self.dropless.alloc(name_binding) |
54a0048b | 1084 | } |
74b04a01 XL |
1085 | fn alloc_import(&'a self, import: Import<'a>) -> &'a Import<'_> { |
1086 | self.imports.alloc(import) | |
54a0048b SL |
1087 | } |
1088 | fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> { | |
1089 | self.name_resolutions.alloc(Default::default()) | |
1090 | } | |
29967ef6 | 1091 | fn alloc_macro_rules_scope(&'a self, scope: MacroRulesScope<'a>) -> MacroRulesScopeRef<'a> { |
5099ac24 | 1092 | Interned::new_unchecked(self.dropless.alloc(Cell::new(scope))) |
29967ef6 | 1093 | } |
ba9703b0 XL |
1094 | fn alloc_macro_rules_binding( |
1095 | &'a self, | |
1096 | binding: MacroRulesBinding<'a>, | |
1097 | ) -> &'a MacroRulesBinding<'a> { | |
29967ef6 | 1098 | self.dropless.alloc(binding) |
c30ab7b3 | 1099 | } |
e1599b0c XL |
1100 | fn alloc_ast_paths(&'a self, paths: &[ast::Path]) -> &'a [ast::Path] { |
1101 | self.ast_paths.alloc_from_iter(paths.iter().cloned()) | |
1102 | } | |
1b1a35ee | 1103 | fn alloc_pattern_spans(&'a self, spans: impl Iterator<Item = Span>) -> &'a [Span] { |
29967ef6 | 1104 | self.dropless.alloc_from_iter(spans) |
1b1a35ee | 1105 | } |
e1599b0c XL |
1106 | } |
1107 | ||
1108 | impl<'a> AsMut<Resolver<'a>> for Resolver<'a> { | |
dfeec247 XL |
1109 | fn as_mut(&mut self) -> &mut Resolver<'a> { |
1110 | self | |
1111 | } | |
1a4d82fc JJ |
1112 | } |
1113 | ||
487cf647 FG |
1114 | /// A minimal subset of resolver that can implemenent `DefIdTree`, sometimes |
1115 | /// required to satisfy borrow checker by avoiding borrowing the whole resolver. | |
1116 | #[derive(Clone, Copy)] | |
1117 | struct ResolverTree<'a, 'b>(&'a Definitions, &'a CrateLoader<'b>); | |
1118 | ||
1119 | impl DefIdTree for ResolverTree<'_, '_> { | |
04454e1e FG |
1120 | #[inline] |
1121 | fn opt_parent(self, id: DefId) -> Option<DefId> { | |
487cf647 | 1122 | let ResolverTree(definitions, crate_loader) = self; |
ba9703b0 | 1123 | match id.as_local() { |
487cf647 FG |
1124 | Some(id) => definitions.def_key(id).parent, |
1125 | None => crate_loader.cstore().def_key(id).parent, | |
dfeec247 XL |
1126 | } |
1127 | .map(|index| DefId { index, ..id }) | |
a7813a04 | 1128 | } |
1a4d82fc JJ |
1129 | } |
1130 | ||
487cf647 FG |
1131 | impl<'a, 'b> DefIdTree for &'a Resolver<'b> { |
1132 | #[inline] | |
1133 | fn opt_parent(self, id: DefId) -> Option<DefId> { | |
1134 | ResolverTree(&self.definitions, &self.crate_loader).opt_parent(id) | |
1135 | } | |
1136 | } | |
1137 | ||
923072b8 | 1138 | impl Resolver<'_> { |
f035d41b XL |
1139 | fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> { |
1140 | self.node_id_to_def_id.get(&node).copied() | |
1141 | } | |
1142 | ||
923072b8 | 1143 | pub fn local_def_id(&self, node: NodeId) -> LocalDefId { |
f035d41b XL |
1144 | self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node)) |
1145 | } | |
1146 | ||
1147 | /// Adds a definition with a parent definition. | |
1148 | fn create_def( | |
1149 | &mut self, | |
1150 | parent: LocalDefId, | |
1151 | node_id: ast::NodeId, | |
1152 | data: DefPathData, | |
1153 | expn_id: ExpnId, | |
1154 | span: Span, | |
1155 | ) -> LocalDefId { | |
1156 | assert!( | |
1157 | !self.node_id_to_def_id.contains_key(&node_id), | |
1158 | "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}", | |
1159 | node_id, | |
1160 | data, | |
1161 | self.definitions.def_key(self.node_id_to_def_id[&node_id]), | |
1162 | ); | |
1163 | ||
923072b8 FG |
1164 | let def_id = self.definitions.create_def(parent, data); |
1165 | ||
1166 | // Create the definition. | |
1167 | if expn_id != ExpnId::root() { | |
1168 | self.expn_that_defined.insert(def_id, expn_id); | |
1169 | } | |
1170 | ||
1171 | // A relative span's parent must be an absolute span. | |
1172 | debug_assert_eq!(span.data_untracked().parent, None); | |
1173 | let _id = self.source_span.push(span); | |
1174 | debug_assert_eq!(_id, def_id); | |
f035d41b XL |
1175 | |
1176 | // Some things for which we allocate `LocalDefId`s don't correspond to | |
1177 | // anything in the AST, so they don't have a `NodeId`. For these cases | |
1178 | // we don't need a mapping from `NodeId` to `LocalDefId`. | |
1179 | if node_id != ast::DUMMY_NODE_ID { | |
1180 | debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); | |
1181 | self.node_id_to_def_id.insert(node_id, def_id); | |
1182 | } | |
1183 | assert_eq!(self.def_id_to_node_id.push(node_id), def_id); | |
1184 | ||
1185 | def_id | |
1186 | } | |
5e7ed085 | 1187 | |
923072b8 FG |
1188 | fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize { |
1189 | if let Some(def_id) = def_id.as_local() { | |
1190 | self.item_generics_num_lifetimes[&def_id] | |
1191 | } else { | |
1192 | self.cstore().item_generics_num_lifetimes(def_id, self.session) | |
1193 | } | |
5e7ed085 | 1194 | } |
a7813a04 XL |
1195 | } |
1196 | ||
0731742a | 1197 | impl<'a> Resolver<'a> { |
dfeec247 XL |
1198 | pub fn new( |
1199 | session: &'a Session, | |
1200 | krate: &Crate, | |
487cf647 | 1201 | crate_name: Symbol, |
17df50a5 | 1202 | metadata_loader: Box<MetadataLoaderDyn>, |
dfeec247 XL |
1203 | arenas: &'a ResolverArenas<'a>, |
1204 | ) -> Resolver<'a> { | |
c295e0f8 | 1205 | let root_def_id = CRATE_DEF_ID.to_def_id(); |
0bf4aa26 | 1206 | let mut module_map = FxHashMap::default(); |
c295e0f8 XL |
1207 | let graph_root = arenas.new_module( |
1208 | None, | |
1209 | ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty), | |
1210 | ExpnId::root(), | |
5e7ed085 | 1211 | krate.spans.inner_span, |
c295e0f8 XL |
1212 | session.contains_name(&krate.attrs, sym::no_implicit_prelude), |
1213 | &mut module_map, | |
1214 | ); | |
1215 | let empty_module = arenas.new_module( | |
1216 | None, | |
1217 | ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty), | |
1218 | ExpnId::root(), | |
1219 | DUMMY_SP, | |
1220 | true, | |
1221 | &mut FxHashMap::default(), | |
1222 | ); | |
1a4d82fc | 1223 | |
923072b8 | 1224 | let definitions = Definitions::new(session.local_stable_crate_id()); |
f035d41b | 1225 | |
29967ef6 | 1226 | let mut visibilities = FxHashMap::default(); |
c295e0f8 | 1227 | visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public); |
29967ef6 | 1228 | |
f035d41b | 1229 | let mut def_id_to_node_id = IndexVec::default(); |
04454e1e | 1230 | assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID); |
f035d41b | 1231 | let mut node_id_to_def_id = FxHashMap::default(); |
04454e1e | 1232 | node_id_to_def_id.insert(CRATE_NODE_ID, CRATE_DEF_ID); |
f035d41b XL |
1233 | |
1234 | let mut invocation_parents = FxHashMap::default(); | |
04454e1e | 1235 | invocation_parents.insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential)); |
c30ab7b3 | 1236 | |
923072b8 FG |
1237 | let mut source_span = IndexVec::default(); |
1238 | let _id = source_span.push(krate.spans.inner_span); | |
1239 | debug_assert_eq!(_id, CRATE_DEF_ID); | |
1240 | ||
dfeec247 XL |
1241 | let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> = session |
1242 | .opts | |
1243 | .externs | |
1244 | .iter() | |
1245 | .filter(|(_, entry)| entry.add_prelude) | |
1246 | .map(|(name, _)| (Ident::from_str(name), Default::default())) | |
1247 | .collect(); | |
b7449926 | 1248 | |
3dfed10e | 1249 | if !session.contains_name(&krate.attrs, sym::no_core) { |
e1599b0c | 1250 | extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default()); |
3dfed10e | 1251 | if !session.contains_name(&krate.attrs, sym::no_std) { |
e1599b0c | 1252 | extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default()); |
4462d4a0 XL |
1253 | } |
1254 | } | |
94b46f34 | 1255 | |
f2b60f7d | 1256 | let registered_tools = macros::registered_tools(session, &krate.attrs); |
60c5eb7d | 1257 | |
416331ca | 1258 | let features = session.features_untracked(); |
dc9dc135 | 1259 | |
29967ef6 | 1260 | let mut resolver = Resolver { |
3b2f2976 | 1261 | session, |
1a4d82fc | 1262 | |
3b2f2976 | 1263 | definitions, |
923072b8 FG |
1264 | expn_that_defined: Default::default(), |
1265 | source_span, | |
1a4d82fc JJ |
1266 | |
1267 | // The outermost module has def ID 0; this is not reflected in the | |
1268 | // AST. | |
3b2f2976 | 1269 | graph_root, |
3157f602 | 1270 | prelude: None, |
94b46f34 | 1271 | extern_prelude, |
1a4d82fc | 1272 | |
0bf4aa26 XL |
1273 | has_self: FxHashSet::default(), |
1274 | field_names: FxHashMap::default(), | |
1a4d82fc | 1275 | |
9e0c209e SL |
1276 | determined_imports: Vec::new(), |
1277 | indeterminate_imports: Vec::new(), | |
1a4d82fc | 1278 | |
cdc7bbd5 | 1279 | pat_span_map: Default::default(), |
48663c56 XL |
1280 | partial_res_map: Default::default(), |
1281 | import_res_map: Default::default(), | |
1282 | label_res_map: Default::default(), | |
04454e1e FG |
1283 | lifetimes_res_map: Default::default(), |
1284 | extra_lifetime_params_map: Default::default(), | |
e74abb32 | 1285 | extern_crate_map: Default::default(), |
5099ac24 | 1286 | reexport_map: FxHashMap::default(), |
3c0e092e | 1287 | trait_map: NodeMap::default(), |
e74abb32 | 1288 | underscore_disambiguator: 0, |
e1599b0c | 1289 | empty_module, |
3b2f2976 | 1290 | module_map, |
a1dfa0c6 | 1291 | block_map: Default::default(), |
0bf4aa26 | 1292 | binding_parent_modules: FxHashMap::default(), |
e1599b0c | 1293 | ast_transform_scopes: FxHashMap::default(), |
1a4d82fc | 1294 | |
a1dfa0c6 | 1295 | glob_map: Default::default(), |
29967ef6 | 1296 | visibilities, |
04454e1e | 1297 | has_pub_restricted: false, |
0bf4aa26 | 1298 | used_imports: FxHashSet::default(), |
a1dfa0c6 | 1299 | maybe_unused_trait_imports: Default::default(), |
3b2f2976 | 1300 | maybe_unused_extern_crates: Vec::new(), |
a7813a04 | 1301 | |
54a0048b | 1302 | privacy_errors: Vec::new(), |
9e0c209e | 1303 | ambiguity_errors: Vec::new(), |
3b2f2976 | 1304 | use_injections: Vec::new(), |
b7449926 | 1305 | macro_expanded_macro_export_errors: BTreeSet::new(), |
9cc50fc6 | 1306 | |
3b2f2976 | 1307 | arenas, |
9e0c209e | 1308 | dummy_binding: arenas.alloc_name_binding(NameBinding { |
487cf647 | 1309 | kind: NameBindingKind::Res(Res::Err), |
0731742a | 1310 | ambiguity: None, |
136023e0 | 1311 | expansion: LocalExpnId::ROOT, |
9e0c209e SL |
1312 | span: DUMMY_SP, |
1313 | vis: ty::Visibility::Public, | |
1314 | }), | |
32a655c1 | 1315 | |
e74abb32 | 1316 | crate_loader: CrateLoader::new(session, metadata_loader, crate_name), |
0bf4aa26 | 1317 | macro_names: FxHashSet::default(), |
416331ca | 1318 | builtin_macros: Default::default(), |
5e7ed085 | 1319 | builtin_macro_kinds: Default::default(), |
60c5eb7d | 1320 | registered_tools, |
0bf4aa26 | 1321 | macro_use_prelude: FxHashMap::default(), |
0bf4aa26 | 1322 | macro_map: FxHashMap::default(), |
416331ca XL |
1323 | dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())), |
1324 | dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())), | |
94222f64 | 1325 | non_macro_attr: Lrc::new(SyntaxExtension::non_macro_attr(session.edition())), |
29967ef6 | 1326 | invocation_parent_scopes: Default::default(), |
ba9703b0 | 1327 | output_macro_rules_scopes: Default::default(), |
04454e1e | 1328 | macro_rules_scopes: Default::default(), |
60c5eb7d | 1329 | helper_attrs: Default::default(), |
cdc7bbd5 | 1330 | derive_data: Default::default(), |
0bf4aa26 XL |
1331 | local_macro_def_scopes: FxHashMap::default(), |
1332 | name_already_seen: FxHashMap::default(), | |
32a655c1 | 1333 | potentially_unused_imports: Vec::new(), |
a1dfa0c6 | 1334 | struct_constructors: Default::default(), |
416331ca | 1335 | unused_macros: Default::default(), |
04454e1e | 1336 | unused_macro_rules: Default::default(), |
416331ca | 1337 | proc_macro_stubs: Default::default(), |
e1599b0c XL |
1338 | single_segment_macro_resolutions: Default::default(), |
1339 | multi_segment_macro_resolutions: Default::default(), | |
1340 | builtin_attrs: Default::default(), | |
60c5eb7d | 1341 | containers_deriving_copy: Default::default(), |
dfeec247 XL |
1342 | active_features: features |
1343 | .declared_lib_features | |
1344 | .iter() | |
1345 | .map(|(feat, ..)| *feat) | |
1346 | .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat)) | |
1347 | .collect(), | |
dfeec247 | 1348 | lint_buffer: LintBuffer::default(), |
a2a8927a | 1349 | next_node_id: CRATE_NODE_ID, |
f035d41b XL |
1350 | node_id_to_def_id, |
1351 | def_id_to_node_id, | |
1352 | placeholder_field_indices: Default::default(), | |
1353 | invocation_parents, | |
29967ef6 | 1354 | trait_impl_items: Default::default(), |
6a06907d | 1355 | legacy_const_generic_args: Default::default(), |
94222f64 | 1356 | item_generics_num_lifetimes: Default::default(), |
cdc7bbd5 | 1357 | main_def: Default::default(), |
94222f64 XL |
1358 | trait_impls: Default::default(), |
1359 | proc_macros: Default::default(), | |
c295e0f8 | 1360 | confused_type_with_std_module: Default::default(), |
487cf647 | 1361 | lifetime_elision_allowed: Default::default(), |
2b03887a | 1362 | effective_visibilities: Default::default(), |
29967ef6 XL |
1363 | }; |
1364 | ||
1365 | let root_parent_scope = ParentScope::module(graph_root, &resolver); | |
136023e0 | 1366 | resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope); |
29967ef6 XL |
1367 | |
1368 | resolver | |
9cc50fc6 SL |
1369 | } |
1370 | ||
c295e0f8 XL |
1371 | fn new_module( |
1372 | &mut self, | |
1373 | parent: Option<Module<'a>>, | |
1374 | kind: ModuleKind, | |
1375 | expn_id: ExpnId, | |
1376 | span: Span, | |
1377 | no_implicit_prelude: bool, | |
1378 | ) -> Module<'a> { | |
1379 | let module_map = &mut self.module_map; | |
1380 | self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude, module_map) | |
1381 | } | |
1382 | ||
60c5eb7d | 1383 | pub fn next_node_id(&mut self) -> NodeId { |
04454e1e FG |
1384 | let start = self.next_node_id; |
1385 | let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); | |
1386 | self.next_node_id = ast::NodeId::from_u32(next); | |
1387 | start | |
1388 | } | |
1389 | ||
1390 | pub fn next_node_ids(&mut self, count: usize) -> std::ops::Range<NodeId> { | |
1391 | let start = self.next_node_id; | |
1392 | let end = start.as_usize().checked_add(count).expect("input too large; ran out of NodeIds"); | |
1393 | self.next_node_id = ast::NodeId::from_usize(end); | |
1394 | start..self.next_node_id | |
60c5eb7d XL |
1395 | } |
1396 | ||
dfeec247 | 1397 | pub fn lint_buffer(&mut self) -> &mut LintBuffer { |
e74abb32 XL |
1398 | &mut self.lint_buffer |
1399 | } | |
1400 | ||
3157f602 | 1401 | pub fn arenas() -> ResolverArenas<'a> { |
0bf4aa26 | 1402 | Default::default() |
1a4d82fc JJ |
1403 | } |
1404 | ||
2b03887a | 1405 | pub fn into_outputs(self) -> ResolverOutputs { |
94222f64 | 1406 | let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); |
f9f354fc | 1407 | let definitions = self.definitions; |
923072b8 FG |
1408 | let cstore = Box::new(self.crate_loader.into_cstore()); |
1409 | let source_span = self.source_span; | |
1410 | let expn_that_defined = self.expn_that_defined; | |
29967ef6 | 1411 | let visibilities = self.visibilities; |
04454e1e | 1412 | let has_pub_restricted = self.has_pub_restricted; |
f9f354fc | 1413 | let extern_crate_map = self.extern_crate_map; |
5099ac24 | 1414 | let reexport_map = self.reexport_map; |
f9f354fc XL |
1415 | let maybe_unused_trait_imports = self.maybe_unused_trait_imports; |
1416 | let maybe_unused_extern_crates = self.maybe_unused_extern_crates; | |
1417 | let glob_map = self.glob_map; | |
cdc7bbd5 | 1418 | let main_def = self.main_def; |
c295e0f8 | 1419 | let confused_type_with_std_module = self.confused_type_with_std_module; |
2b03887a FG |
1420 | let effective_visibilities = self.effective_visibilities; |
1421 | let global_ctxt = ResolverGlobalCtxt { | |
1422 | cstore, | |
923072b8 FG |
1423 | source_span, |
1424 | expn_that_defined, | |
29967ef6 | 1425 | visibilities, |
04454e1e | 1426 | has_pub_restricted, |
2b03887a | 1427 | effective_visibilities, |
f9f354fc | 1428 | extern_crate_map, |
5099ac24 | 1429 | reexport_map, |
f9f354fc XL |
1430 | glob_map, |
1431 | maybe_unused_trait_imports, | |
1432 | maybe_unused_extern_crates, | |
dfeec247 XL |
1433 | extern_prelude: self |
1434 | .extern_prelude | |
1435 | .iter() | |
1436 | .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) | |
1437 | .collect(), | |
cdc7bbd5 | 1438 | main_def, |
94222f64 XL |
1439 | trait_impls: self.trait_impls, |
1440 | proc_macros, | |
c295e0f8 | 1441 | confused_type_with_std_module, |
5099ac24 | 1442 | registered_tools: self.registered_tools, |
923072b8 | 1443 | }; |
2b03887a | 1444 | let ast_lowering = ty::ResolverAstLowering { |
923072b8 FG |
1445 | legacy_const_generic_args: self.legacy_const_generic_args, |
1446 | partial_res_map: self.partial_res_map, | |
1447 | import_res_map: self.import_res_map, | |
1448 | label_res_map: self.label_res_map, | |
1449 | lifetimes_res_map: self.lifetimes_res_map, | |
1450 | extra_lifetime_params_map: self.extra_lifetime_params_map, | |
1451 | next_node_id: self.next_node_id, | |
1452 | node_id_to_def_id: self.node_id_to_def_id, | |
1453 | def_id_to_node_id: self.def_id_to_node_id, | |
1454 | trait_map: self.trait_map, | |
1455 | builtin_macro_kinds: self.builtin_macro_kinds, | |
487cf647 | 1456 | lifetime_elision_allowed: self.lifetime_elision_allowed, |
923072b8 | 1457 | }; |
2b03887a | 1458 | ResolverOutputs { definitions, global_ctxt, ast_lowering } |
e74abb32 XL |
1459 | } |
1460 | ||
2b03887a | 1461 | pub fn clone_outputs(&self) -> ResolverOutputs { |
94222f64 | 1462 | let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); |
923072b8 FG |
1463 | let definitions = self.definitions.clone(); |
1464 | let cstore = Box::new(self.cstore().clone()); | |
2b03887a FG |
1465 | let global_ctxt = ResolverGlobalCtxt { |
1466 | cstore, | |
923072b8 FG |
1467 | source_span: self.source_span.clone(), |
1468 | expn_that_defined: self.expn_that_defined.clone(), | |
29967ef6 | 1469 | visibilities: self.visibilities.clone(), |
04454e1e | 1470 | has_pub_restricted: self.has_pub_restricted, |
e74abb32 | 1471 | extern_crate_map: self.extern_crate_map.clone(), |
5099ac24 | 1472 | reexport_map: self.reexport_map.clone(), |
e74abb32 XL |
1473 | glob_map: self.glob_map.clone(), |
1474 | maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(), | |
1475 | maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(), | |
dfeec247 XL |
1476 | extern_prelude: self |
1477 | .extern_prelude | |
1478 | .iter() | |
1479 | .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) | |
1480 | .collect(), | |
c295e0f8 | 1481 | main_def: self.main_def, |
94222f64 XL |
1482 | trait_impls: self.trait_impls.clone(), |
1483 | proc_macros, | |
c295e0f8 | 1484 | confused_type_with_std_module: self.confused_type_with_std_module.clone(), |
5099ac24 | 1485 | registered_tools: self.registered_tools.clone(), |
2b03887a | 1486 | effective_visibilities: self.effective_visibilities.clone(), |
923072b8 | 1487 | }; |
2b03887a | 1488 | let ast_lowering = ty::ResolverAstLowering { |
923072b8 FG |
1489 | legacy_const_generic_args: self.legacy_const_generic_args.clone(), |
1490 | partial_res_map: self.partial_res_map.clone(), | |
1491 | import_res_map: self.import_res_map.clone(), | |
1492 | label_res_map: self.label_res_map.clone(), | |
1493 | lifetimes_res_map: self.lifetimes_res_map.clone(), | |
1494 | extra_lifetime_params_map: self.extra_lifetime_params_map.clone(), | |
1495 | next_node_id: self.next_node_id.clone(), | |
1496 | node_id_to_def_id: self.node_id_to_def_id.clone(), | |
1497 | def_id_to_node_id: self.def_id_to_node_id.clone(), | |
1498 | trait_map: self.trait_map.clone(), | |
1499 | builtin_macro_kinds: self.builtin_macro_kinds.clone(), | |
487cf647 | 1500 | lifetime_elision_allowed: self.lifetime_elision_allowed.clone(), |
923072b8 | 1501 | }; |
2b03887a | 1502 | ResolverOutputs { definitions, global_ctxt, ast_lowering } |
923072b8 FG |
1503 | } |
1504 | ||
1505 | fn create_stable_hashing_context(&self) -> StableHashingContext<'_> { | |
1506 | StableHashingContext::new( | |
1507 | self.session, | |
1508 | &self.definitions, | |
1509 | self.crate_loader.cstore(), | |
1510 | &self.source_span, | |
1511 | ) | |
e74abb32 XL |
1512 | } |
1513 | ||
1514 | pub fn cstore(&self) -> &CStore { | |
1515 | self.crate_loader.cstore() | |
1516 | } | |
1517 | ||
416331ca XL |
1518 | fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> { |
1519 | match macro_kind { | |
1520 | MacroKind::Bang => self.dummy_ext_bang.clone(), | |
1521 | MacroKind::Derive => self.dummy_ext_derive.clone(), | |
94222f64 | 1522 | MacroKind::Attr => self.non_macro_attr.clone(), |
416331ca XL |
1523 | } |
1524 | } | |
1525 | ||
0531ce1d | 1526 | /// Runs the function on each namespace. |
83c7162d XL |
1527 | fn per_ns<F: FnMut(&mut Self, Namespace)>(&mut self, mut f: F) { |
1528 | f(self, TypeNS); | |
1529 | f(self, ValueNS); | |
b7449926 | 1530 | f(self, MacroNS); |
476ff2be | 1531 | } |
c30ab7b3 | 1532 | |
e1599b0c | 1533 | fn is_builtin_macro(&mut self, res: Res) -> bool { |
923072b8 | 1534 | self.get_macro(res).map_or(false, |macro_data| macro_data.ext.builtin_name.is_some()) |
416331ca XL |
1535 | } |
1536 | ||
ff7c6d11 XL |
1537 | fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId { |
1538 | loop { | |
6a06907d | 1539 | match ctxt.outer_expn_data().macro_def_id { |
f9f354fc | 1540 | Some(def_id) => return def_id, |
ff7c6d11 XL |
1541 | None => ctxt.remove_mark(), |
1542 | }; | |
1543 | } | |
1544 | } | |
1545 | ||
476ff2be SL |
1546 | /// Entry point to crate resolution. |
1547 | pub fn resolve_crate(&mut self, krate: &Crate) { | |
5869c6ff XL |
1548 | self.session.time("resolve_crate", || { |
1549 | self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports()); | |
2b03887a FG |
1550 | self.session.time("compute_effective_visibilities", || { |
1551 | EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate) | |
5099ac24 | 1552 | }); |
5869c6ff XL |
1553 | self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions()); |
1554 | self.session.time("late_resolve_crate", || self.late_resolve_crate(krate)); | |
cdc7bbd5 | 1555 | self.session.time("resolve_main", || self.resolve_main()); |
5869c6ff XL |
1556 | self.session.time("resolve_check_unused", || self.check_unused(krate)); |
1557 | self.session.time("resolve_report_errors", || self.report_errors(krate)); | |
1558 | self.session.time("resolve_postprocess", || self.crate_loader.postprocess(krate)); | |
1559 | }); | |
1560 | } | |
e74abb32 | 1561 | |
5869c6ff XL |
1562 | pub fn traits_in_scope( |
1563 | &mut self, | |
1564 | current_trait: Option<Module<'a>>, | |
1565 | parent_scope: &ParentScope<'a>, | |
1566 | ctxt: SyntaxContext, | |
1567 | assoc_item: Option<(Symbol, Namespace)>, | |
1568 | ) -> Vec<TraitCandidate> { | |
1569 | let mut found_traits = Vec::new(); | |
1570 | ||
1571 | if let Some(module) = current_trait { | |
1572 | if self.trait_may_have_item(Some(module), assoc_item) { | |
c295e0f8 | 1573 | let def_id = module.def_id(); |
5869c6ff XL |
1574 | found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] }); |
1575 | } | |
1576 | } | |
3b2f2976 | 1577 | |
5869c6ff XL |
1578 | self.visit_scopes(ScopeSet::All(TypeNS, false), parent_scope, ctxt, |this, scope, _, _| { |
1579 | match scope { | |
cdc7bbd5 | 1580 | Scope::Module(module, _) => { |
5869c6ff XL |
1581 | this.traits_in_module(module, assoc_item, &mut found_traits); |
1582 | } | |
1583 | Scope::StdLibPrelude => { | |
1584 | if let Some(module) = this.prelude { | |
1585 | this.traits_in_module(module, assoc_item, &mut found_traits); | |
1586 | } | |
1587 | } | |
1588 | Scope::ExternPrelude | Scope::ToolPrelude | Scope::BuiltinTypes => {} | |
1589 | _ => unreachable!(), | |
1590 | } | |
1591 | None::<()> | |
1592 | }); | |
3157f602 | 1593 | |
5869c6ff | 1594 | found_traits |
3157f602 XL |
1595 | } |
1596 | ||
5869c6ff | 1597 | fn traits_in_module( |
3dfed10e | 1598 | &mut self, |
3dfed10e | 1599 | module: Module<'a>, |
5869c6ff | 1600 | assoc_item: Option<(Symbol, Namespace)>, |
3dfed10e | 1601 | found_traits: &mut Vec<TraitCandidate>, |
3dfed10e | 1602 | ) { |
3dfed10e XL |
1603 | module.ensure_traits(self); |
1604 | let traits = module.traits.borrow(); | |
5869c6ff XL |
1605 | for (trait_name, trait_binding) in traits.as_ref().unwrap().iter() { |
1606 | if self.trait_may_have_item(trait_binding.module(), assoc_item) { | |
1607 | let def_id = trait_binding.res().def_id(); | |
1608 | let import_ids = self.find_transitive_imports(&trait_binding.kind, *trait_name); | |
1609 | found_traits.push(TraitCandidate { def_id, import_ids }); | |
1610 | } | |
1611 | } | |
1612 | } | |
3dfed10e | 1613 | |
5869c6ff XL |
1614 | // List of traits in scope is pruned on best effort basis. We reject traits not having an |
1615 | // associated item with the given name and namespace (if specified). This is a conservative | |
1616 | // optimization, proper hygienic type-based resolution of associated items is done in typeck. | |
1617 | // We don't reject trait aliases (`trait_module == None`) because we don't have access to their | |
1618 | // associated items. | |
1619 | fn trait_may_have_item( | |
1620 | &mut self, | |
1621 | trait_module: Option<Module<'a>>, | |
1622 | assoc_item: Option<(Symbol, Namespace)>, | |
1623 | ) -> bool { | |
1624 | match (trait_module, assoc_item) { | |
1625 | (Some(trait_module), Some((name, ns))) => { | |
1626 | self.resolutions(trait_module).borrow().iter().any(|resolution| { | |
1627 | let (&BindingKey { ident: assoc_ident, ns: assoc_ns, .. }, _) = resolution; | |
1628 | assoc_ns == ns && assoc_ident.name == name | |
1629 | }) | |
3dfed10e | 1630 | } |
5869c6ff | 1631 | _ => true, |
3dfed10e XL |
1632 | } |
1633 | } | |
1634 | ||
1635 | fn find_transitive_imports( | |
1636 | &mut self, | |
1637 | mut kind: &NameBindingKind<'_>, | |
1638 | trait_name: Ident, | |
1639 | ) -> SmallVec<[LocalDefId; 1]> { | |
1640 | let mut import_ids = smallvec![]; | |
1641 | while let NameBindingKind::Import { import, binding, .. } = kind { | |
487cf647 FG |
1642 | if let Some(node_id) = import.id() { |
1643 | let def_id = self.local_def_id(node_id); | |
1644 | self.maybe_unused_trait_imports.insert(def_id); | |
1645 | import_ids.push(def_id); | |
1646 | } | |
3dfed10e | 1647 | self.add_to_glob_map(&import, trait_name); |
3dfed10e XL |
1648 | kind = &binding.kind; |
1649 | } | |
1650 | import_ids | |
1651 | } | |
1652 | ||
e74abb32 | 1653 | fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey { |
ba9703b0 | 1654 | let ident = ident.normalize_to_macros_2_0(); |
e74abb32 XL |
1655 | let disambiguator = if ident.name == kw::Underscore { |
1656 | self.underscore_disambiguator += 1; | |
1657 | self.underscore_disambiguator | |
1658 | } else { | |
1659 | 0 | |
1660 | }; | |
1661 | BindingKey { ident, ns, disambiguator } | |
1662 | } | |
1663 | ||
e1599b0c XL |
1664 | fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> { |
1665 | if module.populate_on_access.get() { | |
1666 | module.populate_on_access.set(false); | |
1667 | self.build_reduced_graph_external(module); | |
1668 | } | |
1669 | &module.lazy_resolutions | |
1670 | } | |
1671 | ||
dfeec247 XL |
1672 | fn resolution( |
1673 | &mut self, | |
1674 | module: Module<'a>, | |
1675 | key: BindingKey, | |
1676 | ) -> &'a RefCell<NameResolution<'a>> { | |
1677 | *self | |
1678 | .resolutions(module) | |
1679 | .borrow_mut() | |
1680 | .entry(key) | |
1681 | .or_insert_with(|| self.arenas.alloc_name_resolution()) | |
e1599b0c XL |
1682 | } |
1683 | ||
dfeec247 XL |
1684 | fn record_use( |
1685 | &mut self, | |
1686 | ident: Ident, | |
dfeec247 XL |
1687 | used_binding: &'a NameBinding<'a>, |
1688 | is_lexical_scope: bool, | |
1689 | ) { | |
0731742a XL |
1690 | if let Some((b2, kind)) = used_binding.ambiguity { |
1691 | self.ambiguity_errors.push(AmbiguityError { | |
dfeec247 XL |
1692 | kind, |
1693 | ident, | |
1694 | b1: used_binding, | |
1695 | b2, | |
0731742a XL |
1696 | misc1: AmbiguityErrorMisc::None, |
1697 | misc2: AmbiguityErrorMisc::None, | |
1698 | }); | |
1699 | } | |
74b04a01 | 1700 | if let NameBindingKind::Import { import, binding, ref used } = used_binding.kind { |
0731742a XL |
1701 | // Avoid marking `extern crate` items that refer to a name from extern prelude, |
1702 | // but not introduce it, as used if they are accessed from lexical scope. | |
1703 | if is_lexical_scope { | |
ba9703b0 | 1704 | if let Some(entry) = self.extern_prelude.get(&ident.normalize_to_macros_2_0()) { |
0731742a XL |
1705 | if let Some(crate_item) = entry.extern_crate_item { |
1706 | if ptr::eq(used_binding, crate_item) && !entry.introduced_by_item { | |
1707 | return; | |
13cf67c4 XL |
1708 | } |
1709 | } | |
1710 | } | |
9e0c209e | 1711 | } |
0731742a | 1712 | used.set(true); |
74b04a01 | 1713 | import.used.set(true); |
487cf647 FG |
1714 | if let Some(id) = import.id() { |
1715 | self.used_imports.insert(id); | |
1716 | } | |
74b04a01 | 1717 | self.add_to_glob_map(&import, ident); |
94222f64 | 1718 | self.record_use(ident, binding, false); |
54a0048b | 1719 | } |
5bcae85e | 1720 | } |
7453a54e | 1721 | |
9fa01778 | 1722 | #[inline] |
74b04a01 | 1723 | fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) { |
487cf647 FG |
1724 | if let ImportKind::Glob { id, .. } = import.kind { |
1725 | let def_id = self.local_def_id(id); | |
f9f354fc | 1726 | self.glob_map.entry(def_id).or_default().insert(ident.name); |
1a4d82fc | 1727 | } |
1a4d82fc JJ |
1728 | } |
1729 | ||
8faf50e0 | 1730 | fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> { |
3dfed10e | 1731 | debug!("resolve_crate_root({:?})", ident); |
8faf50e0 | 1732 | let mut ctxt = ident.span.ctxt(); |
dc9dc135 | 1733 | let mark = if ident.name == kw::DollarCrate { |
2c00a5a8 XL |
1734 | // When resolving `$crate` from a `macro_rules!` invoked in a `macro`, |
1735 | // we don't want to pretend that the `macro_rules!` definition is in the `macro` | |
ba9703b0 | 1736 | // as described in `SyntaxContext::apply_mark`, so we ignore prepended opaque marks. |
8faf50e0 XL |
1737 | // FIXME: This is only a guess and it doesn't work correctly for `macro_rules!` |
1738 | // definitions actually produced by `macro` and `macro` definitions produced by | |
1739 | // `macro_rules!`, but at least such configurations are not stable yet. | |
ba9703b0 | 1740 | ctxt = ctxt.normalize_to_macro_rules(); |
3dfed10e XL |
1741 | debug!( |
1742 | "resolve_crate_root: marks={:?}", | |
1743 | ctxt.marks().into_iter().map(|(i, t)| (i.expn_data(), t)).collect::<Vec<_>>() | |
1744 | ); | |
8faf50e0 XL |
1745 | let mut iter = ctxt.marks().into_iter().rev().peekable(); |
1746 | let mut result = None; | |
ba9703b0 | 1747 | // Find the last opaque mark from the end if it exists. |
8faf50e0 XL |
1748 | while let Some(&(mark, transparency)) = iter.peek() { |
1749 | if transparency == Transparency::Opaque { | |
1750 | result = Some(mark); | |
1751 | iter.next(); | |
1752 | } else { | |
1753 | break; | |
1754 | } | |
1755 | } | |
3dfed10e XL |
1756 | debug!( |
1757 | "resolve_crate_root: found opaque mark {:?} {:?}", | |
1758 | result, | |
1759 | result.map(|r| r.expn_data()) | |
1760 | ); | |
ba9703b0 | 1761 | // Then find the last semi-transparent mark from the end if it exists. |
8faf50e0 XL |
1762 | for (mark, transparency) in iter { |
1763 | if transparency == Transparency::SemiTransparent { | |
1764 | result = Some(mark); | |
1765 | } else { | |
1766 | break; | |
1767 | } | |
1768 | } | |
3dfed10e XL |
1769 | debug!( |
1770 | "resolve_crate_root: found semi-transparent mark {:?} {:?}", | |
1771 | result, | |
1772 | result.map(|r| r.expn_data()) | |
1773 | ); | |
8faf50e0 | 1774 | result |
2c00a5a8 | 1775 | } else { |
3dfed10e | 1776 | debug!("resolve_crate_root: not DollarCrate"); |
ba9703b0 | 1777 | ctxt = ctxt.normalize_to_macros_2_0(); |
416331ca | 1778 | ctxt.adjust(ExpnId::root()) |
2c00a5a8 XL |
1779 | }; |
1780 | let module = match mark { | |
c295e0f8 | 1781 | Some(def) => self.expn_def_scope(def), |
3dfed10e XL |
1782 | None => { |
1783 | debug!( | |
1784 | "resolve_crate_root({:?}): found no mark (ident.span = {:?})", | |
1785 | ident, ident.span | |
1786 | ); | |
1787 | return self.graph_root; | |
1788 | } | |
7cac9316 | 1789 | }; |
c295e0f8 XL |
1790 | let module = self.expect_module( |
1791 | module.opt_def_id().map_or(LOCAL_CRATE, |def_id| def_id.krate).as_def_id(), | |
1792 | ); | |
3dfed10e XL |
1793 | debug!( |
1794 | "resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})", | |
1795 | ident, | |
1796 | module, | |
1797 | module.kind.name(), | |
1798 | ident.span | |
1799 | ); | |
1800 | module | |
7cac9316 XL |
1801 | } |
1802 | ||
1803 | fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> { | |
c295e0f8 | 1804 | let mut module = self.expect_module(module.nearest_parent_mod()); |
ba9703b0 | 1805 | while module.span.ctxt().normalize_to_macros_2_0() != *ctxt { |
c295e0f8 XL |
1806 | let parent = module.parent.unwrap_or_else(|| self.expn_def_scope(ctxt.remove_mark())); |
1807 | module = self.expect_module(parent.nearest_parent_mod()); | |
c30ab7b3 | 1808 | } |
7cac9316 | 1809 | module |
c30ab7b3 SL |
1810 | } |
1811 | ||
48663c56 XL |
1812 | fn record_partial_res(&mut self, node_id: NodeId, resolution: PartialRes) { |
1813 | debug!("(recording res) recording {:?} for {}", resolution, node_id); | |
1814 | if let Some(prev_res) = self.partial_res_map.insert(node_id, resolution) { | |
a7813a04 | 1815 | panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution); |
1a4d82fc JJ |
1816 | } |
1817 | } | |
1818 | ||
cdc7bbd5 XL |
1819 | fn record_pat_span(&mut self, node: NodeId, span: Span) { |
1820 | debug!("(recording pat) recording {:?} for {:?}", node, span); | |
1821 | self.pat_span_map.insert(node, span); | |
1822 | } | |
1823 | ||
f2b60f7d FG |
1824 | fn is_accessible_from( |
1825 | &self, | |
1826 | vis: ty::Visibility<impl Into<DefId>>, | |
1827 | module: Module<'a>, | |
1828 | ) -> bool { | |
c295e0f8 | 1829 | vis.is_accessible_from(module.nearest_parent_mod(), self) |
54a0048b SL |
1830 | } |
1831 | ||
4462d4a0 | 1832 | fn set_binding_parent_module(&mut self, binding: &'a NameBinding<'a>, module: Module<'a>) { |
5099ac24 FG |
1833 | if let Some(old_module) = |
1834 | self.binding_parent_modules.insert(Interned::new_unchecked(binding), module) | |
1835 | { | |
4462d4a0 XL |
1836 | if !ptr::eq(module, old_module) { |
1837 | span_bug!(binding.span, "parent module is reset for binding"); | |
1838 | } | |
1839 | } | |
1840 | } | |
1841 | ||
ba9703b0 | 1842 | fn disambiguate_macro_rules_vs_modularized( |
4462d4a0 | 1843 | &self, |
ba9703b0 XL |
1844 | macro_rules: &'a NameBinding<'a>, |
1845 | modularized: &'a NameBinding<'a>, | |
4462d4a0 | 1846 | ) -> bool { |
ba9703b0 | 1847 | // Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules" |
4462d4a0 XL |
1848 | // is disambiguated to mitigate regressions from macro modularization. |
1849 | // Scoping for `macro_rules` behaves like scoping for `let` at module level, in general. | |
dfeec247 | 1850 | match ( |
5099ac24 FG |
1851 | self.binding_parent_modules.get(&Interned::new_unchecked(macro_rules)), |
1852 | self.binding_parent_modules.get(&Interned::new_unchecked(modularized)), | |
dfeec247 | 1853 | ) { |
ba9703b0 | 1854 | (Some(macro_rules), Some(modularized)) => { |
c295e0f8 | 1855 | macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod() |
ba9703b0 | 1856 | && modularized.is_ancestor_of(macro_rules) |
dfeec247 | 1857 | } |
4462d4a0 XL |
1858 | _ => false, |
1859 | } | |
1860 | } | |
1861 | ||
5e7ed085 | 1862 | fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<&'a NameBinding<'a>> { |
13cf67c4 XL |
1863 | if ident.is_path_segment_keyword() { |
1864 | // Make sure `self`, `super` etc produce an error when passed to here. | |
1865 | return None; | |
1866 | } | |
ba9703b0 | 1867 | self.extern_prelude.get(&ident.normalize_to_macros_2_0()).cloned().and_then(|entry| { |
0bf4aa26 | 1868 | if let Some(binding) = entry.extern_crate_item { |
5e7ed085 | 1869 | if finalize && entry.introduced_by_item { |
94222f64 | 1870 | self.record_use(ident, binding, false); |
0731742a | 1871 | } |
0bf4aa26 XL |
1872 | Some(binding) |
1873 | } else { | |
5e7ed085 | 1874 | let crate_id = if finalize { |
a2a8927a XL |
1875 | let Some(crate_id) = |
1876 | self.crate_loader.process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); }; | |
1877 | crate_id | |
0bf4aa26 | 1878 | } else { |
3dfed10e | 1879 | self.crate_loader.maybe_process_path_extern(ident.name)? |
0bf4aa26 | 1880 | }; |
c295e0f8 | 1881 | let crate_root = self.expect_module(crate_id.as_def_id()); |
f2b60f7d FG |
1882 | let vis = ty::Visibility::<LocalDefId>::Public; |
1883 | Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas)) | |
0bf4aa26 XL |
1884 | } |
1885 | }) | |
1886 | } | |
c34b1796 | 1887 | |
5e7ed085 | 1888 | /// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>` |
416331ca XL |
1889 | /// isn't something that can be returned because it can't be made to live that long, |
1890 | /// and also it's a private type. Fortunately rustdoc doesn't need to know the error, | |
1891 | /// just that an error occurred. | |
5e7ed085 | 1892 | pub fn resolve_rustdoc_path( |
dfeec247 | 1893 | &mut self, |
dfeec247 XL |
1894 | path_str: &str, |
1895 | ns: Namespace, | |
04454e1e | 1896 | mut parent_scope: ParentScope<'a>, |
5e7ed085 FG |
1897 | ) -> Option<Res> { |
1898 | let mut segments = | |
1899 | Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident)); | |
04454e1e FG |
1900 | if let Some(segment) = segments.first_mut() { |
1901 | if segment.ident.name == kw::Crate { | |
1902 | // FIXME: `resolve_path` always resolves `crate` to the current crate root, but | |
1903 | // rustdoc wants it to resolve to the `parent_scope`'s crate root. This trick of | |
1904 | // replacing `crate` with `self` and changing the current module should achieve | |
1905 | // the same effect. | |
1906 | segment.ident.name = kw::SelfLower; | |
1907 | parent_scope.module = | |
1908 | self.expect_module(parent_scope.module.def_id().krate.as_def_id()); | |
1909 | } else if segment.ident.name == kw::Empty { | |
1910 | segment.ident.name = kw::PathRoot; | |
1911 | } | |
5e7ed085 | 1912 | } |
416331ca | 1913 | |
04454e1e | 1914 | match self.maybe_resolve_path(&segments, Some(ns), &parent_scope) { |
5e7ed085 | 1915 | PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()), |
2b03887a FG |
1916 | PathResult::NonModule(path_res) => path_res.full_res(), |
1917 | PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => { | |
1918 | None | |
dfeec247 | 1919 | } |
416331ca | 1920 | PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), |
416331ca XL |
1921 | } |
1922 | } | |
32a655c1 | 1923 | |
5099ac24 FG |
1924 | /// For rustdoc. |
1925 | /// For local modules returns only reexports, for external modules returns all children. | |
1926 | pub fn module_children_or_reexports(&self, def_id: DefId) -> Vec<ModChild> { | |
1927 | if let Some(def_id) = def_id.as_local() { | |
1928 | self.reexport_map.get(&def_id).cloned().unwrap_or_default() | |
1929 | } else { | |
487cf647 | 1930 | self.cstore().module_children_untracked(def_id, self.session).collect() |
5099ac24 FG |
1931 | } |
1932 | } | |
1933 | ||
04454e1e FG |
1934 | /// For rustdoc. |
1935 | pub fn macro_rules_scope(&self, def_id: LocalDefId) -> (MacroRulesScopeRef<'a>, Res) { | |
1936 | let scope = *self.macro_rules_scopes.get(&def_id).expect("not a `macro_rules` item"); | |
1937 | match scope.get() { | |
1938 | MacroRulesScope::Binding(mb) => (scope, mb.binding.res()), | |
1939 | _ => unreachable!(), | |
1940 | } | |
1941 | } | |
1942 | ||
2b03887a FG |
1943 | /// For rustdoc. |
1944 | pub fn get_partial_res(&self, node_id: NodeId) -> Option<PartialRes> { | |
1945 | self.partial_res_map.get(&node_id).copied() | |
1946 | } | |
1947 | ||
f035d41b XL |
1948 | /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. |
1949 | #[inline] | |
1950 | pub fn opt_span(&self, def_id: DefId) -> Option<Span> { | |
923072b8 | 1951 | def_id.as_local().map(|def_id| self.source_span[def_id]) |
f035d41b | 1952 | } |
6a06907d | 1953 | |
f2b60f7d FG |
1954 | /// Retrieves the name of the given `DefId`. |
1955 | #[inline] | |
1956 | pub fn opt_name(&self, def_id: DefId) -> Option<Symbol> { | |
1957 | let def_key = match def_id.as_local() { | |
1958 | Some(def_id) => self.definitions.def_key(def_id), | |
1959 | None => self.cstore().def_key(def_id), | |
1960 | }; | |
1961 | def_key.get_opt_name() | |
1962 | } | |
1963 | ||
6a06907d XL |
1964 | /// Checks if an expression refers to a function marked with |
1965 | /// `#[rustc_legacy_const_generics]` and returns the argument index list | |
1966 | /// from the attribute. | |
1967 | pub fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>> { | |
1968 | if let ExprKind::Path(None, path) = &expr.kind { | |
1969 | // Don't perform legacy const generics rewriting if the path already | |
1970 | // has generic arguments. | |
1971 | if path.segments.last().unwrap().args.is_some() { | |
1972 | return None; | |
1973 | } | |
1974 | ||
2b03887a FG |
1975 | let res = self.partial_res_map.get(&expr.id)?.full_res()?; |
1976 | if let Res::Def(def::DefKind::Fn, def_id) = res { | |
6a06907d XL |
1977 | // We only support cross-crate argument rewriting. Uses |
1978 | // within the same crate should be updated to use the new | |
1979 | // const generics style. | |
1980 | if def_id.is_local() { | |
1981 | return None; | |
1982 | } | |
1983 | ||
1984 | if let Some(v) = self.legacy_const_generic_args.get(&def_id) { | |
1985 | return v.clone(); | |
1986 | } | |
1987 | ||
a2a8927a XL |
1988 | let attr = self |
1989 | .cstore() | |
1990 | .item_attrs_untracked(def_id, self.session) | |
a2a8927a XL |
1991 | .find(|a| a.has_name(sym::rustc_legacy_const_generics))?; |
1992 | let mut ret = Vec::new(); | |
1993 | for meta in attr.meta_item_list()? { | |
487cf647 | 1994 | match meta.lit()?.kind { |
a2a8927a XL |
1995 | LitKind::Int(a, _) => ret.push(a as usize), |
1996 | _ => panic!("invalid arg index"), | |
6a06907d | 1997 | } |
a2a8927a | 1998 | } |
f2b60f7d | 1999 | // Cache the lookup to avoid parsing attributes for an item multiple times. |
a2a8927a XL |
2000 | self.legacy_const_generic_args.insert(def_id, Some(ret.clone())); |
2001 | return Some(ret); | |
6a06907d XL |
2002 | } |
2003 | } | |
2004 | None | |
2005 | } | |
cdc7bbd5 XL |
2006 | |
2007 | fn resolve_main(&mut self) { | |
2008 | let module = self.graph_root; | |
2009 | let ident = Ident::with_dummy_span(sym::main); | |
2010 | let parent_scope = &ParentScope::module(module, self); | |
2011 | ||
04454e1e | 2012 | let Ok(name_binding) = self.maybe_resolve_ident_in_module( |
cdc7bbd5 XL |
2013 | ModuleOrUniformRoot::Module(module), |
2014 | ident, | |
2015 | ValueNS, | |
2016 | parent_scope, | |
5e7ed085 FG |
2017 | ) else { |
2018 | return; | |
cdc7bbd5 XL |
2019 | }; |
2020 | ||
2021 | let res = name_binding.res(); | |
2022 | let is_import = name_binding.is_import(); | |
2023 | let span = name_binding.span; | |
2024 | if let Res::Def(DefKind::Fn, _) = res { | |
94222f64 | 2025 | self.record_use(ident, name_binding, false); |
cdc7bbd5 XL |
2026 | } |
2027 | self.main_def = Some(MainDefinition { res, is_import, span }); | |
2028 | } | |
f2b60f7d FG |
2029 | |
2030 | // Items that go to reexport table encoded to metadata and visible through it to other crates. | |
2031 | fn is_reexport(&self, binding: &NameBinding<'a>) -> Option<def::Res<!>> { | |
487cf647 | 2032 | if binding.is_import() { |
f2b60f7d FG |
2033 | let res = binding.res().expect_non_local(); |
2034 | // Ambiguous imports are treated as errors at this point and are | |
2035 | // not exposed to other crates (see #36837 for more details). | |
2036 | if res != def::Res::Err && !binding.is_ambiguity() { | |
2037 | return Some(res); | |
2038 | } | |
2039 | } | |
2040 | ||
2041 | return None; | |
2042 | } | |
32a655c1 SL |
2043 | } |
2044 | ||
f9f354fc | 2045 | fn names_to_string(names: &[Symbol]) -> String { |
c34b1796 | 2046 | let mut result = String::new(); |
dfeec247 | 2047 | for (i, name) in names.iter().filter(|name| **name != kw::PathRoot).enumerate() { |
32a655c1 SL |
2048 | if i > 0 { |
2049 | result.push_str("::"); | |
c34b1796 | 2050 | } |
60c5eb7d XL |
2051 | if Ident::with_dummy_span(*name).is_raw_guess() { |
2052 | result.push_str("r#"); | |
2053 | } | |
a2a8927a | 2054 | result.push_str(name.as_str()); |
92a42be0 | 2055 | } |
c34b1796 AL |
2056 | result |
2057 | } | |
2058 | ||
32a655c1 | 2059 | fn path_names_to_string(path: &Path) -> String { |
60c5eb7d | 2060 | names_to_string(&path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>()) |
c34b1796 AL |
2061 | } |
2062 | ||
2063 | /// A somewhat inefficient routine to obtain the name of a module. | |
9fa01778 | 2064 | fn module_to_string(module: Module<'_>) -> Option<String> { |
c34b1796 AL |
2065 | let mut names = Vec::new(); |
2066 | ||
f9f354fc | 2067 | fn collect_mod(names: &mut Vec<Symbol>, module: Module<'_>) { |
48663c56 | 2068 | if let ModuleKind::Def(.., name) = module.kind { |
9e0c209e | 2069 | if let Some(parent) = module.parent { |
e1599b0c | 2070 | names.push(name); |
9e0c209e | 2071 | collect_mod(names, parent); |
c34b1796 | 2072 | } |
9e0c209e | 2073 | } else { |
f9f354fc | 2074 | names.push(Symbol::intern("<opaque>")); |
c30ab7b3 | 2075 | collect_mod(names, module.parent.unwrap()); |
c34b1796 AL |
2076 | } |
2077 | } | |
2078 | collect_mod(&mut names, module); | |
2079 | ||
9346a6ac | 2080 | if names.is_empty() { |
2c00a5a8 | 2081 | return None; |
c34b1796 | 2082 | } |
e1599b0c XL |
2083 | names.reverse(); |
2084 | Some(names_to_string(&names)) | |
c34b1796 AL |
2085 | } |
2086 | ||
94b46f34 | 2087 | #[derive(Copy, Clone, Debug)] |
04454e1e FG |
2088 | struct Finalize { |
2089 | /// Node ID for linting. | |
2090 | node_id: NodeId, | |
2091 | /// Span of the whole path or some its characteristic fragment. | |
2092 | /// E.g. span of `b` in `foo::{a, b, c}`, or full span for regular paths. | |
2093 | path_span: Span, | |
2b03887a | 2094 | /// Span of the path start, suitable for prepending something to it. |
04454e1e FG |
2095 | /// E.g. span of `foo` in `foo::{a, b, c}`, or full span for regular paths. |
2096 | root_span: Span, | |
2097 | /// Whether to report privacy errors or silently return "no resolution" for them, | |
2098 | /// similarly to speculative resolution. | |
2099 | report_private: bool, | |
94b46f34 XL |
2100 | } |
2101 | ||
5e7ed085 | 2102 | impl Finalize { |
04454e1e FG |
2103 | fn new(node_id: NodeId, path_span: Span) -> Finalize { |
2104 | Finalize::with_root_span(node_id, path_span, path_span) | |
5e7ed085 FG |
2105 | } |
2106 | ||
04454e1e FG |
2107 | fn with_root_span(node_id: NodeId, path_span: Span, root_span: Span) -> Finalize { |
2108 | Finalize { node_id, path_span, root_span, report_private: true } | |
5e7ed085 | 2109 | } |
8faf50e0 | 2110 | } |