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