Skip to main content

rustc_resolve/
build_reduced_graph.rs

1//! After we obtain a fresh AST fragment from a macro, code in this module helps to integrate
2//! that fragment into the module structures that are already partially built.
3//!
4//! Items from the fragment are placed into modules,
5//! unexpanded macros in the fragment are visited and registered.
6//! Imports are also considered items and placed into modules here, but not resolved yet.
7
8use std::sync::Arc;
9
10use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
11use rustc_ast::{
12    self as ast, AssocItem, AssocItemKind, Block, ConstItem, DUMMY_NODE_ID, Delegation,
13    DelegationSource, Fn, ForeignItem, ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem,
14    StmtKind, TraitAlias, TyAlias,
15};
16use rustc_attr_parsing::AttributeParser;
17use rustc_data_structures::fx::FxIndexMap;
18use rustc_expand::base::{ResolverExpand, SyntaxExtension, SyntaxExtensionKind};
19use rustc_hir::Attribute;
20use rustc_hir::attrs::{AttributeKind, MacroUseArgs};
21use rustc_hir::def::{self, *};
22use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
23use rustc_index::bit_set::DenseBitSet;
24use rustc_metadata::creader::LoadedMacro;
25use rustc_middle::metadata::{ModChild, Reexport};
26use rustc_middle::ty::{TyCtxtFeed, Visibility};
27use rustc_middle::{bug, span_bug};
28use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
29use rustc_span::{Ident, Span, Symbol, kw, sym};
30use thin_vec::ThinVec;
31use tracing::debug;
32
33use crate::Namespace::{MacroNS, TypeNS, ValueNS};
34use crate::def_collector::DefCollector;
35use crate::error_helper::{OnUnknownData, StructCtor};
36use crate::imports::{ImportData, ImportKind, NameResolution, NameResolutionRef};
37use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
38use crate::ref_mut::CmCell;
39use crate::{
40    BindingKey, Decl, DeclData, DeclKind, DelayedVisResolutionError, ExternModule,
41    ExternPreludeEntry, Finalize, IdentKey, LocalModule, Module, ModuleKind, ModuleOrUniformRoot,
42    ParentScope, PathResult, Res, Resolver, Segment, Used, VisResolutionError, diagnostics,
43};
44
45impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
46    /// Attempt to put the declaration with the given name and namespace into the module,
47    /// and report an error in case of a collision.
48    pub(crate) fn plant_decl_into_local_module(
49        &mut self,
50        ident: IdentKey,
51        orig_ident_span: Span,
52        ns: Namespace,
53        decl: Decl<'ra>,
54    ) {
55        if let Err(old_decl) =
56            self.try_plant_decl_into_local_module(ident, orig_ident_span, ns, decl)
57        {
58            self.report_conflict(ident, ns, old_decl, decl);
59        }
60    }
61
62    /// Create a name definition from the given components, and put it into the local module.
63    fn define_local(
64        &mut self,
65        parent: LocalModule<'ra>,
66        orig_ident: Ident,
67        ns: Namespace,
68        res: Res,
69        vis: Visibility,
70        span: Span,
71        expn_id: LocalExpnId,
72    ) {
73        let decl =
74            self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id, Some(parent.to_module()));
75        let ident = IdentKey::new(orig_ident);
76        self.plant_decl_into_local_module(ident, orig_ident.span, ns, decl);
77    }
78
79    /// Walks up the tree of definitions starting at `def_id`,
80    /// stopping at the first encountered module.
81    /// Parent block modules for arbitrary def-ids are not recorded for the local crate,
82    /// and are not preserved in metadata for foreign crates, so block modules are never
83    /// returned by this function.
84    ///
85    /// For the local crate ignoring block modules may be incorrect, so use this method with care.
86    ///
87    /// For foreign crates block modules can be ignored without introducing observable differences,
88    /// moreover they has to be ignored right now because they are not kept in metadata.
89    /// Foreign parent modules are used for resolving names used by foreign macros with def-site
90    /// hygiene, therefore block module ignorability relies on macros with def-site hygiene and
91    /// block module parents being unreachable from other crates.
92    /// Reachable macros with block module parents exist due to `#[macro_export] macro_rules!`,
93    /// but they cannot use def-site hygiene, so the assumption holds
94    /// (<https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508>).
95    pub(crate) fn get_nearest_non_block_module(&self, mut def_id: DefId) -> Module<'ra> {
96        loop {
97            match self.get_module(def_id) {
98                Some(module) => return module,
99                None => def_id = self.tcx.parent(def_id),
100            }
101        }
102    }
103
104    pub(crate) fn expect_module(&self, def_id: DefId) -> Module<'ra> {
105        self.get_module(def_id).expect("argument `DefId` is not a module")
106    }
107
108    /// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
109    /// or trait), then this function returns that module's resolver representation, otherwise it
110    /// returns `None`.
111    pub(crate) fn get_module(&self, def_id: DefId) -> Option<Module<'ra>> {
112        match def_id.as_local() {
113            Some(local_def_id) => self.local_module_map.get(&local_def_id).map(|m| m.to_module()),
114            None => {
115                if let module @ Some(..) = self.extern_module_map.borrow().get(&def_id) {
116                    return module.map(|m| m.to_module());
117                }
118
119                // Query `def_kind` is not used because query system overhead is too expensive here.
120                let def_kind = self.cstore().def_kind_untracked(def_id);
121                if def_kind.is_module_like() {
122                    let parent = self.tcx.opt_parent(def_id).map(|parent_id| {
123                        self.get_nearest_non_block_module(parent_id).expect_extern()
124                    });
125                    // Query `expn_that_defined` is not used because
126                    // hashing spans in its result is expensive.
127                    let expn_id = self.cstore().expn_that_defined_untracked(self.tcx, def_id);
128                    let module = self.new_extern_module(
129                        parent,
130                        ModuleKind::Def(
131                            def_kind,
132                            def_id,
133                            DUMMY_NODE_ID,
134                            Some(self.tcx.item_name(def_id)),
135                        ),
136                        expn_id,
137                        self.def_span(def_id),
138                        // FIXME: Account for `#[no_implicit_prelude]` attributes.
139                        parent.is_some_and(|module| module.no_implicit_prelude),
140                    );
141                    return Some(module.to_module());
142                }
143
144                None
145            }
146        }
147    }
148
149    pub(crate) fn expn_def_scope(&self, expn_id: ExpnId) -> Module<'ra> {
150        match expn_id.expn_data().macro_def_id {
151            Some(def_id) => self.macro_def_scope(def_id),
152            None => expn_id
153                .as_local()
154                .and_then(|expn_id| self.ast_transform_scopes.get(&expn_id).copied())
155                .unwrap_or(self.graph_root)
156                .to_module(),
157        }
158    }
159
160    pub(crate) fn macro_def_scope(&self, def_id: DefId) -> Module<'ra> {
161        if let Some(id) = def_id.as_local() {
162            self.local_macro_def_scopes[&id].to_module()
163        } else {
164            self.get_nearest_non_block_module(def_id)
165        }
166    }
167
168    /// Gets the `SyntaxExtension` corresponding to `res`.
169    pub(crate) fn get_macro(&self, res: Res) -> Option<&'ra Arc<SyntaxExtension>> {
170        match res {
171            Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
172            Res::NonMacroAttr(_) => Some(self.non_macro_attr),
173            _ => None,
174        }
175    }
176
177    pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra Arc<SyntaxExtension> {
178        // Local macros are always compiled.
179        match def_id.as_local() {
180            Some(local_def_id) => self.local_macro_map[&local_def_id],
181            None => self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| {
182                let loaded_macro = self.cstore().load_macro_untracked(self.tcx, def_id);
183                let ext = match loaded_macro {
184                    LoadedMacro::MacroDef { def, ident, attrs, span, edition } => {
185                        self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition)
186                    }
187                    LoadedMacro::ProcMacro(ext) => ext,
188                };
189
190                self.arenas.alloc_macro(ext)
191            }),
192        }
193    }
194
195    /// Add every proc macro accessible from the current crate to the `macro_map` so diagnostics can
196    /// find them for suggestions.
197    pub(crate) fn register_macros_for_all_crates(&mut self) {
198        if !self.all_crate_macros_already_registered {
199            for def_id in self.cstore().all_proc_macro_def_ids(self.tcx) {
200                self.get_macro_by_def_id(def_id);
201            }
202            self.all_crate_macros_already_registered = true;
203        }
204    }
205
206    pub(crate) fn try_resolve_visibility(
207        &mut self,
208        parent_scope: &ParentScope<'ra>,
209        vis: &ast::Visibility,
210        finalize: bool,
211    ) -> Result<Visibility, VisResolutionError> {
212        match vis.kind {
213            ast::VisibilityKind::Public => Ok(Visibility::Public),
214            ast::VisibilityKind::Inherited => {
215                Ok(match parent_scope.module.expect_local().kind {
216                    // Any inherited visibility resolved directly inside an enum or trait
217                    // (i.e. variants, fields, and trait items) inherits from the visibility
218                    // of the enum or trait.
219                    ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _, _) => {
220                        self.tcx.visibility(def_id).expect_local()
221                    }
222                    // Otherwise, the visibility is restricted to the nearest parent `mod` item.
223                    _ => Visibility::Restricted(
224                        parent_scope.module.nearest_parent_mod().expect_local(),
225                    ),
226                })
227            }
228            ast::VisibilityKind::Restricted { ref path, id, .. } => {
229                // For visibilities we are not ready to provide correct implementation of "uniform
230                // paths" right now, so on 2018 edition we only allow module-relative paths for now.
231                // On 2015 edition visibilities are resolved as crate-relative by default,
232                // so we are prepending a root segment if necessary.
233                let ident = path.segments.get(0).expect("empty path in visibility").ident;
234                let crate_root = if ident.is_path_segment_keyword() {
235                    None
236                } else if ident.span.is_rust_2015() {
237                    Some(Segment::from_ident(Ident::new(
238                        kw::PathRoot,
239                        path.span.shrink_to_lo().with_ctxt(ident.span.ctxt()),
240                    )))
241                } else {
242                    return Err(VisResolutionError::Relative2018(
243                        ident.span,
244                        path.as_ref().clone(),
245                    ));
246                };
247                let segments = crate_root
248                    .into_iter()
249                    .chain(path.segments.iter().map(|seg| seg.into()))
250                    .collect::<Vec<_>>();
251                let expected_found_error = |res| {
252                    Err(VisResolutionError::ExpectedFound(
253                        path.span,
254                        Segment::names_to_string(&segments),
255                        res,
256                    ))
257                };
258                match self.cm().resolve_path(
259                    &segments,
260                    None,
261                    parent_scope,
262                    finalize.then(|| Finalize::new(id, path.span)),
263                    None,
264                    None,
265                ) {
266                    PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
267                        let res = module.res().expect("visibility resolved to unnamed block");
268                        if module.is_normal() {
269                            match res {
270                                Res::Err => {
271                                    if finalize {
272                                        self.record_partial_res(id, PartialRes::new(res));
273                                    }
274                                    Ok(Visibility::Public)
275                                }
276                                _ => {
277                                    let vis = Visibility::Restricted(res.def_id());
278                                    if self.is_accessible_from(vis, parent_scope.module) {
279                                        if finalize {
280                                            self.record_partial_res(id, PartialRes::new(res));
281                                        }
282                                        Ok(vis.expect_local())
283                                    } else {
284                                        Err(VisResolutionError::AncestorOnly(path.span))
285                                    }
286                                }
287                            }
288                        } else {
289                            expected_found_error(res)
290                        }
291                    }
292                    PathResult::Module(..) => Err(VisResolutionError::ModuleOnly(path.span)),
293                    PathResult::NonModule(partial_res) => {
294                        expected_found_error(partial_res.expect_full_res())
295                    }
296                    PathResult::Failed { label, suggestion, message, segment, .. } => {
297                        Err(VisResolutionError::FailedToResolve(
298                            segment.span,
299                            segment.name,
300                            label,
301                            suggestion,
302                            message,
303                        ))
304                    }
305                    PathResult::Indeterminate => Err(VisResolutionError::Indeterminate(path.span)),
306                }
307            }
308        }
309    }
310
311    pub(crate) fn build_reduced_graph_external(
312        &self,
313        module: ExternModule<'ra>,
314    ) -> FxIndexMap<BindingKey, NameResolutionRef<'ra>> {
315        let mut resolutions = FxIndexMap::default();
316        let def_id = module.def_id();
317        let children = self.tcx.module_children(def_id);
318        for (i, child) in children.iter().enumerate() {
319            self.build_reduced_graph_for_external_crate_res(
320                child,
321                module,
322                i,
323                None,
324                &mut resolutions,
325            )
326        }
327        for (i, child) in
328            self.cstore().ambig_module_children_untracked(self.tcx, def_id).enumerate()
329        {
330            self.build_reduced_graph_for_external_crate_res(
331                &child.main,
332                module,
333                children.len() + i,
334                Some(&child.second),
335                &mut resolutions,
336            )
337        }
338        resolutions
339    }
340
341    /// Builds the reduced graph for a single item in an external crate.
342    fn build_reduced_graph_for_external_crate_res(
343        &self,
344        child: &ModChild,
345        parent: ExternModule<'ra>,
346        child_index: usize,
347        ambig_child: Option<&ModChild>,
348        resolutions: &mut FxIndexMap<BindingKey, NameResolutionRef<'ra>>,
349    ) {
350        let child_span = |this: &Self, reexport_chain: &[Reexport], res: def::Res<_>| {
351            this.def_span(
352                reexport_chain
353                    .first()
354                    .and_then(|reexport| reexport.id())
355                    .unwrap_or_else(|| res.def_id()),
356            )
357        };
358        let ModChild { ident: orig_ident, res, vis, ref reexport_chain } = *child;
359        let ident = IdentKey::new(orig_ident);
360        let span = child_span(self, reexport_chain, res);
361        let res = res.expect_non_local();
362        let expansion = LocalExpnId::ROOT;
363        let ambig = ambig_child.map(|ambig_child| {
364            let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child;
365            let span = child_span(self, reexport_chain, res);
366            let res = res.expect_non_local();
367            // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment.
368            (self.arenas.new_def_decl(res, vis, span, expansion, Some(parent.to_module())), true)
369        });
370
371        // Record primary definitions.
372        let mut define_extern = |ns| {
373            let orig_ident_span = orig_ident.span;
374            let decl = self.arenas.alloc_decl(DeclData {
375                kind: DeclKind::Def(res),
376                ambiguity: CmCell::new(ambig),
377                initial_vis: vis,
378                ambiguity_vis_max: CmCell::new(None),
379                ambiguity_vis_min: CmCell::new(None),
380                span,
381                expansion,
382                parent_module: Some(parent.to_module()),
383            });
384            let resolution = self.arenas.alloc_name_resolution(NameResolution {
385                non_glob_decl: Some(decl),
386                orig_ident_span,
387                single_imports: Default::default(),
388                ..
389            });
390
391            let key =
392                BindingKey::new_disambiguated(ident, ns, || (child_index + 1).try_into().unwrap());
393            if resolutions.insert(key, resolution).is_some() {
394                ::rustc_middle::util::bug::span_bug_fmt(span,
    format_args!("an external binding was already defined"));span_bug!(span, "an external binding was already defined");
395            }
396        };
397        match res {
398            Res::Def(
399                DefKind::Mod
400                | DefKind::Enum
401                | DefKind::Trait
402                | DefKind::Struct
403                | DefKind::Union
404                | DefKind::Variant
405                | DefKind::TyAlias
406                | DefKind::ForeignTy
407                | DefKind::OpaqueTy
408                | DefKind::TraitAlias
409                | DefKind::AssocTy,
410                _,
411            )
412            | Res::PrimTy(..)
413            | Res::ToolMod => define_extern(TypeNS),
414            Res::Def(
415                DefKind::Fn
416                | DefKind::AssocFn
417                | DefKind::Static { .. }
418                | DefKind::Const { .. }
419                | DefKind::AssocConst { .. }
420                | DefKind::Ctor(..),
421                _,
422            ) => define_extern(ValueNS),
423            Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => define_extern(MacroNS),
424            Res::Def(
425                DefKind::TyParam
426                | DefKind::ConstParam
427                | DefKind::ExternCrate
428                | DefKind::Use
429                | DefKind::ForeignMod
430                | DefKind::AnonConst
431                | DefKind::Field
432                | DefKind::LifetimeParam
433                | DefKind::GlobalAsm
434                | DefKind::Closure
435                | DefKind::SyntheticCoroutineBody
436                | DefKind::Impl { .. },
437                _,
438            )
439            | Res::Local(..)
440            | Res::SelfTyParam { .. }
441            | Res::SelfTyAlias { .. }
442            | Res::SelfCtor(..)
443            | Res::OpenMod(..)
444            | Res::Err => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected resolution: {0:?}",
        res))bug!("unexpected resolution: {:?}", res),
