1#![allow(internal_features)]
11#![allow(rustc::diagnostic_outside_of_impl)]
12#![allow(rustc::untranslatable_diagnostic)]
13#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
14#![doc(rust_logo)]
15#![feature(assert_matches)]
16#![feature(box_patterns)]
17#![feature(if_let_guard)]
18#![feature(iter_intersperse)]
19#![feature(let_chains)]
20#![feature(rustc_attrs)]
21#![feature(rustdoc_internals)]
22use std::cell::{Cell, RefCell};
25use std::collections::BTreeSet;
26use std::fmt;
27use std::sync::Arc;
28
29use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
30use effective_visibilities::EffectiveVisibilitiesVisitor;
31use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
32use imports::{Import, ImportData, ImportKind, NameResolution};
33use late::{
34 ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource,
35 UnnecessaryQualification,
36};
37use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
38use rustc_arena::{DroplessArena, TypedArena};
39use rustc_ast::expand::StrippedCfgItem;
40use rustc_ast::node_id::NodeMap;
41use rustc_ast::{
42 self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, Expr, ExprKind, GenericArg, GenericArgs,
43 LitKind, NodeId, Path, attr,
44};
45use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
46use rustc_data_structures::intern::Interned;
47use rustc_data_structures::steal::Steal;
48use rustc_data_structures::sync::FreezeReadGuard;
49use rustc_data_structures::unord::UnordMap;
50use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed};
51use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
52use rustc_feature::BUILTIN_ATTRIBUTES;
53use rustc_hir::def::Namespace::{self, *};
54use rustc_hir::def::{
55 self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS,
56};
57use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap};
58use rustc_hir::{PrimTy, TraitCandidate};
59use rustc_index::IndexVec;
60use rustc_metadata::creader::{CStore, CrateLoader};
61use rustc_middle::metadata::ModChild;
62use rustc_middle::middle::privacy::EffectiveVisibilities;
63use rustc_middle::query::Providers;
64use rustc_middle::span_bug;
65use rustc_middle::ty::{
66 self, DelegationFnSig, Feed, MainDefinition, RegisteredTools, ResolverGlobalCtxt,
67 ResolverOutputs, TyCtxt, TyCtxtFeed,
68};
69use rustc_query_system::ich::StableHashingContext;
70use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
71use rustc_session::lint::{BuiltinLintDiag, LintBuffer};
72use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
73use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
74use smallvec::{SmallVec, smallvec};
75use tracing::debug;
76
77type Res = def::Res<NodeId>;
78
79mod build_reduced_graph;
80mod check_unused;
81mod def_collector;
82mod diagnostics;
83mod effective_visibilities;
84mod errors;
85mod ident;
86mod imports;
87mod late;
88mod macros;
89pub mod rustdoc;
90
91rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
92
93#[derive(Debug)]
94enum Weak {
95 Yes,
96 No,
97}
98
99#[derive(Copy, Clone, PartialEq, Debug)]
100enum Determinacy {
101 Determined,
102 Undetermined,
103}
104
105impl Determinacy {
106 fn determined(determined: bool) -> Determinacy {
107 if determined { Determinacy::Determined } else { Determinacy::Undetermined }
108 }
109}
110
111#[derive(Clone, Copy, Debug)]
115enum Scope<'ra> {
116 DeriveHelpers(LocalExpnId),
117 DeriveHelpersCompat,
118 MacroRules(MacroRulesScopeRef<'ra>),
119 CrateRoot,
120 Module(Module<'ra>, Option<NodeId>),
123 MacroUsePrelude,
124 BuiltinAttrs,
125 ExternPrelude,
126 ToolPrelude,
127 StdLibPrelude,
128 BuiltinTypes,
129}
130
131#[derive(Clone, Copy, Debug)]
136enum ScopeSet<'ra> {
137 All(Namespace),
139 AbsolutePath(Namespace),
141 Macro(MacroKind),
143 Late(Namespace, Module<'ra>, Option<NodeId>),
146}
147
148#[derive(Clone, Copy, Debug)]
153struct ParentScope<'ra> {
154 module: Module<'ra>,
155 expansion: LocalExpnId,
156 macro_rules: MacroRulesScopeRef<'ra>,
157 derives: &'ra [ast::Path],
158}
159
160impl<'ra> ParentScope<'ra> {
161 fn module(module: Module<'ra>, resolver: &Resolver<'ra, '_>) -> ParentScope<'ra> {
164 ParentScope {
165 module,
166 expansion: LocalExpnId::ROOT,
167 macro_rules: resolver.arenas.alloc_macro_rules_scope(MacroRulesScope::Empty),
168 derives: &[],
169 }
170 }
171}
172
173#[derive(Copy, Debug, Clone)]
174struct InvocationParent {
175 parent_def: LocalDefId,
176 impl_trait_context: ImplTraitContext,
177 in_attr: bool,
178}
179
180impl InvocationParent {
181 const ROOT: Self = Self {
182 parent_def: CRATE_DEF_ID,
183 impl_trait_context: ImplTraitContext::Existential,
184 in_attr: false,
185 };
186}
187
188#[derive(Copy, Debug, Clone)]
189enum ImplTraitContext {
190 Existential,
191 Universal,
192 InBinding,
193}
194
195#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
210enum Used {
211 Scope,
212 Other,
213}
214
215#[derive(Debug)]
216struct BindingError {
217 name: Ident,
218 origin: BTreeSet<Span>,
219 target: BTreeSet<Span>,
220 could_be_path: bool,
221}
222
223#[derive(Debug)]
224enum ResolutionError<'ra> {
225 GenericParamsFromOuterItem(Res, HasGenericParams, DefKind),
227 NameAlreadyUsedInParameterList(Ident, Span),
230 MethodNotMemberOfTrait(Ident, String, Option<Symbol>),
232 TypeNotMemberOfTrait(Ident, String, Option<Symbol>),
234 ConstNotMemberOfTrait(Ident, String, Option<Symbol>),
236 VariableNotBoundInPattern(BindingError, ParentScope<'ra>),
238 VariableBoundWithDifferentMode(Ident, Span),
240 IdentifierBoundMoreThanOnceInParameterList(Ident),
242 IdentifierBoundMoreThanOnceInSamePattern(Ident),
244 UndeclaredLabel { name: Symbol, suggestion: Option<LabelSuggestion> },
246 SelfImportsOnlyAllowedWithin { root: bool, span_with_rename: Span },
248 SelfImportCanOnlyAppearOnceInTheList,
250 SelfImportOnlyInImportListWithNonEmptyPrefix,
252 FailedToResolve {
254 segment: Option<Symbol>,
255 label: String,
256 suggestion: Option<Suggestion>,
257 module: Option<ModuleOrUniformRoot<'ra>>,
258 },
259 CannotCaptureDynamicEnvironmentInFnItem,
261 AttemptToUseNonConstantValueInConstant {
263 ident: Ident,
264 suggestion: &'static str,
265 current: &'static str,
266 type_span: Option<Span>,
267 },
268 BindingShadowsSomethingUnacceptable {
270 shadowing_binding: PatternSource,
271 name: Symbol,
272 participle: &'static str,
273 article: &'static str,
274 shadowed_binding: Res,
275 shadowed_binding_span: Span,
276 },
277 ForwardDeclaredGenericParam(Symbol, ForwardGenericParamBanReason),
279 ParamInTyOfConstParam { name: Symbol },
283 ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst },
287 ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
291 ForwardDeclaredSelf(ForwardGenericParamBanReason),
293 UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> },
295 TraitImplMismatch {
297 name: Ident,
298 kind: &'static str,
299 trait_path: String,
300 trait_item_span: Span,
301 code: ErrCode,
302 },
303 TraitImplDuplicate { name: Ident, trait_item_span: Span, old_span: Span },
305 InvalidAsmSym,
307 LowercaseSelf,
309 BindingInNeverPattern,
311}
312
313enum VisResolutionError<'a> {
314 Relative2018(Span, &'a ast::Path),
315 AncestorOnly(Span),
316 FailedToResolve(Span, String, Option<Suggestion>),
317 ExpectedFound(Span, String, Res),
318 Indeterminate(Span),
319 ModuleOnly(Span),
320}
321
322#[derive(Clone, Copy, Debug)]
325struct Segment {
326 ident: Ident,
327 id: Option<NodeId>,
328 has_generic_args: bool,
331 has_lifetime_args: bool,
333 args_span: Span,
334}
335
336impl Segment {
337 fn from_path(path: &Path) -> Vec<Segment> {
338 path.segments.iter().map(|s| s.into()).collect()
339 }
340
341 fn from_ident(ident: Ident) -> Segment {
342 Segment {
343 ident,
344 id: None,
345 has_generic_args: false,
346 has_lifetime_args: false,
347 args_span: DUMMY_SP,
348 }
349 }
350
351 fn from_ident_and_id(ident: Ident, id: NodeId) -> Segment {
352 Segment {
353 ident,
354 id: Some(id),
355 has_generic_args: false,
356 has_lifetime_args: false,
357 args_span: DUMMY_SP,
358 }
359 }
360
361 fn names_to_string(segments: &[Segment]) -> String {
362 names_to_string(segments.iter().map(|seg| seg.ident.name))
363 }
364}
365
366impl<'a> From<&'a ast::PathSegment> for Segment {
367 fn from(seg: &'a ast::PathSegment) -> Segment {
368 let has_generic_args = seg.args.is_some();
369 let (args_span, has_lifetime_args) = if let Some(args) = seg.args.as_deref() {
370 match args {
371 GenericArgs::AngleBracketed(args) => {
372 let found_lifetimes = args
373 .args
374 .iter()
375 .any(|arg| matches!(arg, AngleBracketedArg::Arg(GenericArg::Lifetime(_))));
376 (args.span, found_lifetimes)
377 }
378 GenericArgs::Parenthesized(args) => (args.span, true),
379 GenericArgs::ParenthesizedElided(span) => (*span, true),
380 }
381 } else {
382 (DUMMY_SP, false)
383 };
384 Segment {
385 ident: seg.ident,
386 id: Some(seg.id),
387 has_generic_args,
388 has_lifetime_args,
389 args_span,
390 }
391 }
392}
393
394#[derive(Debug, Copy, Clone)]
400enum LexicalScopeBinding<'ra> {
401 Item(NameBinding<'ra>),
402 Res(Res),
403}
404
405impl<'ra> LexicalScopeBinding<'ra> {
406 fn res(self) -> Res {
407 match self {
408 LexicalScopeBinding::Item(binding) => binding.res(),
409 LexicalScopeBinding::Res(res) => res,
410 }
411 }
412}
413
414#[derive(Copy, Clone, PartialEq, Debug)]
415enum ModuleOrUniformRoot<'ra> {
416 Module(Module<'ra>),
418
419 CrateRootAndExternPrelude,
421
422 ExternPrelude,
425
426 CurrentScope,
430}
431
432#[derive(Debug)]
433enum PathResult<'ra> {
434 Module(ModuleOrUniformRoot<'ra>),
435 NonModule(PartialRes),
436 Indeterminate,
437 Failed {
438 span: Span,
439 label: String,
440 suggestion: Option<Suggestion>,
441 is_error_from_last_segment: bool,
442 module: Option<ModuleOrUniformRoot<'ra>>,
456 segment_name: Symbol,
458 error_implied_by_parse_error: bool,
459 },
460}
461
462impl<'ra> PathResult<'ra> {
463 fn failed(
464 ident: Ident,
465 is_error_from_last_segment: bool,
466 finalize: bool,
467 error_implied_by_parse_error: bool,
468 module: Option<ModuleOrUniformRoot<'ra>>,
469 label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>),
470 ) -> PathResult<'ra> {
471 let (label, suggestion) =
472 if finalize { label_and_suggestion() } else { (String::new(), None) };
473 PathResult::Failed {
474 span: ident.span,
475 segment_name: ident.name,
476 label,
477 suggestion,
478 is_error_from_last_segment,
479 module,
480 error_implied_by_parse_error,
481 }
482 }
483}
484
485#[derive(Debug)]
486enum ModuleKind {
487 Block,
500 Def(DefKind, DefId, Symbol),
510}
511
512impl ModuleKind {
513 fn name(&self) -> Option<Symbol> {
515 match self {
516 ModuleKind::Block => None,
517 ModuleKind::Def(.., name) => Some(*name),
518 }
519 }
520}
521
522#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
527struct BindingKey {
528 ident: Ident,
531 ns: Namespace,
532 disambiguator: u32,
535}
536
537impl BindingKey {
538 fn new(ident: Ident, ns: Namespace) -> Self {
539 let ident = ident.normalize_to_macros_2_0();
540 BindingKey { ident, ns, disambiguator: 0 }
541 }
542}
543
544type Resolutions<'ra> = RefCell<FxIndexMap<BindingKey, &'ra RefCell<NameResolution<'ra>>>>;
545
546struct ModuleData<'ra> {
558 parent: Option<Module<'ra>>,
560 kind: ModuleKind,
562
563 lazy_resolutions: Resolutions<'ra>,
566 populate_on_access: Cell<bool>,
568
569 unexpanded_invocations: RefCell<FxHashSet<LocalExpnId>>,
571
572 no_implicit_prelude: bool,
574
575 glob_importers: RefCell<Vec<Import<'ra>>>,
576 globs: RefCell<Vec<Import<'ra>>>,
577
578 traits: RefCell<Option<Box<[(Ident, NameBinding<'ra>)]>>>,
580
581 span: Span,
583
584 expansion: ExpnId,
585}
586
587#[derive(Clone, Copy, PartialEq, Eq, Hash)]
590#[rustc_pass_by_value]
591struct Module<'ra>(Interned<'ra, ModuleData<'ra>>);
592
593impl std::hash::Hash for ModuleData<'_> {
598 fn hash<H>(&self, _: &mut H)
599 where
600 H: std::hash::Hasher,
601 {
602 unreachable!()
603 }
604}
605
606impl<'ra> ModuleData<'ra> {
607 fn new(
608 parent: Option<Module<'ra>>,
609 kind: ModuleKind,
610 expansion: ExpnId,
611 span: Span,
612 no_implicit_prelude: bool,
613 ) -> Self {
614 let is_foreign = match kind {
615 ModuleKind::Def(_, def_id, _) => !def_id.is_local(),
616 ModuleKind::Block => false,
617 };
618 ModuleData {
619 parent,
620 kind,
621 lazy_resolutions: Default::default(),
622 populate_on_access: Cell::new(is_foreign),
623 unexpanded_invocations: Default::default(),
624 no_implicit_prelude,
625 glob_importers: RefCell::new(Vec::new()),
626 globs: RefCell::new(Vec::new()),
627 traits: RefCell::new(None),
628 span,
629 expansion,
630 }
631 }
632}
633
634impl<'ra> Module<'ra> {
635 fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F)
636 where
637 R: AsMut<Resolver<'ra, 'tcx>>,
638 F: FnMut(&mut R, Ident, Namespace, NameBinding<'ra>),
639 {
640 for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
641 if let Some(binding) = name_resolution.borrow().binding {
642 f(resolver, key.ident, key.ns, binding);
643 }
644 }
645 }
646
647 fn ensure_traits<'tcx, R>(self, resolver: &mut R)
649 where
650 R: AsMut<Resolver<'ra, 'tcx>>,
651 {
652 let mut traits = self.traits.borrow_mut();
653 if traits.is_none() {
654 let mut collected_traits = Vec::new();
655 self.for_each_child(resolver, |_, name, ns, binding| {
656 if ns != TypeNS {
657 return;
658 }
659 if let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = binding.res() {
660 collected_traits.push((name, binding))
661 }
662 });
663 *traits = Some(collected_traits.into_boxed_slice());
664 }
665 }
666
667 fn res(self) -> Option<Res> {
668 match self.kind {
669 ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)),
670 _ => None,
671 }
672 }
673
674 fn def_id(self) -> DefId {
676 self.opt_def_id().expect("`ModuleData::def_id` is called on a block module")
677 }
678
679 fn opt_def_id(self) -> Option<DefId> {
680 match self.kind {
681 ModuleKind::Def(_, def_id, _) => Some(def_id),
682 _ => None,
683 }
684 }
685
686 fn is_normal(self) -> bool {
688 matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _))
689 }
690
691 fn is_trait(self) -> bool {
692 matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _))
693 }
694
695 fn nearest_item_scope(self) -> Module<'ra> {
696 match self.kind {
697 ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => {
698 self.parent.expect("enum or trait module without a parent")
699 }
700 _ => self,
701 }
702 }
703
704 fn nearest_parent_mod(self) -> DefId {
707 match self.kind {
708 ModuleKind::Def(DefKind::Mod, def_id, _) => def_id,
709 _ => self.parent.expect("non-root module without parent").nearest_parent_mod(),
710 }
711 }
712
713 fn is_ancestor_of(self, mut other: Self) -> bool {
714 while self != other {
715 if let Some(parent) = other.parent {
716 other = parent;
717 } else {
718 return false;
719 }
720 }
721 true
722 }
723}
724
725impl<'ra> std::ops::Deref for Module<'ra> {
726 type Target = ModuleData<'ra>;
727
728 fn deref(&self) -> &Self::Target {
729 &self.0
730 }
731}
732
733impl<'ra> fmt::Debug for Module<'ra> {
734 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
735 write!(f, "{:?}", self.res())
736 }
737}
738
739#[derive(Clone, Copy, Debug)]
741struct NameBindingData<'ra> {
742 kind: NameBindingKind<'ra>,
743 ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>,
744 warn_ambiguity: bool,
747 expansion: LocalExpnId,
748 span: Span,
749 vis: ty::Visibility<DefId>,
750}
751
752type NameBinding<'ra> = Interned<'ra, NameBindingData<'ra>>;
755
756impl std::hash::Hash for NameBindingData<'_> {
761 fn hash<H>(&self, _: &mut H)
762 where
763 H: std::hash::Hasher,
764 {
765 unreachable!()
766 }
767}
768
769trait ToNameBinding<'ra> {
770 fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra>;
771}
772
773impl<'ra> ToNameBinding<'ra> for NameBinding<'ra> {
774 fn to_name_binding(self, _: &'ra ResolverArenas<'ra>) -> NameBinding<'ra> {
775 self
776 }
777}
778
779#[derive(Clone, Copy, Debug)]
780enum NameBindingKind<'ra> {
781 Res(Res),
782 Module(Module<'ra>),
783 Import { binding: NameBinding<'ra>, import: Import<'ra> },
784}
785
786impl<'ra> NameBindingKind<'ra> {
787 fn is_import(&self) -> bool {
789 matches!(*self, NameBindingKind::Import { .. })
790 }
791}
792
793#[derive(Debug)]
794struct PrivacyError<'ra> {
795 ident: Ident,
796 binding: NameBinding<'ra>,
797 dedup_span: Span,
798 outermost_res: Option<(Res, Ident)>,
799 parent_scope: ParentScope<'ra>,
800 single_nested: bool,
802}
803
804#[derive(Debug)]
805struct UseError<'a> {
806 err: Diag<'a>,
807 candidates: Vec<ImportSuggestion>,
809 def_id: DefId,
811 instead: bool,
813 suggestion: Option<(Span, &'static str, String, Applicability)>,
815 path: Vec<Segment>,
818 is_call: bool,
820}
821
822#[derive(Clone, Copy, PartialEq, Debug)]
823enum AmbiguityKind {
824 BuiltinAttr,
825 DeriveHelper,
826 MacroRulesVsModularized,
827 GlobVsOuter,
828 GlobVsGlob,
829 GlobVsExpanded,
830 MoreExpandedVsOuter,
831}
832
833impl AmbiguityKind {
834 fn descr(self) -> &'static str {
835 match self {
836 AmbiguityKind::BuiltinAttr => "a name conflict with a builtin attribute",
837 AmbiguityKind::DeriveHelper => "a name conflict with a derive helper attribute",
838 AmbiguityKind::MacroRulesVsModularized => {
839 "a conflict between a `macro_rules` name and a non-`macro_rules` name from another module"
840 }
841 AmbiguityKind::GlobVsOuter => {
842 "a conflict between a name from a glob import and an outer scope during import or macro resolution"
843 }
844 AmbiguityKind::GlobVsGlob => "multiple glob imports of a name in the same module",
845 AmbiguityKind::GlobVsExpanded => {
846 "a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution"
847 }
848 AmbiguityKind::MoreExpandedVsOuter => {
849 "a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution"
850 }
851 }
852 }
853}
854
855#[derive(Clone, Copy, PartialEq)]
857enum AmbiguityErrorMisc {
858 SuggestCrate,
859 SuggestSelf,
860 FromPrelude,
861 None,
862}
863
864struct AmbiguityError<'ra> {
865 kind: AmbiguityKind,
866 ident: Ident,
867 b1: NameBinding<'ra>,
868 b2: NameBinding<'ra>,
869 misc1: AmbiguityErrorMisc,
870 misc2: AmbiguityErrorMisc,
871 warning: bool,
872}
873
874impl<'ra> NameBindingData<'ra> {
875 fn module(&self) -> Option<Module<'ra>> {
876 match self.kind {
877 NameBindingKind::Module(module) => Some(module),
878 NameBindingKind::Import { binding, .. } => binding.module(),
879 _ => None,
880 }
881 }
882
883 fn res(&self) -> Res {
884 match self.kind {
885 NameBindingKind::Res(res) => res,
886 NameBindingKind::Module(module) => module.res().unwrap(),
887 NameBindingKind::Import { binding, .. } => binding.res(),
888 }
889 }
890
891 fn is_ambiguity_recursive(&self) -> bool {
892 self.ambiguity.is_some()
893 || match self.kind {
894 NameBindingKind::Import { binding, .. } => binding.is_ambiguity_recursive(),
895 _ => false,
896 }
897 }
898
899 fn warn_ambiguity_recursive(&self) -> bool {
900 self.warn_ambiguity
901 || match self.kind {
902 NameBindingKind::Import { binding, .. } => binding.warn_ambiguity_recursive(),
903 _ => false,
904 }
905 }
906
907 fn is_possibly_imported_variant(&self) -> bool {
908 match self.kind {
909 NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(),
910 NameBindingKind::Res(Res::Def(
911 DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..),
912 _,
913 )) => true,
914 NameBindingKind::Res(..) | NameBindingKind::Module(..) => false,
915 }
916 }
917
918 fn is_extern_crate(&self) -> bool {
919 match self.kind {
920 NameBindingKind::Import { import, .. } => {
921 matches!(import.kind, ImportKind::ExternCrate { .. })
922 }
923 NameBindingKind::Module(module)
924 if let ModuleKind::Def(DefKind::Mod, def_id, _) = module.kind =>
925 {
926 def_id.is_crate_root()
927 }
928 _ => false,
929 }
930 }
931
932 fn is_import(&self) -> bool {
933 matches!(self.kind, NameBindingKind::Import { .. })
934 }
935
936 fn is_import_user_facing(&self) -> bool {
939 matches!(self.kind, NameBindingKind::Import { import, .. }
940 if !matches!(import.kind, ImportKind::MacroExport))
941 }
942
943 fn is_glob_import(&self) -> bool {
944 match self.kind {
945 NameBindingKind::Import { import, .. } => import.is_glob(),
946 _ => false,
947 }
948 }
949
950 fn is_importable(&self) -> bool {
951 !matches!(self.res(), Res::Def(DefKind::AssocTy, _))
952 }
953
954 fn is_assoc_const_or_fn(&self) -> bool {
957 matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _))
958 }
959
960 fn macro_kind(&self) -> Option<MacroKind> {
961 self.res().macro_kind()
962 }
963
964 fn may_appear_after(
971 &self,
972 invoc_parent_expansion: LocalExpnId,
973 binding: NameBinding<'_>,
974 ) -> bool {
975 let self_parent_expansion = self.expansion;
979 let other_parent_expansion = binding.expansion;
980 let certainly_before_other_or_simultaneously =
981 other_parent_expansion.is_descendant_of(self_parent_expansion);
982 let certainly_before_invoc_or_simultaneously =
983 invoc_parent_expansion.is_descendant_of(self_parent_expansion);
984 !(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously)
985 }
986
987 fn determined(&self) -> bool {
991 match &self.kind {
992 NameBindingKind::Import { binding, import, .. } if import.is_glob() => {
993 import.parent_scope.module.unexpanded_invocations.borrow().is_empty()
994 && binding.determined()
995 }
996 _ => true,
997 }
998 }
999}
1000
1001#[derive(Default, Clone)]
1002struct ExternPreludeEntry<'ra> {
1003 binding: Option<NameBinding<'ra>>,
1004 introduced_by_item: bool,
1005}
1006
1007impl ExternPreludeEntry<'_> {
1008 fn is_import(&self) -> bool {
1009 self.binding.is_some_and(|binding| binding.is_import())
1010 }
1011}
1012
1013enum BuiltinMacroState {
1015 NotYetSeen(SyntaxExtensionKind),
1016 AlreadySeen(Span),
1017}
1018
1019struct DeriveData {
1020 resolutions: Vec<DeriveResolution>,
1021 helper_attrs: Vec<(usize, Ident)>,
1022 has_derive_copy: bool,
1023}
1024
1025struct MacroData {
1026 ext: Arc<SyntaxExtension>,
1027 rule_spans: Vec<(usize, Span)>,
1028 macro_rules: bool,
1029}
1030
1031impl MacroData {
1032 fn new(ext: Arc<SyntaxExtension>) -> MacroData {
1033 MacroData { ext, rule_spans: Vec::new(), macro_rules: false }
1034 }
1035}
1036
1037pub struct Resolver<'ra, 'tcx> {
1041 tcx: TyCtxt<'tcx>,
1042
1043 expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
1045
1046 graph_root: Module<'ra>,
1047
1048 prelude: Option<Module<'ra>>,
1049 extern_prelude: FxIndexMap<Ident, ExternPreludeEntry<'ra>>,
1050
1051 field_names: LocalDefIdMap<Vec<Ident>>,
1053
1054 field_visibility_spans: FxHashMap<DefId, Vec<Span>>,
1057
1058 determined_imports: Vec<Import<'ra>>,
1060
1061 indeterminate_imports: Vec<Import<'ra>>,
1063
1064 pat_span_map: NodeMap<Span>,
1067
1068 partial_res_map: NodeMap<PartialRes>,
1070 import_res_map: NodeMap<PerNS<Option<Res>>>,
1072 import_use_map: FxHashMap<Import<'ra>, Used>,
1074 label_res_map: NodeMap<NodeId>,
1076 lifetimes_res_map: NodeMap<LifetimeRes>,
1078 extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>,
1080
1081 extern_crate_map: UnordMap<LocalDefId, CrateNum>,
1083 module_children: LocalDefIdMap<Vec<ModChild>>,
1084 trait_map: NodeMap<Vec<TraitCandidate>>,
1085
1086 block_map: NodeMap<Module<'ra>>,
1101 empty_module: Module<'ra>,
1105 module_map: FxIndexMap<DefId, Module<'ra>>,
1106 binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
1107
1108 underscore_disambiguator: u32,
1109
1110 glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
1112 glob_error: Option<ErrorGuaranteed>,
1113 visibilities_for_hashing: Vec<(LocalDefId, ty::Visibility)>,
1114 used_imports: FxHashSet<NodeId>,
1115 maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
1116
1117 privacy_errors: Vec<PrivacyError<'ra>>,
1119 ambiguity_errors: Vec<AmbiguityError<'ra>>,
1121 use_injections: Vec<UseError<'tcx>>,
1123 macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
1125
1126 arenas: &'ra ResolverArenas<'ra>,
1127 dummy_binding: NameBinding<'ra>,
1128 builtin_types_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
1129 builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
1130 registered_tool_bindings: FxHashMap<Ident, NameBinding<'ra>>,
1131 module_self_bindings: FxHashMap<Module<'ra>, NameBinding<'ra>>,
1134
1135 used_extern_options: FxHashSet<Symbol>,
1136 macro_names: FxHashSet<Ident>,
1137 builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
1138 registered_tools: &'tcx RegisteredTools,
1139 macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>,
1140 macro_map: FxHashMap<DefId, MacroData>,
1141 dummy_ext_bang: Arc<SyntaxExtension>,
1142 dummy_ext_derive: Arc<SyntaxExtension>,
1143 non_macro_attr: MacroData,
1144 local_macro_def_scopes: FxHashMap<LocalDefId, Module<'ra>>,
1145 ast_transform_scopes: FxHashMap<LocalExpnId, Module<'ra>>,
1146 unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>,
1147 unused_macro_rules: FxIndexMap<LocalDefId, UnordMap<usize, (Ident, Span)>>,
1149 proc_macro_stubs: FxHashSet<LocalDefId>,
1150 single_segment_macro_resolutions:
1152 Vec<(Ident, MacroKind, ParentScope<'ra>, Option<NameBinding<'ra>>)>,
1153 multi_segment_macro_resolutions:
1154 Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'ra>, Option<Res>, Namespace)>,
1155 builtin_attrs: Vec<(Ident, ParentScope<'ra>)>,
1156 containers_deriving_copy: FxHashSet<LocalExpnId>,
1160 invocation_parent_scopes: FxHashMap<LocalExpnId, ParentScope<'ra>>,
1163 output_macro_rules_scopes: FxHashMap<LocalExpnId, MacroRulesScopeRef<'ra>>,
1166 macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'ra>>,
1168 helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'ra>)>>,
1170 derive_data: FxHashMap<LocalExpnId, DeriveData>,
1173
1174 name_already_seen: FxHashMap<Symbol, Span>,
1176
1177 potentially_unused_imports: Vec<Import<'ra>>,
1178
1179 potentially_unnecessary_qualifications: Vec<UnnecessaryQualification<'ra>>,
1180
1181 struct_constructors: LocalDefIdMap<(Res, ty::Visibility<DefId>, Vec<ty::Visibility<DefId>>)>,
1185
1186 lint_buffer: LintBuffer,
1187
1188 next_node_id: NodeId,
1189
1190 node_id_to_def_id: NodeMap<Feed<'tcx, LocalDefId>>,
1191 def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
1192
1193 placeholder_field_indices: FxHashMap<NodeId, usize>,
1195 invocation_parents: FxHashMap<LocalExpnId, InvocationParent>,
1199
1200 trait_impl_items: FxHashSet<LocalDefId>,
1203
1204 legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
1205 item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
1207 delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
1208
1209 main_def: Option<MainDefinition>,
1210 trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
1211 proc_macros: Vec<NodeId>,
1214 confused_type_with_std_module: FxIndexMap<Span, Span>,
1215 lifetime_elision_allowed: FxHashSet<NodeId>,
1217
1218 stripped_cfg_items: Vec<StrippedCfgItem<NodeId>>,
1220
1221 effective_visibilities: EffectiveVisibilities,
1222 doc_link_resolutions: FxIndexMap<LocalDefId, DocLinkResMap>,
1223 doc_link_traits_in_scope: FxIndexMap<LocalDefId, Vec<DefId>>,
1224 all_macro_rules: FxHashSet<Symbol>,
1225
1226 glob_delegation_invoc_ids: FxHashSet<LocalExpnId>,
1228 impl_unexpanded_invocations: FxHashMap<LocalDefId, FxHashSet<LocalExpnId>>,
1231 impl_binding_keys: FxHashMap<LocalDefId, FxHashSet<BindingKey>>,
1234
1235 current_crate_outer_attr_insert_span: Span,
1238
1239 mods_with_parse_errors: FxHashSet<DefId>,
1240}
1241
1242#[derive(Default)]
1245pub struct ResolverArenas<'ra> {
1246 modules: TypedArena<ModuleData<'ra>>,
1247 local_modules: RefCell<Vec<Module<'ra>>>,
1248 imports: TypedArena<ImportData<'ra>>,
1249 name_resolutions: TypedArena<RefCell<NameResolution<'ra>>>,
1250 ast_paths: TypedArena<ast::Path>,
1251 dropless: DroplessArena,
1252}
1253
1254impl<'ra> ResolverArenas<'ra> {
1255 fn new_module(
1256 &'ra self,
1257 parent: Option<Module<'ra>>,
1258 kind: ModuleKind,
1259 expn_id: ExpnId,
1260 span: Span,
1261 no_implicit_prelude: bool,
1262 module_map: &mut FxIndexMap<DefId, Module<'ra>>,
1263 module_self_bindings: &mut FxHashMap<Module<'ra>, NameBinding<'ra>>,
1264 ) -> Module<'ra> {
1265 let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new(
1266 parent,
1267 kind,
1268 expn_id,
1269 span,
1270 no_implicit_prelude,
1271 ))));
1272 let def_id = module.opt_def_id();
1273 if def_id.is_none_or(|def_id| def_id.is_local()) {
1274 self.local_modules.borrow_mut().push(module);
1275 }
1276 if let Some(def_id) = def_id {
1277 module_map.insert(def_id, module);
1278 let vis = ty::Visibility::<DefId>::Public;
1279 let binding = (module, vis, module.span, LocalExpnId::ROOT).to_name_binding(self);
1280 module_self_bindings.insert(module, binding);
1281 }
1282 module
1283 }
1284 fn local_modules(&'ra self) -> std::cell::Ref<'ra, Vec<Module<'ra>>> {
1285 self.local_modules.borrow()
1286 }
1287 fn alloc_name_binding(&'ra self, name_binding: NameBindingData<'ra>) -> NameBinding<'ra> {
1288 Interned::new_unchecked(self.dropless.alloc(name_binding))
1289 }
1290 fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> {
1291 Interned::new_unchecked(self.imports.alloc(import))
1292 }
1293 fn alloc_name_resolution(&'ra self) -> &'ra RefCell<NameResolution<'ra>> {
1294 self.name_resolutions.alloc(Default::default())
1295 }
1296 fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> {
1297 Interned::new_unchecked(self.dropless.alloc(Cell::new(scope)))
1298 }
1299 fn alloc_macro_rules_binding(
1300 &'ra self,
1301 binding: MacroRulesBinding<'ra>,
1302 ) -> &'ra MacroRulesBinding<'ra> {
1303 self.dropless.alloc(binding)
1304 }
1305 fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] {
1306 self.ast_paths.alloc_from_iter(paths.iter().cloned())
1307 }
1308 fn alloc_pattern_spans(&'ra self, spans: impl Iterator<Item = Span>) -> &'ra [Span] {
1309 self.dropless.alloc_from_iter(spans)
1310 }
1311}
1312
1313impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for Resolver<'ra, 'tcx> {
1314 fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
1315 self
1316 }
1317}
1318
1319impl<'tcx> Resolver<'_, 'tcx> {
1320 fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
1321 self.opt_feed(node).map(|f| f.key())
1322 }
1323
1324 fn local_def_id(&self, node: NodeId) -> LocalDefId {
1325 self.feed(node).key()
1326 }
1327
1328 fn opt_feed(&self, node: NodeId) -> Option<Feed<'tcx, LocalDefId>> {
1329 self.node_id_to_def_id.get(&node).copied()
1330 }
1331
1332 fn feed(&self, node: NodeId) -> Feed<'tcx, LocalDefId> {
1333 self.opt_feed(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
1334 }
1335
1336 fn local_def_kind(&self, node: NodeId) -> DefKind {
1337 self.tcx.def_kind(self.local_def_id(node))
1338 }
1339
1340 fn create_def(
1342 &mut self,
1343 parent: LocalDefId,
1344 node_id: ast::NodeId,
1345 name: Option<Symbol>,
1346 def_kind: DefKind,
1347 expn_id: ExpnId,
1348 span: Span,
1349 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1350 let data = def_kind.def_path_data(name);
1351 assert!(
1352 !self.node_id_to_def_id.contains_key(&node_id),
1353 "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
1354 node_id,
1355 data,
1356 self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id].key()),
1357 );
1358
1359 let feed = self.tcx.create_def(parent, name, def_kind);
1361 let def_id = feed.def_id();
1362
1363 if expn_id != ExpnId::root() {
1365 self.expn_that_defined.insert(def_id, expn_id);
1366 }
1367
1368 debug_assert_eq!(span.data_untracked().parent, None);
1370 let _id = self.tcx.untracked().source_span.push(span);
1371 debug_assert_eq!(_id, def_id);
1372
1373 if node_id != ast::DUMMY_NODE_ID {
1377 debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
1378 self.node_id_to_def_id.insert(node_id, feed.downgrade());
1379 }
1380 assert_eq!(self.def_id_to_node_id.push(node_id), def_id);
1381
1382 feed
1383 }
1384
1385 fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize {
1386 if let Some(def_id) = def_id.as_local() {
1387 self.item_generics_num_lifetimes[&def_id]
1388 } else {
1389 self.tcx.generics_of(def_id).own_counts().lifetimes
1390 }
1391 }
1392
1393 pub fn tcx(&self) -> TyCtxt<'tcx> {
1394 self.tcx
1395 }
1396}
1397
1398impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1399 pub fn new(
1400 tcx: TyCtxt<'tcx>,
1401 attrs: &[ast::Attribute],
1402 crate_span: Span,
1403 current_crate_outer_attr_insert_span: Span,
1404 arenas: &'ra ResolverArenas<'ra>,
1405 ) -> Resolver<'ra, 'tcx> {
1406 let root_def_id = CRATE_DEF_ID.to_def_id();
1407 let mut module_map = FxIndexMap::default();
1408 let mut module_self_bindings = FxHashMap::default();
1409 let graph_root = arenas.new_module(
1410 None,
1411 ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
1412 ExpnId::root(),
1413 crate_span,
1414 attr::contains_name(attrs, sym::no_implicit_prelude),
1415 &mut module_map,
1416 &mut module_self_bindings,
1417 );
1418 let empty_module = arenas.new_module(
1419 None,
1420 ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
1421 ExpnId::root(),
1422 DUMMY_SP,
1423 true,
1424 &mut Default::default(),
1425 &mut Default::default(),
1426 );
1427
1428 let mut def_id_to_node_id = IndexVec::default();
1429 assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID);
1430 let mut node_id_to_def_id = NodeMap::default();
1431 let crate_feed = tcx.create_local_crate_def_id(crate_span);
1432
1433 crate_feed.def_kind(DefKind::Mod);
1434 let crate_feed = crate_feed.downgrade();
1435 node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed);
1436
1437 let mut invocation_parents = FxHashMap::default();
1438 invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT);
1439
1440 let mut extern_prelude: FxIndexMap<Ident, ExternPreludeEntry<'_>> = tcx
1441 .sess
1442 .opts
1443 .externs
1444 .iter()
1445 .filter(|(_, entry)| entry.add_prelude)
1446 .map(|(name, _)| (Ident::from_str(name), Default::default()))
1447 .collect();
1448
1449 if !attr::contains_name(attrs, sym::no_core) {
1450 extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
1451 if !attr::contains_name(attrs, sym::no_std) {
1452 extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default());
1453 }
1454 }
1455
1456 let registered_tools = tcx.registered_tools(());
1457
1458 let pub_vis = ty::Visibility::<DefId>::Public;
1459 let edition = tcx.sess.edition();
1460
1461 let mut resolver = Resolver {
1462 tcx,
1463
1464 expn_that_defined: Default::default(),
1465
1466 graph_root,
1469 prelude: None,
1470 extern_prelude,
1471
1472 field_names: Default::default(),
1473 field_visibility_spans: FxHashMap::default(),
1474
1475 determined_imports: Vec::new(),
1476 indeterminate_imports: Vec::new(),
1477
1478 pat_span_map: Default::default(),
1479 partial_res_map: Default::default(),
1480 import_res_map: Default::default(),
1481 import_use_map: Default::default(),
1482 label_res_map: Default::default(),
1483 lifetimes_res_map: Default::default(),
1484 extra_lifetime_params_map: Default::default(),
1485 extern_crate_map: Default::default(),
1486 module_children: Default::default(),
1487 trait_map: NodeMap::default(),
1488 underscore_disambiguator: 0,
1489 empty_module,
1490 module_map,
1491 block_map: Default::default(),
1492 binding_parent_modules: FxHashMap::default(),
1493 ast_transform_scopes: FxHashMap::default(),
1494
1495 glob_map: Default::default(),
1496 glob_error: None,
1497 visibilities_for_hashing: Default::default(),
1498 used_imports: FxHashSet::default(),
1499 maybe_unused_trait_imports: Default::default(),
1500
1501 privacy_errors: Vec::new(),
1502 ambiguity_errors: Vec::new(),
1503 use_injections: Vec::new(),
1504 macro_expanded_macro_export_errors: BTreeSet::new(),
1505
1506 arenas,
1507 dummy_binding: (Res::Err, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas),
1508 builtin_types_bindings: PrimTy::ALL
1509 .iter()
1510 .map(|prim_ty| {
1511 let binding = (Res::PrimTy(*prim_ty), pub_vis, DUMMY_SP, LocalExpnId::ROOT)
1512 .to_name_binding(arenas);
1513 (prim_ty.name(), binding)
1514 })
1515 .collect(),
1516 builtin_attrs_bindings: BUILTIN_ATTRIBUTES
1517 .iter()
1518 .map(|builtin_attr| {
1519 let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(builtin_attr.name));
1520 let binding =
1521 (res, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas);
1522 (builtin_attr.name, binding)
1523 })
1524 .collect(),
1525 registered_tool_bindings: registered_tools
1526 .iter()
1527 .map(|ident| {
1528 let binding = (Res::ToolMod, pub_vis, ident.span, LocalExpnId::ROOT)
1529 .to_name_binding(arenas);
1530 (*ident, binding)
1531 })
1532 .collect(),
1533 module_self_bindings,
1534
1535 used_extern_options: Default::default(),
1536 macro_names: FxHashSet::default(),
1537 builtin_macros: Default::default(),
1538 registered_tools,
1539 macro_use_prelude: Default::default(),
1540 macro_map: FxHashMap::default(),
1541 dummy_ext_bang: Arc::new(SyntaxExtension::dummy_bang(edition)),
1542 dummy_ext_derive: Arc::new(SyntaxExtension::dummy_derive(edition)),
1543 non_macro_attr: MacroData::new(Arc::new(SyntaxExtension::non_macro_attr(edition))),
1544 invocation_parent_scopes: Default::default(),
1545 output_macro_rules_scopes: Default::default(),
1546 macro_rules_scopes: Default::default(),
1547 helper_attrs: Default::default(),
1548 derive_data: Default::default(),
1549 local_macro_def_scopes: FxHashMap::default(),
1550 name_already_seen: FxHashMap::default(),
1551 potentially_unused_imports: Vec::new(),
1552 potentially_unnecessary_qualifications: Default::default(),
1553 struct_constructors: Default::default(),
1554 unused_macros: Default::default(),
1555 unused_macro_rules: Default::default(),
1556 proc_macro_stubs: Default::default(),
1557 single_segment_macro_resolutions: Default::default(),
1558 multi_segment_macro_resolutions: Default::default(),
1559 builtin_attrs: Default::default(),
1560 containers_deriving_copy: Default::default(),
1561 lint_buffer: LintBuffer::default(),
1562 next_node_id: CRATE_NODE_ID,
1563 node_id_to_def_id,
1564 def_id_to_node_id,
1565 placeholder_field_indices: Default::default(),
1566 invocation_parents,
1567 trait_impl_items: Default::default(),
1568 legacy_const_generic_args: Default::default(),
1569 item_generics_num_lifetimes: Default::default(),
1570 main_def: Default::default(),
1571 trait_impls: Default::default(),
1572 proc_macros: Default::default(),
1573 confused_type_with_std_module: Default::default(),
1574 lifetime_elision_allowed: Default::default(),
1575 stripped_cfg_items: Default::default(),
1576 effective_visibilities: Default::default(),
1577 doc_link_resolutions: Default::default(),
1578 doc_link_traits_in_scope: Default::default(),
1579 all_macro_rules: Default::default(),
1580 delegation_fn_sigs: Default::default(),
1581 glob_delegation_invoc_ids: Default::default(),
1582 impl_unexpanded_invocations: Default::default(),
1583 impl_binding_keys: Default::default(),
1584 current_crate_outer_attr_insert_span,
1585 mods_with_parse_errors: Default::default(),
1586 };
1587
1588 let root_parent_scope = ParentScope::module(graph_root, &resolver);
1589 resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope);
1590 resolver.feed_visibility(crate_feed, ty::Visibility::Public);
1591
1592 resolver
1593 }
1594
1595 fn new_module(
1596 &mut self,
1597 parent: Option<Module<'ra>>,
1598 kind: ModuleKind,
1599 expn_id: ExpnId,
1600 span: Span,
1601 no_implicit_prelude: bool,
1602 ) -> Module<'ra> {
1603 let module_map = &mut self.module_map;
1604 let module_self_bindings = &mut self.module_self_bindings;
1605 self.arenas.new_module(
1606 parent,
1607 kind,
1608 expn_id,
1609 span,
1610 no_implicit_prelude,
1611 module_map,
1612 module_self_bindings,
1613 )
1614 }
1615
1616 fn next_node_id(&mut self) -> NodeId {
1617 let start = self.next_node_id;
1618 let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
1619 self.next_node_id = ast::NodeId::from_u32(next);
1620 start
1621 }
1622
1623 fn next_node_ids(&mut self, count: usize) -> std::ops::Range<NodeId> {
1624 let start = self.next_node_id;
1625 let end = start.as_usize().checked_add(count).expect("input too large; ran out of NodeIds");
1626 self.next_node_id = ast::NodeId::from_usize(end);
1627 start..self.next_node_id
1628 }
1629
1630 pub fn lint_buffer(&mut self) -> &mut LintBuffer {
1631 &mut self.lint_buffer
1632 }
1633
1634 pub fn arenas() -> ResolverArenas<'ra> {
1635 Default::default()
1636 }
1637
1638 fn feed_visibility(&mut self, feed: Feed<'tcx, LocalDefId>, vis: ty::Visibility) {
1639 let feed = feed.upgrade(self.tcx);
1640 feed.visibility(vis.to_def_id());
1641 self.visibilities_for_hashing.push((feed.def_id(), vis));
1642 }
1643
1644 pub fn into_outputs(self) -> ResolverOutputs {
1645 let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
1646 let expn_that_defined = self.expn_that_defined;
1647 let extern_crate_map = self.extern_crate_map;
1648 let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
1649 let glob_map = self.glob_map;
1650 let main_def = self.main_def;
1651 let confused_type_with_std_module = self.confused_type_with_std_module;
1652 let effective_visibilities = self.effective_visibilities;
1653
1654 let stripped_cfg_items = Steal::new(
1655 self.stripped_cfg_items
1656 .into_iter()
1657 .filter_map(|item| {
1658 let parent_module =
1659 self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id();
1660 Some(StrippedCfgItem { parent_module, name: item.name, cfg: item.cfg })
1661 })
1662 .collect(),
1663 );
1664
1665 let global_ctxt = ResolverGlobalCtxt {
1666 expn_that_defined,
1667 visibilities_for_hashing: self.visibilities_for_hashing,
1668 effective_visibilities,
1669 extern_crate_map,
1670 module_children: self.module_children,
1671 glob_map,
1672 maybe_unused_trait_imports,
1673 main_def,
1674 trait_impls: self.trait_impls,
1675 proc_macros,
1676 confused_type_with_std_module,
1677 doc_link_resolutions: self.doc_link_resolutions,
1678 doc_link_traits_in_scope: self.doc_link_traits_in_scope,
1679 all_macro_rules: self.all_macro_rules,
1680 stripped_cfg_items,
1681 };
1682 let ast_lowering = ty::ResolverAstLowering {
1683 legacy_const_generic_args: self.legacy_const_generic_args,
1684 partial_res_map: self.partial_res_map,
1685 import_res_map: self.import_res_map,
1686 label_res_map: self.label_res_map,
1687 lifetimes_res_map: self.lifetimes_res_map,
1688 extra_lifetime_params_map: self.extra_lifetime_params_map,
1689 next_node_id: self.next_node_id,
1690 node_id_to_def_id: self
1691 .node_id_to_def_id
1692 .into_items()
1693 .map(|(k, f)| (k, f.key()))
1694 .collect(),
1695 trait_map: self.trait_map,
1696 lifetime_elision_allowed: self.lifetime_elision_allowed,
1697 lint_buffer: Steal::new(self.lint_buffer),
1698 delegation_fn_sigs: self.delegation_fn_sigs,
1699 };
1700 ResolverOutputs { global_ctxt, ast_lowering }
1701 }
1702
1703 fn create_stable_hashing_context(&self) -> StableHashingContext<'_> {
1704 StableHashingContext::new(self.tcx.sess, self.tcx.untracked())
1705 }
1706
1707 fn crate_loader<T>(&mut self, f: impl FnOnce(&mut CrateLoader<'_, '_>) -> T) -> T {
1708 f(&mut CrateLoader::new(
1709 self.tcx,
1710 &mut CStore::from_tcx_mut(self.tcx),
1711 &mut self.used_extern_options,
1712 ))
1713 }
1714
1715 fn cstore(&self) -> FreezeReadGuard<'_, CStore> {
1716 CStore::from_tcx(self.tcx)
1717 }
1718
1719 fn dummy_ext(&self, macro_kind: MacroKind) -> Arc<SyntaxExtension> {
1720 match macro_kind {
1721 MacroKind::Bang => Arc::clone(&self.dummy_ext_bang),
1722 MacroKind::Derive => Arc::clone(&self.dummy_ext_derive),
1723 MacroKind::Attr => Arc::clone(&self.non_macro_attr.ext),
1724 }
1725 }
1726
1727 fn per_ns<F: FnMut(&mut Self, Namespace)>(&mut self, mut f: F) {
1729 f(self, TypeNS);
1730 f(self, ValueNS);
1731 f(self, MacroNS);
1732 }
1733
1734 fn is_builtin_macro(&mut self, res: Res) -> bool {
1735 self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
1736 }
1737
1738 fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
1739 loop {
1740 match ctxt.outer_expn_data().macro_def_id {
1741 Some(def_id) => return def_id,
1742 None => ctxt.remove_mark(),
1743 };
1744 }
1745 }
1746
1747 pub fn resolve_crate(&mut self, krate: &Crate) {
1749 self.tcx.sess.time("resolve_crate", || {
1750 self.tcx.sess.time("finalize_imports", || self.finalize_imports());
1751 let exported_ambiguities = self.tcx.sess.time("compute_effective_visibilities", || {
1752 EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate)
1753 });
1754 self.tcx.sess.time("check_hidden_glob_reexports", || {
1755 self.check_hidden_glob_reexports(exported_ambiguities)
1756 });
1757 self.tcx
1758 .sess
1759 .time("finalize_macro_resolutions", || self.finalize_macro_resolutions(krate));
1760 self.tcx.sess.time("late_resolve_crate", || self.late_resolve_crate(krate));
1761 self.tcx.sess.time("resolve_main", || self.resolve_main());
1762 self.tcx.sess.time("resolve_check_unused", || self.check_unused(krate));
1763 self.tcx.sess.time("resolve_report_errors", || self.report_errors(krate));
1764 self.tcx
1765 .sess
1766 .time("resolve_postprocess", || self.crate_loader(|c| c.postprocess(krate)));
1767 });
1768
1769 self.tcx.untracked().cstore.freeze();
1771 }
1772
1773 fn traits_in_scope(
1774 &mut self,
1775 current_trait: Option<Module<'ra>>,
1776 parent_scope: &ParentScope<'ra>,
1777 ctxt: SyntaxContext,
1778 assoc_item: Option<(Symbol, Namespace)>,
1779 ) -> Vec<TraitCandidate> {
1780 let mut found_traits = Vec::new();
1781
1782 if let Some(module) = current_trait {
1783 if self.trait_may_have_item(Some(module), assoc_item) {
1784 let def_id = module.def_id();
1785 found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
1786 }
1787 }
1788
1789 self.visit_scopes(ScopeSet::All(TypeNS), parent_scope, ctxt, |this, scope, _, _| {
1790 match scope {
1791 Scope::Module(module, _) => {
1792 this.traits_in_module(module, assoc_item, &mut found_traits);
1793 }
1794 Scope::StdLibPrelude => {
1795 if let Some(module) = this.prelude {
1796 this.traits_in_module(module, assoc_item, &mut found_traits);
1797 }
1798 }
1799 Scope::ExternPrelude | Scope::ToolPrelude | Scope::BuiltinTypes => {}
1800 _ => unreachable!(),
1801 }
1802 None::<()>
1803 });
1804
1805 found_traits
1806 }
1807
1808 fn traits_in_module(
1809 &mut self,
1810 module: Module<'ra>,
1811 assoc_item: Option<(Symbol, Namespace)>,
1812 found_traits: &mut Vec<TraitCandidate>,
1813 ) {
1814 module.ensure_traits(self);
1815 let traits = module.traits.borrow();
1816 for (trait_name, trait_binding) in traits.as_ref().unwrap().iter() {
1817 if self.trait_may_have_item(trait_binding.module(), assoc_item) {
1818 let def_id = trait_binding.res().def_id();
1819 let import_ids = self.find_transitive_imports(&trait_binding.kind, *trait_name);
1820 found_traits.push(TraitCandidate { def_id, import_ids });
1821 }
1822 }
1823 }
1824
1825 fn trait_may_have_item(
1831 &mut self,
1832 trait_module: Option<Module<'ra>>,
1833 assoc_item: Option<(Symbol, Namespace)>,
1834 ) -> bool {
1835 match (trait_module, assoc_item) {
1836 (Some(trait_module), Some((name, ns))) => self
1837 .resolutions(trait_module)
1838 .borrow()
1839 .iter()
1840 .any(|(key, _name_resolution)| key.ns == ns && key.ident.name == name),
1841 _ => true,
1842 }
1843 }
1844
1845 fn find_transitive_imports(
1846 &mut self,
1847 mut kind: &NameBindingKind<'_>,
1848 trait_name: Ident,
1849 ) -> SmallVec<[LocalDefId; 1]> {
1850 let mut import_ids = smallvec![];
1851 while let NameBindingKind::Import { import, binding, .. } = kind {
1852 if let Some(node_id) = import.id() {
1853 let def_id = self.local_def_id(node_id);
1854 self.maybe_unused_trait_imports.insert(def_id);
1855 import_ids.push(def_id);
1856 }
1857 self.add_to_glob_map(*import, trait_name);
1858 kind = &binding.kind;
1859 }
1860 import_ids
1861 }
1862
1863 fn new_disambiguated_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
1864 let ident = ident.normalize_to_macros_2_0();
1865 let disambiguator = if ident.name == kw::Underscore {
1866 self.underscore_disambiguator += 1;
1867 self.underscore_disambiguator
1868 } else {
1869 0
1870 };
1871 BindingKey { ident, ns, disambiguator }
1872 }
1873
1874 fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> {
1875 if module.populate_on_access.get() {
1876 module.populate_on_access.set(false);
1877 self.build_reduced_graph_external(module);
1878 }
1879 &module.0.0.lazy_resolutions
1880 }
1881
1882 fn resolution(
1883 &mut self,
1884 module: Module<'ra>,
1885 key: BindingKey,
1886 ) -> &'ra RefCell<NameResolution<'ra>> {
1887 *self
1888 .resolutions(module)
1889 .borrow_mut()
1890 .entry(key)
1891 .or_insert_with(|| self.arenas.alloc_name_resolution())
1892 }
1893
1894 fn matches_previous_ambiguity_error(&self, ambi: &AmbiguityError<'_>) -> bool {
1896 for ambiguity_error in &self.ambiguity_errors {
1897 if ambiguity_error.kind == ambi.kind
1899 && ambiguity_error.ident == ambi.ident
1900 && ambiguity_error.ident.span == ambi.ident.span
1901 && ambiguity_error.b1.span == ambi.b1.span
1902 && ambiguity_error.b2.span == ambi.b2.span
1903 && ambiguity_error.misc1 == ambi.misc1
1904 && ambiguity_error.misc2 == ambi.misc2
1905 {
1906 return true;
1907 }
1908 }
1909 false
1910 }
1911
1912 fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'ra>, used: Used) {
1913 self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity);
1914 }
1915
1916 fn record_use_inner(
1917 &mut self,
1918 ident: Ident,
1919 used_binding: NameBinding<'ra>,
1920 used: Used,
1921 warn_ambiguity: bool,
1922 ) {
1923 if let Some((b2, kind)) = used_binding.ambiguity {
1924 let ambiguity_error = AmbiguityError {
1925 kind,
1926 ident,
1927 b1: used_binding,
1928 b2,
1929 misc1: AmbiguityErrorMisc::None,
1930 misc2: AmbiguityErrorMisc::None,
1931 warning: warn_ambiguity,
1932 };
1933 if !self.matches_previous_ambiguity_error(&ambiguity_error) {
1934 self.ambiguity_errors.push(ambiguity_error);
1936 }
1937 }
1938 if let NameBindingKind::Import { import, binding } = used_binding.kind {
1939 if let ImportKind::MacroUse { warn_private: true } = import.kind {
1940 self.lint_buffer().buffer_lint(
1941 PRIVATE_MACRO_USE,
1942 import.root_id,
1943 ident.span,
1944 BuiltinLintDiag::MacroIsPrivate(ident),
1945 );
1946 }
1947 if used == Used::Scope {
1950 if let Some(entry) = self.extern_prelude.get(&ident.normalize_to_macros_2_0()) {
1951 if !entry.introduced_by_item && entry.binding == Some(used_binding) {
1952 return;
1953 }
1954 }
1955 }
1956 let old_used = self.import_use_map.entry(import).or_insert(used);
1957 if *old_used < used {
1958 *old_used = used;
1959 }
1960 if let Some(id) = import.id() {
1961 self.used_imports.insert(id);
1962 }
1963 self.add_to_glob_map(import, ident);
1964 self.record_use_inner(
1965 ident,
1966 binding,
1967 Used::Other,
1968 warn_ambiguity || binding.warn_ambiguity,
1969 );
1970 }
1971 }
1972
1973 #[inline]
1974 fn add_to_glob_map(&mut self, import: Import<'_>, ident: Ident) {
1975 if let ImportKind::Glob { id, .. } = import.kind {
1976 let def_id = self.local_def_id(id);
1977 self.glob_map.entry(def_id).or_default().insert(ident.name);
1978 }
1979 }
1980
1981 fn resolve_crate_root(&mut self, ident: Ident) -> Module<'ra> {
1982 debug!("resolve_crate_root({:?})", ident);
1983 let mut ctxt = ident.span.ctxt();
1984 let mark = if ident.name == kw::DollarCrate {
1985 ctxt = ctxt.normalize_to_macro_rules();
1992 debug!(
1993 "resolve_crate_root: marks={:?}",
1994 ctxt.marks().into_iter().map(|(i, t)| (i.expn_data(), t)).collect::<Vec<_>>()
1995 );
1996 let mut iter = ctxt.marks().into_iter().rev().peekable();
1997 let mut result = None;
1998 while let Some(&(mark, transparency)) = iter.peek() {
2000 if transparency == Transparency::Opaque {
2001 result = Some(mark);
2002 iter.next();
2003 } else {
2004 break;
2005 }
2006 }
2007 debug!(
2008 "resolve_crate_root: found opaque mark {:?} {:?}",
2009 result,
2010 result.map(|r| r.expn_data())
2011 );
2012 for (mark, transparency) in iter {
2014 if transparency == Transparency::SemiTransparent {
2015 result = Some(mark);
2016 } else {
2017 break;
2018 }
2019 }
2020 debug!(
2021 "resolve_crate_root: found semi-transparent mark {:?} {:?}",
2022 result,
2023 result.map(|r| r.expn_data())
2024 );
2025 result
2026 } else {
2027 debug!("resolve_crate_root: not DollarCrate");
2028 ctxt = ctxt.normalize_to_macros_2_0();
2029 ctxt.adjust(ExpnId::root())
2030 };
2031 let module = match mark {
2032 Some(def) => self.expn_def_scope(def),
2033 None => {
2034 debug!(
2035 "resolve_crate_root({:?}): found no mark (ident.span = {:?})",
2036 ident, ident.span
2037 );
2038 return self.graph_root;
2039 }
2040 };
2041 let module = self.expect_module(
2042 module.opt_def_id().map_or(LOCAL_CRATE, |def_id| def_id.krate).as_def_id(),
2043 );
2044 debug!(
2045 "resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})",
2046 ident,
2047 module,
2048 module.kind.name(),
2049 ident.span
2050 );
2051 module
2052 }
2053
2054 fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'ra>) -> Module<'ra> {
2055 let mut module = self.expect_module(module.nearest_parent_mod());
2056 while module.span.ctxt().normalize_to_macros_2_0() != *ctxt {
2057 let parent = module.parent.unwrap_or_else(|| self.expn_def_scope(ctxt.remove_mark()));
2058 module = self.expect_module(parent.nearest_parent_mod());
2059 }
2060 module
2061 }
2062
2063 fn record_partial_res(&mut self, node_id: NodeId, resolution: PartialRes) {
2064 debug!("(recording res) recording {:?} for {}", resolution, node_id);
2065 if let Some(prev_res) = self.partial_res_map.insert(node_id, resolution) {
2066 panic!("path resolved multiple times ({prev_res:?} before, {resolution:?} now)");
2067 }
2068 }
2069
2070 fn record_pat_span(&mut self, node: NodeId, span: Span) {
2071 debug!("(recording pat) recording {:?} for {:?}", node, span);
2072 self.pat_span_map.insert(node, span);
2073 }
2074
2075 fn is_accessible_from(
2076 &self,
2077 vis: ty::Visibility<impl Into<DefId>>,
2078 module: Module<'ra>,
2079 ) -> bool {
2080 vis.is_accessible_from(module.nearest_parent_mod(), self.tcx)
2081 }
2082
2083 fn set_binding_parent_module(&mut self, binding: NameBinding<'ra>, module: Module<'ra>) {
2084 if let Some(old_module) = self.binding_parent_modules.insert(binding, module) {
2085 if module != old_module {
2086 span_bug!(binding.span, "parent module is reset for binding");
2087 }
2088 }
2089 }
2090
2091 fn disambiguate_macro_rules_vs_modularized(
2092 &self,
2093 macro_rules: NameBinding<'ra>,
2094 modularized: NameBinding<'ra>,
2095 ) -> bool {
2096 match (
2100 self.binding_parent_modules.get(¯o_rules),
2101 self.binding_parent_modules.get(&modularized),
2102 ) {
2103 (Some(macro_rules), Some(modularized)) => {
2104 macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
2105 && modularized.is_ancestor_of(*macro_rules)
2106 }
2107 _ => false,
2108 }
2109 }
2110
2111 fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'ra>> {
2112 if ident.is_path_segment_keyword() {
2113 return None;
2115 }
2116
2117 let norm_ident = ident.normalize_to_macros_2_0();
2118 let binding = self.extern_prelude.get(&norm_ident).cloned().and_then(|entry| {
2119 Some(if let Some(binding) = entry.binding {
2120 if finalize {
2121 if !entry.is_import() {
2122 self.crate_loader(|c| c.process_path_extern(ident.name, ident.span));
2123 } else if entry.introduced_by_item {
2124 self.record_use(ident, binding, Used::Other);
2125 }
2126 }
2127 binding
2128 } else {
2129 let crate_id = if finalize {
2130 let Some(crate_id) =
2131 self.crate_loader(|c| c.process_path_extern(ident.name, ident.span))
2132 else {
2133 return Some(self.dummy_binding);
2134 };
2135 crate_id
2136 } else {
2137 self.crate_loader(|c| c.maybe_process_path_extern(ident.name))?
2138 };
2139 let crate_root = self.expect_module(crate_id.as_def_id());
2140 let vis = ty::Visibility::<DefId>::Public;
2141 (crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas)
2142 })
2143 });
2144
2145 if let Some(entry) = self.extern_prelude.get_mut(&norm_ident) {
2146 entry.binding = binding;
2147 }
2148
2149 binding
2150 }
2151
2152 fn resolve_rustdoc_path(
2157 &mut self,
2158 path_str: &str,
2159 ns: Namespace,
2160 parent_scope: ParentScope<'ra>,
2161 ) -> Option<Res> {
2162 let mut segments =
2163 Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident));
2164 if let Some(segment) = segments.first_mut() {
2165 if segment.ident.name == kw::Empty {
2166 segment.ident.name = kw::PathRoot;
2167 }
2168 }
2169
2170 match self.maybe_resolve_path(&segments, Some(ns), &parent_scope, None) {
2171 PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
2172 PathResult::NonModule(path_res) => {
2173 path_res.full_res().filter(|res| !matches!(res, Res::Def(DefKind::Ctor(..), _)))
2174 }
2175 PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => {
2176 None
2177 }
2178 PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
2179 }
2180 }
2181
2182 fn def_span(&self, def_id: DefId) -> Span {
2184 match def_id.as_local() {
2185 Some(def_id) => self.tcx.source_span(def_id),
2186 None => self.cstore().def_span_untracked(def_id, self.tcx.sess),
2188 }
2189 }
2190
2191 fn field_idents(&self, def_id: DefId) -> Option<Vec<Ident>> {
2192 match def_id.as_local() {
2193 Some(def_id) => self.field_names.get(&def_id).cloned(),
2194 None => Some(
2195 self.tcx
2196 .associated_item_def_ids(def_id)
2197 .iter()
2198 .map(|&def_id| {
2199 Ident::new(self.tcx.item_name(def_id), self.tcx.def_span(def_id))
2200 })
2201 .collect(),
2202 ),
2203 }
2204 }
2205
2206 fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>> {
2210 if let ExprKind::Path(None, path) = &expr.kind {
2211 if path.segments.last().unwrap().args.is_some() {
2214 return None;
2215 }
2216
2217 let res = self.partial_res_map.get(&expr.id)?.full_res()?;
2218 if let Res::Def(def::DefKind::Fn, def_id) = res {
2219 if def_id.is_local() {
2223 return None;
2224 }
2225
2226 if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
2227 return v.clone();
2228 }
2229
2230 let attr = self.tcx.get_attr(def_id, sym::rustc_legacy_const_generics)?;
2231 let mut ret = Vec::new();
2232 for meta in attr.meta_item_list()? {
2233 match meta.lit()?.kind {
2234 LitKind::Int(a, _) => ret.push(a.get() as usize),
2235 _ => panic!("invalid arg index"),
2236 }
2237 }
2238 self.legacy_const_generic_args.insert(def_id, Some(ret.clone()));
2240 return Some(ret);
2241 }
2242 }
2243 None
2244 }
2245
2246 fn resolve_main(&mut self) {
2247 let module = self.graph_root;
2248 let ident = Ident::with_dummy_span(sym::main);
2249 let parent_scope = &ParentScope::module(module, self);
2250
2251 let Ok(name_binding) = self.maybe_resolve_ident_in_module(
2252 ModuleOrUniformRoot::Module(module),
2253 ident,
2254 ValueNS,
2255 parent_scope,
2256 None,
2257 ) else {
2258 return;
2259 };
2260
2261 let res = name_binding.res();
2262 let is_import = name_binding.is_import();
2263 let span = name_binding.span;
2264 if let Res::Def(DefKind::Fn, _) = res {
2265 self.record_use(ident, name_binding, Used::Other);
2266 }
2267 self.main_def = Some(MainDefinition { res, is_import, span });
2268 }
2269}
2270
2271fn names_to_string(names: impl Iterator<Item = Symbol>) -> String {
2272 let mut result = String::new();
2273 for (i, name) in names.filter(|name| *name != kw::PathRoot).enumerate() {
2274 if i > 0 {
2275 result.push_str("::");
2276 }
2277 if Ident::with_dummy_span(name).is_raw_guess() {
2278 result.push_str("r#");
2279 }
2280 result.push_str(name.as_str());
2281 }
2282 result
2283}
2284
2285fn path_names_to_string(path: &Path) -> String {
2286 names_to_string(path.segments.iter().map(|seg| seg.ident.name))
2287}
2288
2289fn module_to_string(mut module: Module<'_>) -> Option<String> {
2291 let mut names = Vec::new();
2292 loop {
2293 if let ModuleKind::Def(.., name) = module.kind {
2294 if let Some(parent) = module.parent {
2295 names.push(name);
2296 module = parent
2297 } else {
2298 break;
2299 }
2300 } else {
2301 names.push(sym::opaque_module_name_placeholder);
2302 let Some(parent) = module.parent else {
2303 return None;
2304 };
2305 module = parent;
2306 }
2307 }
2308 if names.is_empty() {
2309 return None;
2310 }
2311 Some(names_to_string(names.iter().rev().copied()))
2312}
2313
2314#[derive(Copy, Clone, Debug)]
2315struct Finalize {
2316 node_id: NodeId,
2318 path_span: Span,
2321 root_span: Span,
2324 report_private: bool,
2327 used: Used,
2329}
2330
2331impl Finalize {
2332 fn new(node_id: NodeId, path_span: Span) -> Finalize {
2333 Finalize::with_root_span(node_id, path_span, path_span)
2334 }
2335
2336 fn with_root_span(node_id: NodeId, path_span: Span, root_span: Span) -> Finalize {
2337 Finalize { node_id, path_span, root_span, report_private: true, used: Used::Other }
2338 }
2339}
2340
2341pub fn provide(providers: &mut Providers) {
2342 providers.registered_tools = macros::registered_tools;
2343}