445        }
446    }
447}
448
449impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for DefCollector<'_, 'ra, 'tcx> {
450    fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
451        self.r
452    }
453}
454
455impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
456    fn res(&self, def_id: impl Into<DefId>) -> Res {
457        let def_id = def_id.into();
458        Res::Def(self.r.tcx.def_kind(def_id), def_id)
459    }
460
461    fn resolve_visibility(&mut self, vis: &ast::Visibility) -> Visibility {
462        match self.r.try_resolve_visibility(&self.parent_scope, vis, false) {
463            Ok(vis) => vis,
464            Err(error) => {
465                self.r.delayed_vis_resolution_errors.push(DelayedVisResolutionError {
466                    vis: vis.clone(),
467                    parent_scope: self.parent_scope,
468                    error,
469                });
470                Visibility::Public
471            }
472        }
473    }
474
475    fn insert_field_idents(&mut self, def_id: LocalDefId, fields: &[ast::FieldDef]) {
476        if fields.iter().any(|field| field.is_placeholder) {
477            // The fields are not expanded yet.
478            return;
479        }
480        let field_name = |i, field: &ast::FieldDef| {
481            field.ident.unwrap_or_else(|| Ident::from_str_and_span(&::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("{0}", i)) })format!("{i}"), field.span))
482        };
483        let field_names: Vec<_> =
484            fields.iter().enumerate().map(|(i, field)| field_name(i, field)).collect();
485        let defaults = fields
486            .iter()
487            .enumerate()
488            .filter_map(|(i, field)| field.default.as_ref().map(|_| field_name(i, field).name))
489            .collect();
490        self.r.field_names.insert(def_id, field_names);
491        self.r.field_defaults.insert(def_id, defaults);
492    }
493
494    fn insert_field_visibilities_local(&mut self, def_id: DefId, fields: &[ast::FieldDef]) {
495        let field_vis = fields
496            .iter()
497            .map(|field| field.vis.span.until(field.ident.map_or(field.ty.span, |i| i.span)))
498            .collect();
499        self.r.field_visibility_spans.insert(def_id, field_vis);
500    }
501
502    fn block_needs_anonymous_module(&self, block: &Block) -> bool {
503        // If any statements are items, we need to create an anonymous module
504        block
505            .stmts
506            .iter()
507            .any(|statement| #[allow(non_exhaustive_omitted_patterns)] match statement.kind {
    StmtKind::Item(_) | StmtKind::MacCall(_) => true,
    _ => false,
}matches!(statement.kind, StmtKind::Item(_) | StmtKind::MacCall(_)))
508    }
509
510    // Add an import to the current module.
511    fn add_import(
512        &mut self,
513        module_path: Vec<Segment>,
514        kind: ImportKind<'ra>,
515        span: Span,
516        item: &ast::Item,
517        root_span: Span,
518        root_id: NodeId,
519        vis: Visibility,
520    ) {
521        let current_module = self.parent_scope.module.expect_local();
522        let import = self.r.arenas.alloc_import(ImportData {
523            kind,
524            parent_scope: self.parent_scope,
525            module_path,
526            imported_module: CmCell::new(None),
527            span,
528            use_span: item.span,
529            use_span_with_attributes: item.span_with_attributes(),
530            has_attributes: !item.attrs.is_empty(),
531            root_span,
532            root_id,
533            vis,
534            vis_span: item.vis.span,
535            on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs),
536        });
537
538        self.r.indeterminate_imports.push(import);
539        match import.kind {
540            ImportKind::Single { target, .. } => {
541                // Don't add underscore imports to `single_imports`
542                // because they cannot define any usable names.
543                if target.name != kw::Underscore {
544                    self.r.per_ns(|this, ns| {
545                        let key = BindingKey::new(IdentKey::new(target), ns);
546                        this.resolution_or_default(current_module.to_module(), key, target.span)
547                            .borrow_mut(this)
548                            .single_imports
549                            .insert(import);
550                    });
551                }
552            }
553            ImportKind::Glob { .. } => current_module.globs.borrow_mut(self.r).push(import),
554            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
555        }
556    }
557
558    fn build_reduced_graph_for_use_tree(
559        &mut self,
560        // This particular use tree
561        use_tree: &ast::UseTree,
562        id: NodeId,
563        parent_prefix: &[Segment],
564        nested: bool,
565        list_stem: bool,
566        // The whole `use` item
567        item: &Item,
568        vis: Visibility,
569        root_span: Span,
570        feed: TyCtxtFeed<'tcx, LocalDefId>,
571    ) {
572        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_resolve/src/build_reduced_graph.rs:572",
                        "rustc_resolve::build_reduced_graph",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_resolve/src/build_reduced_graph.rs"),
                        ::tracing_core::__macro_support::Option::Some(572u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_resolve::build_reduced_graph"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("build_reduced_graph_for_use_tree(parent_prefix={0:?}, use_tree={1:?}, nested={2})",
                                                    parent_prefix, use_tree, nested) as &dyn Value))])
            });
    } else { ; }
};debug!(
573            "build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
574            parent_prefix, use_tree, nested
575        );
576
577        // Top level use tree reuses the item's id and list stems reuse their parent
578        // use tree's ids, so in both cases their visibilities are already filled.
579        if nested && !list_stem {
580            self.r.feed_visibility(feed, vis);
581        }
582
583        let mut prefix_iter = parent_prefix
584            .iter()
585            .cloned()
586            .chain(use_tree.prefix.segments.iter().map(|seg| seg.into()))
587            .peekable();
588
589        // On 2015 edition imports are resolved as crate-relative by default,
590        // so prefixes are prepended with crate root segment if necessary.
591        // The root is prepended lazily, when the first non-empty prefix or terminating glob
592        // appears, so imports in braced groups can have roots prepended independently.
593        let crate_root = match prefix_iter.peek() {
594            Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.is_rust_2015() => {
595                Some(seg.ident.span.ctxt())
596            }
597            None if let ast::UseTreeKind::Glob(span) = use_tree.kind
598                && span.is_rust_2015() =>
599            {
600                Some(span.ctxt())
601            }
602            _ => None,
603        }
604        .map(|ctxt| {
605            Segment::from_ident(Ident::new(
606                kw::PathRoot,
607                use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt),
608            ))
609        });
610
611        let prefix = crate_root.into_iter().chain(prefix_iter).collect::<Vec<_>>();
612        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_resolve/src/build_reduced_graph.rs:612",
                        "rustc_resolve::build_reduced_graph",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_resolve/src/build_reduced_graph.rs"),
                        ::tracing_core::__macro_support::Option::Some(612u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_resolve::build_reduced_graph"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("build_reduced_graph_for_use_tree: prefix={0:?}",
                                                    prefix) as &dyn Value))])
            });
    } else { ; }
};debug!("build_reduced_graph_for_use_tree: prefix={:?}", prefix);
613
614        match use_tree.kind {
615            ast::UseTreeKind::Simple(rename) => {
616                let mut module_path = prefix;
617                let source = module_path.pop().unwrap();
618
619                // If the identifier is `self` without a rename,
620                // then it is replaced with the parent identifier.
621                let ident = if source.ident.name == kw::SelfLower
622                    && rename.is_none()
623                    && let Some(parent) = module_path.last()
624                {
625                    Ident::new(parent.ident.name, source.ident.span)
626                } else {
627                    use_tree.ident()
628                };
629
630                match source.ident.name {
631                    kw::DollarCrate => {
632                        if !module_path.is_empty() {
633                            self.r.dcx().span_err(
634                                source.ident.span,
635                                "`$crate` in paths can only be used in start position",
636                            );
637                            return;
638                        }
639                    }
640                    kw::Crate => {
641                        if !module_path.is_empty() {
642                            self.r.dcx().span_err(
643                                source.ident.span,
644                                "`crate` in paths can only be used in start position",
645                            );
646                            return;
647                        }
648                    }
649                    kw::Super => {
650                        // Allow `self::super` as a valid prefix - `self` at position 0
651                        // followed by any number of `super` segments.
652                        let valid_prefix = module_path.iter().enumerate().all(|(i, seg)| {
653                            let name = seg.ident.name;
654                            name == kw::Super || (name == kw::SelfLower && i == 0)
655                        });
656
657                        if !valid_prefix {
658                            self.r.dcx().span_err(
659                                source.ident.span,
660                                "`super` in paths can only be used in start position, after `self`, or after another `super`",
661                            );
662                            return;
663                        }
664                    }
665                    // Deny `use ::{self};` after edition 2015
666                    kw::SelfLower
667                        if let Some(parent) = module_path.last()
668                            && parent.ident.name == kw::PathRoot
669                            && !self.r.path_root_is_crate_root(parent.ident) =>
670                    {
671                        self.r.dcx().span_err(use_tree.span(), "extern prelude cannot be imported");
672                        return;
673                    }
674                    _ => (),
675                }
676
677                // Deny `use ...::self::source [as target];` or `use ...::self::self [as target];`,
678                // but allow `use self::source [as target];` and `use self::self as target;`.
679                if let Some(parent) = module_path.last()
680                    && parent.ident.name == kw::SelfLower
681                    && module_path.len() > 1
682                {
683                    self.r.dcx().span_err(
684                        parent.ident.span,
685                        "`self` in paths can only be used in start position or last position",
686                    );
687                    return;
688                }
689
690                // Deny importing path-kw without renaming
691                if rename.is_none() && ident.is_path_segment_keyword() {
692                    let ident = use_tree.ident();
693                    self.r.dcx().emit_err(diagnostics::UnnamedImport {
694                        span: ident.span,
695                        sugg: diagnostics::UnnamedImportSugg { span: ident.span, ident },
696                    });
697                    return;
698                }
699
700                let kind = ImportKind::Single {
701                    source: source.ident,
702                    target: ident,
703                    decls: Default::default(),
704                    nested,
705                    id,
706                    def_id: feed.def_id(),
707                };
708
709                self.add_import(module_path, kind, use_tree.span(), item, root_span, item.id, vis);
710            }
711            ast::UseTreeKind::Glob(_) => {
712                if !ast::attr::contains_name(&item.attrs, sym::prelude_import) {
713                    let kind =
714                        ImportKind::Glob { max_vis: CmCell::new(None), id, def_id: feed.def_id() };
715                    self.add_import(prefix, kind, use_tree.span(), item, root_span, item.id, vis);
716                } else {
717                    // Resolve the prelude import early.
718                    let path_res =
719                        self.r.cm().maybe_resolve_path(&prefix, None, &self.parent_scope, None);
720                    if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = path_res {
721                        self.r.prelude = Some(module);
722                    } else {
723                        self.r.dcx().span_err(use_tree.span(), "cannot resolve a prelude import");
724                    }
725                }
726            }
727            ast::UseTreeKind::Nested { ref items, .. } => {
728                for &(ref tree, id) in items {
729                    self.with_owner(id, None, DefKind::Use, use_tree.span(), |this, feed| {
730                        this.build_reduced_graph_for_use_tree(
731                            // This particular use tree
732                            tree, id, &prefix, true, false, // The whole `use` item
733                            item, vis, root_span, feed,
734                        )
735                    });
736                }
737
738                // Empty groups `a::b::{}` are turned into synthetic `self` imports
739                // `a::b::c::{self as _}`, so that their prefixes are correctly
740                // resolved and checked for privacy/stability/etc.
741                if items.is_empty()
742                    && !prefix.is_empty()
743                    && (prefix.len() > 1 || prefix[0].ident.name != kw::PathRoot)
744                {
745                    let new_span = prefix[prefix.len() - 1].ident.span;
746                    let tree = ast::UseTree {
747                        prefix: ast::Path::from_ident(Ident::new(kw::SelfLower, new_span)),
748                        kind: ast::UseTreeKind::Simple(Some(Ident::new(kw::Underscore, new_span))),
749                    };
750                    self.build_reduced_graph_for_use_tree(
751                        // This particular use tree
752                        &tree,
753                        id,
754                        &prefix,
755                        true,
756                        true,
757                        // The whole `use` item
758                        item,
759                        Visibility::Restricted(
760                            self.parent_scope.module.nearest_parent_mod().expect_local(),
761                        ),
762                        root_span,
763                        feed,
764                    );
765                }
766            }
767        }
768    }
769
770    fn build_reduced_graph_for_struct_variant(
771        &mut self,
772        fields: &[ast::FieldDef],
773        ident: Ident,
774        feed: TyCtxtFeed<'tcx, LocalDefId>,
775        adt_res: Res,
776        adt_vis: Visibility,
777        adt_span: Span,
778    ) {
779        let parent_scope = &self.parent_scope;
780        let parent = parent_scope.module.expect_local();
781        let expansion = parent_scope.expansion;
782
783        // Define a name in the type namespace if it is not anonymous.
784        self.r.define_local(parent, ident, TypeNS, adt_res, adt_vis, adt_span, expansion);
785        self.r.feed_visibility(feed, adt_vis);
786        let def_id = feed.key();
787
788        // Record field names for error reporting.
789        self.insert_field_idents(def_id, fields);
790        self.insert_field_visibilities_local(def_id.to_def_id(), fields);
791    }
792
793    /// Constructs the reduced graph for one item.
794    fn build_reduced_graph_for_item(&mut self, item: &'a Item, feed: TyCtxtFeed<'tcx, LocalDefId>) {
795        let parent_scope = &self.parent_scope;
796        let parent = parent_scope.module.expect_local();
797        let expansion = parent_scope.expansion;
798        let sp = item.span;
799        let vis = self.resolve_visibility(&item.vis);
800        let local_def_id = feed.key();
801        let def_id = local_def_id.to_def_id();
802        let def_kind = self.r.tcx.def_kind(def_id);
803        let res = Res::Def(def_kind, def_id);
804
805        self.r.feed_visibility(feed, vis);
806
807        match item.kind {
808            ItemKind::Use(ref use_tree) => {
809                self.build_reduced_graph_for_use_tree(
810                    // This particular use tree
811                    use_tree,
812                    item.id,
813                    &[],
814                    false,
815                    false,
816                    // The whole `use` item
817                    item,
818                    vis,
819                    use_tree.span(),
820                    feed,
821                );
822            }
823
824            ItemKind::ExternCrate(orig_name, ident) => {
825                self.build_reduced_graph_for_extern_crate(
826                    orig_name,
827                    item,
828                    ident,
829                    local_def_id,
830                    vis,
831                );
832            }
833
834            ItemKind::Mod(_, ident, ref mod_kind) => {
835                self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
836
837                if let ast::ModKind::Loaded(_, Inline::No { had_parse_error: Err(_) }, _) = mod_kind
838                {
839                    self.r.mods_with_parse_errors.insert(def_id);
840                }
841                let module = self.r.new_local_module(
842                    Some(parent),
843                    ModuleKind::Def(def_kind, def_id, item.id, Some(ident.name)),
844                    expansion.to_expn_id(),
845                    item.span,
846                    parent.no_implicit_prelude
847                        || ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude),
848                );
849                self.parent_scope.module = module.to_module();
850                if let Some(directive) = OnUnknownData::from_attrs(self.r, &item.attrs) {
851                    self.r.on_unknown_data.insert(local_def_id, directive);
852                }
853            }
854
855            // These items live in the value namespace.
856            ItemKind::Const(ConstItem { ident, .. })
857            | ItemKind::Delegation(Delegation { ident, .. })
858            | ItemKind::Static(StaticItem { ident, .. }) => {
859                self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion);
860            }
861            ItemKind::Fn(Fn { ident, .. }) => {
862                self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion);
863
864                // Functions introducing procedural macros reserve a slot
865                // in the macro namespace as well (see #52225).
866                self.define_macro(item, feed);
867            }
868
869            // These items live in the type namespace.
870            ItemKind::TyAlias(TyAlias { ident, .. })
871            | ItemKind::TraitAlias(TraitAlias { ident, .. }) => {
872                self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
873            }
874
875            ItemKind::Enum(ident, _, _) | ItemKind::Trait(ast::Trait { ident, .. }) => {
876                self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
877
878                let module = self.r.new_local_module(
879                    Some(parent),
880                    ModuleKind::Def(def_kind, def_id, item.id, Some(ident.name)),
881                    expansion.to_expn_id(),
882                    item.span,
883                    parent.no_implicit_prelude,
884                );
885                self.parent_scope.module = module.to_module();
886            }
887
888            // These items live in both the type and value namespaces.
889            ItemKind::Struct(ident, ref generics, ref vdata) => {
890                self.build_reduced_graph_for_struct_variant(
891                    vdata.fields(),
892                    ident,
893                    feed,
894                    res,
895                    vis,
896                    sp,
897                );
898
899                // If this is a tuple or unit struct, define a name
900                // in the value namespace as well.
901                if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(vdata) {
902                    // If the structure is marked as non_exhaustive then lower the visibility
903                    // to within the crate.
904                    let mut ctor_vis = if vis.is_public()
905                        && ast::attr::contains_name(&item.attrs, sym::non_exhaustive)
906                    {
907                        Visibility::Restricted(CRATE_DEF_ID)
908                    } else {
909                        vis
910                    };
911
912                    let mut field_visibilities = Vec::with_capacity(vdata.fields().len());
913
914                    for field in vdata.fields() {
915                        // NOTE: The field may be an expansion placeholder, but expansion sets
916                        // correct visibilities for unnamed field placeholders specifically, so the
917                        // constructor visibility should still be determined correctly.
918                        let field_vis = self
919                            .r
920                            .try_resolve_visibility(&self.parent_scope, &field.vis, false)
921                            .unwrap_or(Visibility::Public);
922                        if ctor_vis.greater_than(field_vis, self.r.tcx) {
923                            ctor_vis = field_vis;
924                        }
925                        field_visibilities.push(field_vis.to_def_id());
926                    }
927                    // If this is a unit or tuple-like struct, register the constructor.
928                    let feed = self.create_def(
929                        ctor_node_id,
930                        None,
931                        DefKind::Ctor(CtorOf::Struct, ctor_kind),
932                        item.span,
933                    );
934
935                    let ctor_def_id = feed.key();
936                    let ctor_res = self.res(ctor_def_id);
937                    self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion);
938                    self.r.feed_visibility(feed, ctor_vis);
939                    // We need the field visibility spans also for the constructor for E0603.
940                    self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata.fields());
941
942                    let ctor =
943                        StructCtor { res: ctor_res, vis: ctor_vis.to_def_id(), field_visibilities };
944                    self.r.struct_ctors.insert(local_def_id, ctor);
945                }
946                self.r.struct_generics.insert(local_def_id, generics.clone());
947            }
948
949            ItemKind::Union(ident, _, ref vdata) => {
950                self.build_reduced_graph_for_struct_variant(
951                    vdata.fields(),
952                    ident,
953                    feed,
954                    res,
955                    vis,
956                    sp,
957                );
958            }
959
960            // These items do not add names to modules.
961            ItemKind::Impl { .. }
962            | ItemKind::ForeignMod(..)
963            | ItemKind::GlobalAsm(..)
964            | ItemKind::ConstBlock(..) => {}
965
966            ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
967                ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
968            }
969        }
970    }
971
972    fn build_reduced_graph_for_extern_crate(
973        &mut self,
974        orig_name: Option<Symbol>,
975        item: &Item,
976        orig_ident: Ident,
977        local_def_id: LocalDefId,
978        vis: Visibility,
979    ) {
980        let sp = item.span;
981        let parent_scope = self.parent_scope;
982        let parent = parent_scope.module;
983        let expansion = parent_scope.expansion;
984
985        let (used, module, decl) = if orig_name.is_none() && orig_ident.name == kw::SelfLower {
986            self.r.dcx().emit_err(diagnostics::ExternCrateSelfRequiresRenaming { span: sp });
987            return;
988        } else if orig_name == Some(kw::SelfLower) {
989            Some(self.r.graph_root.to_module())
990        } else {
991            let tcx = self.r.tcx;
992            let crate_id = self.r.cstore_mut().process_extern_crate(
993                self.r.tcx,
994                item,
995                local_def_id,
996                &tcx.definitions_untracked(),
997            );
998            crate_id.map(|crate_id| {
999                self.r.extern_crate_map.insert(local_def_id, crate_id);
1000                self.r.expect_module(crate_id.as_def_id())
1001            })
1002        }
1003        .map(|module| {
1004            let used = self.process_macro_use_imports(item, module);
1005            let decl = self.r.arenas.new_pub_def_decl(module.res().unwrap(), sp, expansion);
1006            (used, Some(ModuleOrUniformRoot::Module(module)), decl)
1007        })
1008        .unwrap_or((true, None, self.r.dummy_decl));
1009        let import = self.r.arenas.alloc_import(ImportData {
1010            kind: ImportKind::ExternCrate {
1011                source: orig_name,
1012                target: orig_ident,
1013                id: item.id,
1014                def_id: local_def_id,
1015            },
1016            root_id: item.id,
1017            parent_scope,
1018            imported_module: CmCell::new(module),
1019            has_attributes: !item.attrs.is_empty(),
1020            use_span_with_attributes: item.span_with_attributes(),
1021            use_span: item.span,
1022            root_span: item.span,
1023            span: item.span,
1024            module_path: Vec::new(),
1025            vis,
1026            vis_span: item.vis.span,
1027            on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs),
1028        });
1029        if used {
1030            self.r.import_use_map.insert(import, Used::Other);
1031        }
1032        self.r.potentially_unused_imports.push(import);
1033        let import_decl = self.r.new_import_decl(decl, import);
1034        let ident = IdentKey::new(orig_ident);
1035        if ident.name != kw::Underscore && parent == self.r.graph_root.to_module() {
1036            // FIXME: this error is technically unnecessary now when extern prelude is split into
1037            // two scopes, remove it with lang team approval.
1038            if let Some(entry) = self.r.extern_prelude.get(&ident)
1039                && expansion != LocalExpnId::ROOT
1040                && orig_name.is_some()
1041                && entry.item_decl.is_none()
1042            {
1043                self.r.dcx().emit_err(
1044                    diagnostics::MacroExpandedExternCrateCannotShadowExternArguments {
1045                        span: item.span,
1046                    },
1047                );
1048            }
1049
1050            use indexmap::map::Entry;
1051            match self.r.extern_prelude.entry(ident) {
1052                Entry::Occupied(mut occupied) => {
1053                    let entry = occupied.get_mut();
1054                    if entry.item_decl.is_some() {
1055                        let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("extern crate `{0}` already in extern prelude",
                orig_ident))
    })format!("extern crate `{orig_ident}` already in extern prelude");
1056                        self.r.tcx.dcx().span_delayed_bug(item.span, msg);
1057                    } else {
1058                        entry.item_decl = Some((import_decl, orig_ident.span, orig_name.is_some()));
1059                    }
1060                    entry
1061                }
1062                Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry {
1063                    item_decl: Some((import_decl, orig_ident.span, true)),
1064                    flag_decl: None,
1065                }),
1066            };
1067        }
1068        self.r.plant_decl_into_local_module(ident, orig_ident.span, TypeNS, import_decl);
1069    }
1070
1071    /// Constructs the reduced graph for one foreign item.
1072    pub(crate) fn build_reduced_graph_for_foreign_item(
1073        &mut self,
1074        item: &ForeignItem,
1075        ident: Ident,
1076        feed: TyCtxtFeed<'tcx, LocalDefId>,
1077    ) {
1078        let local_def_id = feed.key();
1079        let def_id = local_def_id.to_def_id();
1080        let ns = match item.kind {
1081            ForeignItemKind::Fn(..) => ValueNS,
1082            ForeignItemKind::Static(..) => ValueNS,
1083            ForeignItemKind::TyAlias(..) => TypeNS,
1084            ForeignItemKind::MacCall(..) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1085        };
1086        let parent = self.parent_scope.module.expect_local();
1087        let expansion = self.parent_scope.expansion;
1088        let vis = self.resolve_visibility(&item.vis);
1089        self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion);
1090        self.r.feed_visibility(feed, vis);
1091    }
1092
1093    fn build_reduced_graph_for_block(&mut self, block: &Block) {
1094        let parent = self.parent_scope.module.expect_local();
1095        let expansion = self.parent_scope.expansion;
1096        if self.block_needs_anonymous_module(block) {
1097            let module = self.r.new_local_module(
1098                Some(parent),
1099                ModuleKind::Block,
1100                expansion.to_expn_id(),
1101                block.span,
1102                parent.no_implicit_prelude,
1103            );
1104            self.r.block_map.insert(block.id, module);
1105            self.parent_scope.module = module.to_module(); // Descend into the block.
1106        }
1107    }
1108
1109    fn add_macro_use_decl(
1110        &mut self,
1111        name: Symbol,
1112        decl: Decl<'ra>,
1113        span: Span,
1114        allow_shadowing: bool,
1115    ) {
1116        if self.r.macro_use_prelude.insert(name, decl).is_some() && !allow_shadowing {
1117            self.r.dcx().emit_err(diagnostics::MacroUseNameAlreadyInUse { span, name });
1118        }
1119    }
1120
1121    /// Returns `true` if we should consider the underlying `extern crate` to be used.
1122    fn process_macro_use_imports(&mut self, item: &Item, module: Module<'ra>) -> bool {
1123        let mut import_all = None;
1124        let mut single_imports = ThinVec::new();
1125        if let Some(Attribute::Parsed(AttributeKind::MacroUse { span, arguments })) =
1126            AttributeParser::parse_limited(self.r.tcx.sess, &item.attrs, &[sym::macro_use])
1127        {
1128            if self.parent_scope.module.expect_local().parent.is_some() {
1129                self.r.dcx().emit_err(diagnostics::ExternCrateLoadingMacroNotAtCrateRoot {
1130                    span: item.span,
1131                });
1132            }
1133            if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
1134                && orig_name == kw::SelfLower
1135            {
1136                self.r.dcx().emit_err(diagnostics::MacroUseExternCrateSelf { span });
1137            }
1138
1139            match arguments {
1140                MacroUseArgs::UseAll => import_all = Some(span),
1141                MacroUseArgs::UseSpecific(imports) => single_imports = imports,
1142            }
1143        }
1144
1145        let macro_use_import = |this: &Self, span, warn_private| {
1146            this.r.arenas.alloc_import(ImportData {
1147                kind: ImportKind::MacroUse { warn_private },
1148                root_id: item.id,
1149                parent_scope: this.parent_scope,
1150                imported_module: CmCell::new(Some(ModuleOrUniformRoot::Module(module))),
1151                use_span_with_attributes: item.span_with_attributes(),
1152                has_attributes: !item.attrs.is_empty(),
1153                use_span: item.span,
1154                root_span: span,
1155                span,
1156                module_path: Vec::new(),
1157                vis: Visibility::Restricted(CRATE_DEF_ID),
1158                vis_span: item.vis.span,
1159                on_unknown_attr: OnUnknownData::from_attrs(this.r, &item.attrs),
1160            })
1161        };
1162
1163        let allow_shadowing = self.parent_scope.expansion == LocalExpnId::ROOT;
1164        if let Some(span) = import_all {
1165            let import = macro_use_import(self, span, false);
1166            self.r.potentially_unused_imports.push(import);
1167            module.for_each_child_mut(self, |this, ident, _, ns, binding| {
1168                if ns == MacroNS {
1169                    let import =
1170                        if this.r.is_accessible_from(binding.vis(), this.parent_scope.module) {
1171                            import
1172                        } else {
1173                            // FIXME: This branch is used for reporting the `private_macro_use` lint
1174                            // and should eventually be removed.
1175                            if this.r.macro_use_prelude.contains_key(&ident.name) {
1176                                // Do not override already existing entries with compatibility entries.
1177                                return;
1178                            }
1179                            macro_use_import(this, span, true)
1180                        };
1181                    let import_decl = this.r.new_import_decl(binding, import);
1182                    this.add_macro_use_decl(ident.name, import_decl, span, allow_shadowing);
1183                }
1184            });
1185        } else {
1186            for ident in single_imports.iter().cloned() {
1187                let result = self.r.cm().maybe_resolve_ident_in_module(
1188                    ModuleOrUniformRoot::Module(module),
1189                    ident,
1190                    MacroNS,
1191                    &self.parent_scope,
1192                    None,
1193                );
1194                if let Ok(binding) = result {
1195                    let import = macro_use_import(self, ident.span, false);
1196                    self.r.potentially_unused_imports.push(import);
1197                    let import_decl = self.r.new_import_decl(binding, import);
1198                    self.add_macro_use_decl(ident.name, import_decl, ident.span, allow_shadowing);
1199                } else {
1200                    self.r.dcx().emit_err(diagnostics::ImportedMacroNotFound { span: ident.span });
1201                }
1202            }
1203        }
1204        import_all.is_some() || !single_imports.is_empty()
1205    }
1206
1207    /// Returns `true` if this attribute list contains `macro_use`.
1208    pub(crate) fn contains_macro_use(&self, attrs: &[ast::Attribute]) -> bool {
1209        for attr in attrs {
1210            if attr.has_name(sym::macro_escape) {
1211                let inner_attribute = #[allow(non_exhaustive_omitted_patterns)] match attr.style {
    ast::AttrStyle::Inner => true,
    _ => false,
}matches!(attr.style, ast::AttrStyle::Inner);
1212                self.r.dcx().emit_warn(diagnostics::MacroExternDeprecated {
1213                    span: attr.span,
1214                    inner_attribute,
1215                });
1216            } else if !attr.has_name(sym::macro_use) {
1217                continue;
1218            }
1219
1220            if !attr.is_word() {
1221                self.r.dcx().emit_err(diagnostics::ArgumentsMacroUseNotAllowed { span: attr.span });
1222            }
1223            return true;
1224        }
1225
1226        false
1227    }
1228
1229    pub(crate) fn visit_invoc(&mut self, id: NodeId) -> LocalExpnId {
1230        let invoc_id = id.placeholder_to_expn_id();
1231        let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
1232        if !old_parent_scope.is_none() {
    {
        ::core::panicking::panic_fmt(format_args!("invocation data is reset for an invocation"));
    }
};assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
1233        invoc_id
1234    }
1235
1236    /// Visit invocation in context in which it can emit a named item (possibly `macro_rules`)
1237    /// directly into its parent scope's module.
1238    pub(crate) fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> {
1239        let invoc_id = self.visit_invoc(id);
1240        let module = self.parent_scope.module.expect_local();
1241        module.unexpanded_invocations.borrow_mut(self.r).insert(invoc_id);
1242        self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
1243    }
1244
1245    fn proc_macro_stub(
1246        &self,
1247        item: &ast::Item,
1248        fn_ident: Ident,
1249    ) -> Option<(MacroKind, Ident, Span)> {
1250        if ast::attr::contains_name(&item.attrs, sym::proc_macro) {
1251            return Some((MacroKind::Bang, fn_ident, item.span));
1252        } else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
1253            return Some((MacroKind::Attr, fn_ident, item.span));
1254        } else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
1255            && let Some(meta_item_inner) =
1256                attr.meta_item_list().and_then(|list| list.get(0).cloned())
1257            && let Some(ident) = meta_item_inner.ident()
1258        {
1259            return Some((MacroKind::Derive, ident, ident.span));
1260        }
1261        None
1262    }
1263
1264    // Mark the given macro as unused unless its name starts with `_`.
1265    // Macro uses will remove items from this set, and the remaining
1266    // items will be reported as `unused_macros`.
1267    fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) {
1268        if !ident.as_str().starts_with('_') {
1269            self.r.unused_macros.insert(def_id, (node_id, ident));
1270            if let SyntaxExtensionKind::MacroRules(mr) = &self.r.local_macro_map[&def_id].kind {
1271                let value = (def_id, DenseBitSet::new_filled(mr.nrules()));
1272                self.r.unused_macro_rules.insert(node_id, value);
1273            }
1274        }
1275    }
1276
1277    fn define_macro(
1278        &mut self,
1279        item: &ast::Item,
1280        feed: TyCtxtFeed<'tcx, LocalDefId>,
1281    ) -> MacroRulesScopeRef<'ra> {
1282        let parent_scope = self.parent_scope;
1283        let expansion = parent_scope.expansion;
1284        let def_id = feed.key();
1285        let (res, orig_ident, span, macro_rules) = match &item.kind {
1286            ItemKind::MacroDef(ident, def) => {
1287                (self.res(def_id), *ident, item.span, def.macro_rules)
1288            }
1289            ItemKind::Fn(ast::Fn { ident: fn_ident, .. }) => {
1290                match self.proc_macro_stub(item, *fn_ident) {
1291                    Some((macro_kind, ident, span)) => {
1292                        let macro_kinds = macro_kind.into();
1293                        let res = Res::Def(DefKind::Macro(macro_kinds), def_id.to_def_id());
1294                        self.r.local_macro_map.insert(def_id, self.r.dummy_ext(macro_kind));
1295                        self.r.proc_macro_stubs.insert(def_id);
1296                        (res, ident, span, false)
1297                    }
1298                    None => return parent_scope.macro_rules,
1299                }
1300            }
1301            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1302        };
1303
1304        self.r.local_macro_def_scopes.insert(def_id, parent_scope.module.expect_local());
1305
1306        if macro_rules {
1307            let ident = IdentKey::new(orig_ident);
1308            self.r.macro_names.insert(ident);
1309            let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export);
1310            let vis = if is_macro_export {
1311                Visibility::Public
1312            } else {
1313                Visibility::Restricted(CRATE_DEF_ID)
1314            };
1315            let decl = self.r.arenas.new_def_decl(
1316                res,
1317                vis.to_def_id(),
1318                span,
1319                expansion,
1320                Some(parent_scope.module),
1321            );
1322            self.r.all_macro_rules.insert(ident.name);
1323            if is_macro_export {
1324                let import = self.r.arenas.alloc_import(ImportData {
1325                    kind: ImportKind::MacroExport,
1326                    root_id: item.id,
1327                    parent_scope: ParentScope {
1328                        module: self.r.graph_root.to_module(),
1329                        ..parent_scope
1330                    },
1331                    imported_module: CmCell::new(None),
1332                    has_attributes: false,
1333                    use_span_with_attributes: span,
1334                    use_span: span,
1335                    root_span: span,
1336                    span,
1337                    module_path: Vec::new(),
1338                    vis,
1339                    vis_span: item.vis.span,
1340                    on_unknown_attr: OnUnknownData::from_attrs(self.r, &item.attrs),
1341                });
1342                self.r.import_use_map.insert(import, Used::Other);
1343                let import_decl = self.r.new_import_decl(decl, import);
1344                self.r.plant_decl_into_local_module(ident, orig_ident.span, MacroNS, import_decl);
1345            } else {
1346                self.r.check_reserved_macro_name(ident.name, orig_ident.span, res);
1347                self.insert_unused_macro(orig_ident, def_id, item.id);
1348            }
1349            self.r.feed_visibility(feed, vis);
1350            let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Def(
1351                self.r.arenas.alloc_macro_rules_decl(MacroRulesDecl {
1352                    parent_macro_rules_scope: parent_scope.macro_rules,
1353                    decl,
1354                    ident,
1355                    orig_ident_span: orig_ident.span,
1356                }),
1357            ));
1358            self.r.macro_rules_scopes.insert(def_id, scope);
1359            scope
1360        } else {
1361            let module = parent_scope.module.expect_local();
1362            let vis = match item.kind {
1363                // Visibilities must not be resolved non-speculatively twice
1364                // and we already resolved this one as a `fn` item visibility.
1365                ItemKind::Fn(..) => self
1366                    .r
1367                    .try_resolve_visibility(&self.parent_scope, &item.vis, false)
1368                    .unwrap_or(Visibility::Public),
1369                _ => self.resolve_visibility(&item.vis),
1370            };
1371            if !vis.is_public() {
1372                self.insert_unused_macro(orig_ident, def_id, item.id);
1373            }
1374            self.r.define_local(module, orig_ident, MacroNS, res, vis, span, expansion);
1375            self.r.feed_visibility(feed, vis);
1376            self.parent_scope.macro_rules
1377        }
1378    }
1379}
1380
1381impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
1382    pub(crate) fn brg_visit_item(&mut self, item: &'a Item, feed: TyCtxtFeed<'tcx, LocalDefId>) {
1383        let orig_module_scope = self.parent_scope.module;
1384        self.parent_scope.macro_rules = match item.kind {
1385            ItemKind::MacroDef(..) => {
1386                let macro_rules_scope = self.define_macro(item, feed);
1387                visit::walk_item(self, item);
1388                macro_rules_scope
1389            }
1390            _ => {
1391                let orig_macro_rules_scope = self.parent_scope.macro_rules;
1392                self.build_reduced_graph_for_item(item, feed);
1393                match item.kind {
1394                    ItemKind::Mod(..) => {
1395                        // Visit attributes after items for backward compatibility.
1396                        // This way they can use `macro_rules` defined later.
1397                        self.visit_vis(&item.vis);
1398                        item.kind.walk(&item.attrs, item.span, item.id, &item.vis, (), self);
1399                        for elem in &item.attrs {
    match ::rustc_ast_ir::visit::VisitorResult::branch(self.visit_attribute(elem))
        {
        core::ops::ControlFlow::Continue(()) =>
            (),
            #[allow(unreachable_code)]
            core::ops::ControlFlow::Break(r) => {
            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
        }
    };
};visit::walk_list!(self, visit_attribute, &item.attrs);
1400                    }
1401                    _ => visit::walk_item(self, item),
1402                }
1403                match item.kind {
1404                    ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => {
1405                        self.parent_scope.macro_rules
1406                    }
1407                    _ => orig_macro_rules_scope,
1408                }
1409            }
1410        };
1411        self.parent_scope.module = orig_module_scope;
1412    }
1413
1414    /// Handle a macro call that itself can produce new `macro_rules` items
1415    /// in the current module.
1416    pub(crate) fn brg_visit_mac_call_in_module(&mut self, id: NodeId) {
1417        self.parent_scope.macro_rules = self.visit_invoc_in_module(id);
1418    }
1419
1420    pub(crate) fn brg_visit_block(&mut self, block: &'a Block) {
1421        let orig_current_module = self.parent_scope.module;
1422        let orig_current_macro_rules_scope = self.parent_scope.macro_rules;
1423        self.build_reduced_graph_for_block(block);
1424        visit::walk_block(self, block);
1425        self.parent_scope.module = orig_current_module;
1426        self.parent_scope.macro_rules = orig_current_macro_rules_scope;
1427    }
1428
1429    pub(crate) fn brg_visit_assoc_item(
1430        &mut self,
1431        item: &'a AssocItem,
1432        ctxt: AssocCtxt,
1433        ident: Ident,
1434        ns: Namespace,
1435        feed: TyCtxtFeed<'tcx, LocalDefId>,
1436    ) {
1437        let vis = self.resolve_visibility(&item.vis);
1438        let local_def_id = feed.key();
1439        let def_id = local_def_id.to_def_id();
1440
1441        if !(#[allow(non_exhaustive_omitted_patterns)] match ctxt {
    AssocCtxt::Impl { of_trait: true } => true,
    _ => false,
}matches!(ctxt, AssocCtxt::Impl { of_trait: true })
1442            && #[allow(non_exhaustive_omitted_patterns)] match item.vis.kind {
    ast::VisibilityKind::Inherited => true,
    _ => false,
}matches!(item.vis.kind, ast::VisibilityKind::Inherited))
1443        {
1444            // Trait impl item visibility is inherited from its trait when not specified
1445            // explicitly. In that case we cannot determine it here in early resolve,
1446            // so we leave a hole in the visibility table to be filled later.
1447            self.r.feed_visibility(feed, vis);
1448        }
1449
1450        if ctxt == AssocCtxt::Trait {
1451            let parent = self.parent_scope.module.expect_local();
1452            let expansion = self.parent_scope.expansion;
1453            self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion);
1454        } else if !#[allow(non_exhaustive_omitted_patterns)] match &item.kind {
    AssocItemKind::Delegation(d) if d.source == DelegationSource::Glob =>
        true,
    _ => false,
}matches!(&item.kind, AssocItemKind::Delegation(d) if d.source == DelegationSource::Glob)
1455            && ident.name != kw::Underscore
1456        {
1457            // Don't add underscore names, they cannot be looked up anyway.
1458            let impl_def_id = self.r.tcx.local_parent(local_def_id);
1459            let key = BindingKey::new(IdentKey::new(ident), ns);
1460            self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
1461        }
1462
1463        visit::walk_assoc_item(self, item, ctxt);
1464    }
1465
1466    pub(crate) fn visit_assoc_item_mac_call(
1467        &mut self,
1468        item: &'a Item<AssocItemKind>,
1469        ctxt: AssocCtxt,
1470    ) {
1471        match ctxt {
1472            AssocCtxt::Trait => {
1473                self.visit_invoc_in_module(item.id);
1474            }
1475            AssocCtxt::Impl { .. } => {
1476                let invoc_id = item.id.placeholder_to_expn_id();
1477                if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
1478                    self.r
1479                        .impl_unexpanded_invocations
1480                        .entry(self.r.invocation_parent(invoc_id))
1481                        .or_default()
1482                        .insert(invoc_id);
1483                }
1484                self.visit_invoc(item.id);
1485            }
1486        }
1487    }
1488
1489    pub(crate) fn brg_visit_field_def(
1490        &mut self,
1491        sf: &'a ast::FieldDef,
1492        feed: TyCtxtFeed<'tcx, LocalDefId>,
1493    ) {
1494        let vis = self.resolve_visibility(&sf.vis);
1495        self.r.feed_visibility(feed, vis);
1496        visit::walk_field_def(self, sf);
1497    }
1498
1499    // Constructs the reduced graph for one variant. Variants exist in the
1500    // type and value namespaces.
1501    pub(crate) fn brg_visit_variant(
1502        &mut self,
1503        variant: &'a ast::Variant,
1504        feed: TyCtxtFeed<'tcx, LocalDefId>,
1505    ) {
1506        let parent = self.parent_scope.module.expect_local();
1507        let expn_id = self.parent_scope.expansion;
1508        let ident = variant.ident;
1509
1510        // Define a name in the type namespace.
1511        let def_id = feed.key();
1512        let vis = self.resolve_visibility(&variant.vis);
1513        self.r.define_local(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id);
1514        self.r.feed_visibility(feed, vis);
1515
1516        // If the variant is marked as non_exhaustive then lower the visibility to within the crate.
1517        let ctor_vis =
1518            if vis.is_public() && ast::attr::contains_name(&variant.attrs, sym::non_exhaustive) {
1519                Visibility::Restricted(CRATE_DEF_ID)
1520            } else {
1521                vis
1522            };
1523
1524        // Define a constructor name in the value namespace.
1525        if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) {
1526            let feed = self.create_def(
1527                ctor_node_id,
1528                None,
1529                DefKind::Ctor(CtorOf::Variant, ctor_kind),
1530                variant.span,
1531            );
1532            let ctor_def_id = feed.key();
1533            let ctor_res = self.res(ctor_def_id);
1534            self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id);
1535            self.r.feed_visibility(feed, ctor_vis);
1536        }
1537
1538        // Record field names for error reporting.
1539        self.insert_field_idents(def_id, variant.data.fields());
1540        self.insert_field_visibilities_local(def_id.to_def_id(), variant.data.fields());
1541
1542        visit::walk_variant(self, variant);
1543    }
1544}