1use std::sync::Arc;
9
10use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
11use rustc_ast::{
12 self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
13 ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, TyAlias,
14};
15use rustc_attr_parsing as attr;
16use rustc_attr_parsing::AttributeParser;
17use rustc_expand::base::ResolverExpand;
18use rustc_expand::expand::AstFragment;
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::{Feed, 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::collect_definitions;
35use crate::diagnostics::StructCtor;
36use crate::imports::{ImportData, ImportKind, OnUnknownData};
37use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
38use crate::ref_mut::CmCell;
39use crate::{
40 BindingKey, Decl, DeclData, DeclKind, ExternModule, ExternPreludeEntry, Finalize, IdentKey,
41 LocalModule, MacroData, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, Res,
42 ResolutionError, Resolver, Segment, Used, VisResolutionError, errors,
43};
44
45impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
46 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, false)
57 {
58 self.report_conflict(ident, ns, old_decl, decl);
59 }
60 }
61
62 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 fn define_extern(
81 &self,
82 parent: ExternModule<'ra>,
83 ident: IdentKey,
84 orig_ident_span: Span,
85 ns: Namespace,
86 child_index: usize,
87 res: Res,
88 vis: Visibility<DefId>,
89 span: Span,
90 expansion: LocalExpnId,
91 ambiguity: Option<Decl<'ra>>,
92 ) {
93 let decl = self.arenas.alloc_decl(DeclData {
94 kind: DeclKind::Def(res),
95 ambiguity: CmCell::new(ambiguity),
96 warn_ambiguity: CmCell::new(true),
98 vis: CmCell::new(vis),
99 span,
100 expansion,
101 parent_module: Some(parent.to_module()),
102 });
103 let key =
107 BindingKey::new_disambiguated(ident, ns, || (child_index + 1).try_into().unwrap()); if self
109 .resolution_or_default(parent.to_module(), key, orig_ident_span)
110 .borrow_mut_unchecked()
111 .non_glob_decl
112 .replace(decl)
113 .is_some()
114 {
115 ::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");
116 }
117 }
118
119 pub(crate) fn get_nearest_non_block_module(&self, mut def_id: DefId) -> Module<'ra> {
136 loop {
137 match self.get_module(def_id) {
138 Some(module) => return module,
139 None => def_id = self.tcx.parent(def_id),
140 }
141 }
142 }
143
144 pub(crate) fn expect_module(&self, def_id: DefId) -> Module<'ra> {
145 self.get_module(def_id).expect("argument `DefId` is not a module")
146 }
147
148 pub(crate) fn get_module(&self, def_id: DefId) -> Option<Module<'ra>> {
152 match def_id.as_local() {
153 Some(local_def_id) => self.local_module_map.get(&local_def_id).map(|m| m.to_module()),
154 None => {
155 if let module @ Some(..) = self.extern_module_map.borrow().get(&def_id) {
156 return module.map(|m| m.to_module());
157 }
158
159 let def_kind = self.cstore().def_kind_untracked(self.tcx, def_id);
161 if def_kind.is_module_like() {
162 let parent = self.tcx.opt_parent(def_id).map(|parent_id| {
163 self.get_nearest_non_block_module(parent_id).expect_extern()
164 });
165 let expn_id = self.cstore().expn_that_defined_untracked(self.tcx, def_id);
168 let module = self.new_extern_module(
169 parent,
170 ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
171 expn_id,
172 self.def_span(def_id),
173 parent.is_some_and(|module| module.no_implicit_prelude),
175 );
176 return Some(module.to_module());
177 }
178
179 None
180 }
181 }
182 }
183
184 pub(crate) fn expn_def_scope(&self, expn_id: ExpnId) -> Module<'ra> {
185 match expn_id.expn_data().macro_def_id {
186 Some(def_id) => self.macro_def_scope(def_id),
187 None => expn_id
188 .as_local()
189 .and_then(|expn_id| self.ast_transform_scopes.get(&expn_id).copied())
190 .unwrap_or(self.graph_root)
191 .to_module(),
192 }
193 }
194
195 pub(crate) fn macro_def_scope(&self, def_id: DefId) -> Module<'ra> {
196 if let Some(id) = def_id.as_local() {
197 self.local_macro_def_scopes[&id].to_module()
198 } else {
199 self.get_nearest_non_block_module(def_id)
200 }
201 }
202
203 pub(crate) fn get_macro(&self, res: Res) -> Option<&'ra MacroData> {
204 match res {
205 Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
206 Res::NonMacroAttr(_) => Some(self.non_macro_attr),
207 _ => None,
208 }
209 }
210
211 pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra MacroData {
212 match def_id.as_local() {
214 Some(local_def_id) => self.local_macro_map[&local_def_id],
215 None => *self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| {
216 let loaded_macro = self.cstore().load_macro_untracked(self.tcx, def_id);
217 let macro_data = match loaded_macro {
218 LoadedMacro::MacroDef { def, ident, attrs, span, edition } => {
219 self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition)
220 }
221 LoadedMacro::ProcMacro(ext) => MacroData::new(Arc::new(ext)),
222 };
223
224 self.arenas.alloc_macro(macro_data)
225 }),
226 }
227 }
228
229 pub(crate) fn register_macros_for_all_crates(&mut self) {
232 if !self.all_crate_macros_already_registered {
233 for def_id in self.cstore().all_proc_macro_def_ids(self.tcx) {
234 self.get_macro_by_def_id(def_id);
235 }
236 self.all_crate_macros_already_registered = true;
237 }
238 }
239
240 pub(crate) fn build_reduced_graph(
241 &mut self,
242 fragment: &AstFragment,
243 parent_scope: ParentScope<'ra>,
244 ) -> MacroRulesScopeRef<'ra> {
245 collect_definitions(self, fragment, parent_scope.expansion);
246 let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
247 fragment.visit_with(&mut visitor);
248 visitor.parent_scope.macro_rules
249 }
250
251 pub(crate) fn build_reduced_graph_external(&self, module: ExternModule<'ra>) {
252 let def_id = module.def_id();
253 let children = self.tcx.module_children(def_id);
254 let parent_scope = ParentScope::module(module.to_module(), self.arenas);
255 for (i, child) in children.iter().enumerate() {
256 self.build_reduced_graph_for_external_crate_res(child, parent_scope, i, None)
257 }
258 for (i, child) in
259 self.cstore().ambig_module_children_untracked(self.tcx, def_id).enumerate()
260 {
261 self.build_reduced_graph_for_external_crate_res(
262 &child.main,
263 parent_scope,
264 children.len() + i,
265 Some(&child.second),
266 )
267 }
268 }
269
270 fn build_reduced_graph_for_external_crate_res(
272 &self,
273 child: &ModChild,
274 parent_scope: ParentScope<'ra>,
275 child_index: usize,
276 ambig_child: Option<&ModChild>,
277 ) {
278 let parent = parent_scope.module.expect_extern();
279 let child_span = |this: &Self, reexport_chain: &[Reexport], res: def::Res<_>| {
280 this.def_span(
281 reexport_chain
282 .first()
283 .and_then(|reexport| reexport.id())
284 .unwrap_or_else(|| res.def_id()),
285 )
286 };
287 let ModChild { ident: orig_ident, res, vis, ref reexport_chain } = *child;
288 let ident = IdentKey::new(orig_ident);
289 let span = child_span(self, reexport_chain, res);
290 let res = res.expect_non_local();
291 let expansion = parent_scope.expansion;
292 let ambig = ambig_child.map(|ambig_child| {
293 let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child;
294 let span = child_span(self, reexport_chain, res);
295 let res = res.expect_non_local();
296 self.arenas.new_def_decl(res, vis, span, expansion, Some(parent.to_module()))
297 });
298
299 let define_extern = |ns| {
301 self.define_extern(
302 parent,
303 ident,
304 orig_ident.span,
305 ns,
306 child_index,
307 res,
308 vis,
309 span,
310 expansion,
311 ambig,
312 )
313 };
314 match res {
315 Res::Def(
316 DefKind::Mod
317 | DefKind::Enum
318 | DefKind::Trait
319 | DefKind::Struct
320 | DefKind::Union
321 | DefKind::Variant
322 | DefKind::TyAlias
323 | DefKind::ForeignTy
324 | DefKind::OpaqueTy
325 | DefKind::TraitAlias
326 | DefKind::AssocTy,
327 _,
328 )
329 | Res::PrimTy(..)
330 | Res::ToolMod => define_extern(TypeNS),
331 Res::Def(
332 DefKind::Fn
333 | DefKind::AssocFn
334 | DefKind::Static { .. }
335 | DefKind::Const { .. }
336 | DefKind::AssocConst { .. }
337 | DefKind::Ctor(..),
338 _,
339 ) => define_extern(ValueNS),
340 Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => define_extern(MacroNS),
341 Res::Def(
342 DefKind::TyParam
343 | DefKind::ConstParam
344 | DefKind::ExternCrate
345 | DefKind::Use
346 | DefKind::ForeignMod
347 | DefKind::AnonConst
348 | DefKind::InlineConst
349 | DefKind::Field
350 | DefKind::LifetimeParam
351 | DefKind::GlobalAsm
352 | DefKind::Closure
353 | DefKind::SyntheticCoroutineBody
354 | DefKind::Impl { .. },
355 _,
356 )
357 | Res::Local(..)
358 | Res::SelfTyParam { .. }
359 | Res::SelfTyAlias { .. }
360 | Res::SelfCtor(..)
361 | Res::OpenMod(..)
362 | Res::Err => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected resolution: {0:?}",
res))bug!("unexpected resolution: {:?}", res),
363 }
364 }
365}
366
367struct BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
368 r: &'a mut Resolver<'ra, 'tcx>,
369 parent_scope: ParentScope<'ra>,
370}
371
372impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for BuildReducedGraphVisitor<'_, 'ra, 'tcx> {
373 fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
374 self.r
375 }
376}
377
378impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
379 fn res(&self, def_id: impl Into<DefId>) -> Res {
380 let def_id = def_id.into();
381 Res::Def(self.r.tcx.def_kind(def_id), def_id)
382 }
383
384 fn resolve_visibility(&mut self, vis: &ast::Visibility) -> Visibility {
385 self.try_resolve_visibility(vis, true).unwrap_or_else(|err| {
386 self.r.report_vis_error(err);
387 Visibility::Public
388 })
389 }
390
391 fn try_resolve_visibility<'ast>(
392 &mut self,
393 vis: &'ast ast::Visibility,
394 finalize: bool,
395 ) -> Result<Visibility, VisResolutionError<'ast>> {
396 let parent_scope = &self.parent_scope;
397 match vis.kind {
398 ast::VisibilityKind::Public => Ok(Visibility::Public),
399 ast::VisibilityKind::Inherited => {
400 Ok(match self.parent_scope.module.kind {
401 ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => {
405 self.r.tcx.visibility(def_id).expect_local()
406 }
407 _ => Visibility::Restricted(
409 self.parent_scope.module.nearest_parent_mod().expect_local(),
410 ),
411 })
412 }
413 ast::VisibilityKind::Restricted { ref path, id, .. } => {
414 let ident = path.segments.get(0).expect("empty path in visibility").ident;
419 let crate_root = if ident.is_path_segment_keyword() {
420 None
421 } else if ident.span.is_rust_2015() {
422 Some(Segment::from_ident(Ident::new(
423 kw::PathRoot,
424 path.span.shrink_to_lo().with_ctxt(ident.span.ctxt()),
425 )))
426 } else {
427 return Err(VisResolutionError::Relative2018(ident.span, path));
428 };
429
430 let segments = crate_root
431 .into_iter()
432 .chain(path.segments.iter().map(|seg| seg.into()))
433 .collect::<Vec<_>>();
434 let expected_found_error = |res| {
435 Err(VisResolutionError::ExpectedFound(
436 path.span,
437 Segment::names_to_string(&segments),
438 res,
439 ))
440 };
441 match self.r.cm().resolve_path(
442 &segments,
443 None,
444 parent_scope,
445 finalize.then(|| Finalize::new(id, path.span)),
446 None,
447 None,
448 ) {
449 PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
450 let res = module.res().expect("visibility resolved to unnamed block");
451 if finalize {
452 self.r.record_partial_res(id, PartialRes::new(res));
453 }
454 if module.is_normal() {
455 match res {
456 Res::Err => Ok(Visibility::Public),
457 _ => {
458 let vis = Visibility::Restricted(res.def_id());
459 if self.r.is_accessible_from(vis, parent_scope.module) {
460 Ok(vis.expect_local())
461 } else {
462 Err(VisResolutionError::AncestorOnly(path.span))
463 }
464 }
465 }
466 } else {
467 expected_found_error(res)
468 }
469 }
470 PathResult::Module(..) => Err(VisResolutionError::ModuleOnly(path.span)),
471 PathResult::NonModule(partial_res) => {
472 expected_found_error(partial_res.expect_full_res())
473 }
474 PathResult::Failed {
475 span, label, suggestion, message, segment_name, ..
476 } => Err(VisResolutionError::FailedToResolve(
477 span,
478 segment_name,
479 label,
480 suggestion,
481 message,
482 )),
483 PathResult::Indeterminate => Err(VisResolutionError::Indeterminate(path.span)),
484 }
485 }
486 }
487 }
488
489 fn insert_field_idents(&mut self, def_id: LocalDefId, fields: &[ast::FieldDef]) {
490 if fields.iter().any(|field| field.is_placeholder) {
491 return;
493 }
494 let field_name = |i, field: &ast::FieldDef| {
495 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))
496 };
497 let field_names: Vec<_> =
498 fields.iter().enumerate().map(|(i, field)| field_name(i, field)).collect();
499 let defaults = fields
500 .iter()
501 .enumerate()
502 .filter_map(|(i, field)| field.default.as_ref().map(|_| field_name(i, field).name))
503 .collect();
504 self.r.field_names.insert(def_id, field_names);
505 self.r.field_defaults.insert(def_id, defaults);
506 }
507
508 fn insert_field_visibilities_local(&mut self, def_id: DefId, fields: &[ast::FieldDef]) {
509 let field_vis = fields
510 .iter()
511 .map(|field| field.vis.span.until(field.ident.map_or(field.ty.span, |i| i.span)))
512 .collect();
513 self.r.field_visibility_spans.insert(def_id, field_vis);
514 }
515
516 fn block_needs_anonymous_module(&self, block: &Block) -> bool {
517 block
519 .stmts
520 .iter()
521 .any(|statement| #[allow(non_exhaustive_omitted_patterns)] match statement.kind {
StmtKind::Item(_) | StmtKind::MacCall(_) => true,
_ => false,
}matches!(statement.kind, StmtKind::Item(_) | StmtKind::MacCall(_)))
522 }
523
524 fn add_import(
526 &mut self,
527 module_path: Vec<Segment>,
528 kind: ImportKind<'ra>,
529 span: Span,
530 item: &ast::Item,
531 root_span: Span,
532 root_id: NodeId,
533 vis: Visibility,
534 ) {
535 let current_module = self.parent_scope.module;
536 let import = self.r.arenas.alloc_import(ImportData {
537 kind,
538 parent_scope: self.parent_scope,
539 module_path,
540 imported_module: CmCell::new(None),
541 span,
542 use_span: item.span,
543 use_span_with_attributes: item.span_with_attributes(),
544 has_attributes: !item.attrs.is_empty(),
545 root_span,
546 root_id,
547 vis,
548 vis_span: item.vis.span,
549 on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, item),
550 });
551
552 self.r.indeterminate_imports.push(import);
553 match import.kind {
554 ImportKind::Single { target, type_ns_only, .. } => {
555 if target.name != kw::Underscore {
558 self.r.per_ns(|this, ns| {
559 if !type_ns_only || ns == TypeNS {
560 let key = BindingKey::new(IdentKey::new(target), ns);
561 this.resolution_or_default(current_module, key, target.span)
562 .borrow_mut(this)
563 .single_imports
564 .insert(import);
565 }
566 });
567 }
568 }
569 ImportKind::Glob { .. } => current_module.globs.borrow_mut(self.r).push(import),
570 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
571 }
572 }
573
574 fn build_reduced_graph_for_use_tree(
575 &mut self,
576 use_tree: &ast::UseTree,
578 id: NodeId,
579 parent_prefix: &[Segment],
580 nested: bool,
581 list_stem: bool,
582 item: &Item,
584 vis: Visibility,
585 root_span: Span,
586 ) {
587 {
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:587",
"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(587u32),
::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!(
588 "build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
589 parent_prefix, use_tree, nested
590 );
591
592 if nested && !list_stem {
595 self.r.feed_visibility(self.r.feed(id), vis);
596 }
597
598 let mut prefix_iter = parent_prefix
599 .iter()
600 .cloned()
601 .chain(use_tree.prefix.segments.iter().map(|seg| seg.into()))
602 .peekable();
603
604 let crate_root = match prefix_iter.peek() {
609 Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.is_rust_2015() => {
610 Some(seg.ident.span.ctxt())
611 }
612 None if let ast::UseTreeKind::Glob(span) = use_tree.kind
613 && span.is_rust_2015() =>
614 {
615 Some(span.ctxt())
616 }
617 _ => None,
618 }
619 .map(|ctxt| {
620 Segment::from_ident(Ident::new(
621 kw::PathRoot,
622 use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt),
623 ))
624 });
625
626 let prefix = crate_root.into_iter().chain(prefix_iter).collect::<Vec<_>>();
627 {
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:627",
"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(627u32),
::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);
628
629 match use_tree.kind {
630 ast::UseTreeKind::Simple(rename) => {
631 let mut module_path = prefix;
632 let source = module_path.pop().unwrap();
633
634 let type_ns_only = nested && source.ident.name == kw::SelfLower;
636
637 if source.ident.name == kw::SelfLower
639 && let Some(parent) = module_path.last()
640 && !type_ns_only
641 && (parent.ident.name != kw::PathRoot
642 || self.r.path_root_is_crate_root(parent.ident))
643 {
644 let span_with_rename = match rename {
645 Some(rename) => source.ident.span.to(rename.span),
646 None => source.ident.span,
647 };
648
649 self.r.report_error(
650 parent.ident.span.shrink_to_hi().to(source.ident.span),
651 ResolutionError::SelfImportsOnlyAllowedWithin {
652 root: parent.ident.name == kw::PathRoot,
653 span_with_rename,
654 },
655 );
656 }
657
658 let ident = if source.ident.name == kw::SelfLower
659 && rename.is_none()
660 && let Some(parent) = module_path.last()
661 {
662 Ident::new(parent.ident.name, source.ident.span)
663 } else {
664 use_tree.ident()
665 };
666
667 match source.ident.name {
668 kw::DollarCrate => {
669 if !module_path.is_empty() {
670 self.r.dcx().span_err(
671 source.ident.span,
672 "`$crate` in paths can only be used in start position",
673 );
674 return;
675 }
676 }
677 kw::Crate => {
678 if !module_path.is_empty() {
679 self.r.dcx().span_err(
680 source.ident.span,
681 "`crate` in paths can only be used in start position",
682 );
683 return;
684 }
685 }
686 kw::Super => {
687 let valid_prefix = module_path.iter().enumerate().all(|(i, seg)| {
690 let name = seg.ident.name;
691 name == kw::Super || (name == kw::SelfLower && i == 0)
692 });
693
694 if !valid_prefix {
695 self.r.dcx().span_err(
696 source.ident.span,
697 "`super` in paths can only be used in start position, after `self`, or after another `super`",
698 );
699 return;
700 }
701 }
702 kw::SelfLower
704 if let Some(parent) = module_path.last()
705 && parent.ident.name == kw::PathRoot
706 && !self.r.path_root_is_crate_root(parent.ident) =>
707 {
708 self.r.dcx().span_err(use_tree.span(), "extern prelude cannot be imported");
709 return;
710 }
711 _ => {}
712 }
713
714 if rename.is_none() && ident.is_path_segment_keyword() {
716 let ident = use_tree.ident();
717
718 let sugg = if !type_ns_only && ident.name == kw::SelfLower {
721 None
722 } else {
723 Some(errors::UnnamedImportSugg { span: ident.span, ident })
724 };
725
726 self.r.dcx().emit_err(errors::UnnamedImport { span: ident.span, sugg });
727 return;
728 }
729
730 let kind = ImportKind::Single {
731 source: source.ident,
732 target: ident,
733 decls: Default::default(),
734 type_ns_only,
735 nested,
736 id,
737 };
738
739 self.add_import(module_path, kind, use_tree.span(), item, root_span, item.id, vis);
740 }
741 ast::UseTreeKind::Glob(_) => {
742 if !ast::attr::contains_name(&item.attrs, sym::prelude_import) {
743 let kind = ImportKind::Glob { max_vis: CmCell::new(None), id };
744 self.add_import(prefix, kind, use_tree.span(), item, root_span, item.id, vis);
745 } else {
746 let path_res =
748 self.r.cm().maybe_resolve_path(&prefix, None, &self.parent_scope, None);
749 if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = path_res {
750 self.r.prelude = Some(module);
751 } else {
752 self.r.dcx().span_err(use_tree.span(), "cannot resolve a prelude import");
753 }
754 }
755 }
756 ast::UseTreeKind::Nested { ref items, .. } => {
757 for &(ref tree, id) in items {
758 self.build_reduced_graph_for_use_tree(
759 tree, id, &prefix, true, false, item, vis, root_span,
762 );
763 }
764
765 if items.is_empty()
769 && !prefix.is_empty()
770 && (prefix.len() > 1 || prefix[0].ident.name != kw::PathRoot)
771 {
772 let new_span = prefix[prefix.len() - 1].ident.span;
773 let tree = ast::UseTree {
774 prefix: ast::Path::from_ident(Ident::new(kw::SelfLower, new_span)),
775 kind: ast::UseTreeKind::Simple(Some(Ident::new(kw::Underscore, new_span))),
776 };
777 self.build_reduced_graph_for_use_tree(
778 &tree,
780 id,
781 &prefix,
782 true,
783 true,
784 item,
786 Visibility::Restricted(
787 self.parent_scope.module.nearest_parent_mod().expect_local(),
788 ),
789 root_span,
790 );
791 }
792 }
793 }
794 }
795
796 fn build_reduced_graph_for_struct_variant(
797 &mut self,
798 fields: &[ast::FieldDef],
799 ident: Ident,
800 feed: Feed<'tcx, LocalDefId>,
801 adt_res: Res,
802 adt_vis: Visibility,
803 adt_span: Span,
804 ) {
805 let parent_scope = &self.parent_scope;
806 let parent = parent_scope.module.expect_local();
807 let expansion = parent_scope.expansion;
808
809 self.r.define_local(parent, ident, TypeNS, adt_res, adt_vis, adt_span, expansion);
811 self.r.feed_visibility(feed, adt_vis);
812 let def_id = feed.key();
813
814 self.insert_field_idents(def_id, fields);
816 self.insert_field_visibilities_local(def_id.to_def_id(), fields);
817 }
818
819 fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
821 let parent_scope = &self.parent_scope;
822 let parent = parent_scope.module.expect_local();
823 let expansion = parent_scope.expansion;
824 let sp = item.span;
825 let vis = self.resolve_visibility(&item.vis);
826 let feed = self.r.feed(item.id);
827 let local_def_id = feed.key();
828 let def_id = local_def_id.to_def_id();
829 let def_kind = self.r.tcx.def_kind(def_id);
830 let res = Res::Def(def_kind, def_id);
831
832 self.r.feed_visibility(feed, vis);
833
834 match item.kind {
835 ItemKind::Use(ref use_tree) => {
836 self.build_reduced_graph_for_use_tree(
837 use_tree,
839 item.id,
840 &[],
841 false,
842 false,
843 item,
845 vis,
846 use_tree.span(),
847 );
848 }
849
850 ItemKind::ExternCrate(orig_name, ident) => {
851 self.build_reduced_graph_for_extern_crate(
852 orig_name,
853 item,
854 ident,
855 local_def_id,
856 vis,
857 );
858 }
859
860 ItemKind::Mod(_, ident, ref mod_kind) => {
861 self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
862
863 if let ast::ModKind::Loaded(_, Inline::No { had_parse_error: Err(_) }, _) = mod_kind
864 {
865 self.r.mods_with_parse_errors.insert(def_id);
866 }
867 let module = self.r.new_local_module(
868 Some(parent),
869 ModuleKind::Def(def_kind, def_id, Some(ident.name)),
870 expansion.to_expn_id(),
871 item.span,
872 parent.no_implicit_prelude
873 || ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude),
874 );
875 self.parent_scope.module = module.to_module();
876 }
877
878 ItemKind::Const(box ConstItem { ident, .. })
880 | ItemKind::Delegation(box Delegation { ident, .. })
881 | ItemKind::Static(box StaticItem { ident, .. }) => {
882 self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion);
883 }
884 ItemKind::Fn(box Fn { ident, .. }) => {
885 self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion);
886
887 self.define_macro(item);
890 }
891
892 ItemKind::TyAlias(box TyAlias { ident, .. })
894 | ItemKind::TraitAlias(box TraitAlias { ident, .. }) => {
895 self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
896 }
897
898 ItemKind::Enum(ident, _, _) | ItemKind::Trait(box ast::Trait { ident, .. }) => {
899 self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
900
901 let module = self.r.new_local_module(
902 Some(parent),
903 ModuleKind::Def(def_kind, def_id, Some(ident.name)),
904 expansion.to_expn_id(),
905 item.span,
906 parent.no_implicit_prelude,
907 );
908 self.parent_scope.module = module.to_module();
909 }
910
911 ItemKind::Struct(ident, ref generics, ref vdata) => {
913 self.build_reduced_graph_for_struct_variant(
914 vdata.fields(),
915 ident,
916 feed,
917 res,
918 vis,
919 sp,
920 );
921
922 if let Some(ctor_node_id) = vdata.ctor_node_id() {
925 let mut ctor_vis = if vis.is_public()
928 && ast::attr::contains_name(&item.attrs, sym::non_exhaustive)
929 {
930 Visibility::Restricted(CRATE_DEF_ID)
931 } else {
932 vis
933 };
934
935 let mut field_visibilities = Vec::with_capacity(vdata.fields().len());
936
937 for field in vdata.fields() {
938 let field_vis = self
942 .try_resolve_visibility(&field.vis, false)
943 .unwrap_or(Visibility::Public);
944 if ctor_vis.is_at_least(field_vis, self.r.tcx) {
945 ctor_vis = field_vis;
946 }
947 field_visibilities.push(field_vis.to_def_id());
948 }
949 let feed = self.r.feed(ctor_node_id);
950 let ctor_def_id = feed.key();
951 let ctor_res = self.res(ctor_def_id);
952 self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion);
953 self.r.feed_visibility(feed, ctor_vis);
954 self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata.fields());
956
957 let ctor =
958 StructCtor { res: ctor_res, vis: ctor_vis.to_def_id(), field_visibilities };
959 self.r.struct_ctors.insert(local_def_id, ctor);
960 }
961 self.r.struct_generics.insert(local_def_id, generics.clone());
962 }
963
964 ItemKind::Union(ident, _, ref vdata) => {
965 self.build_reduced_graph_for_struct_variant(
966 vdata.fields(),
967 ident,
968 feed,
969 res,
970 vis,
971 sp,
972 );
973 }
974
975 ItemKind::Impl { .. }
977 | ItemKind::ForeignMod(..)
978 | ItemKind::GlobalAsm(..)
979 | ItemKind::ConstBlock(..) => {}
980
981 ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
982 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
983 }
984 }
985 }
986
987 fn build_reduced_graph_for_extern_crate(
988 &mut self,
989 orig_name: Option<Symbol>,
990 item: &Item,
991 orig_ident: Ident,
992 local_def_id: LocalDefId,
993 vis: Visibility,
994 ) {
995 let sp = item.span;
996 let parent_scope = self.parent_scope;
997 let parent = parent_scope.module;
998 let expansion = parent_scope.expansion;
999
1000 let (used, module, decl) = if orig_name.is_none() && orig_ident.name == kw::SelfLower {
1001 self.r.dcx().emit_err(errors::ExternCrateSelfRequiresRenaming { span: sp });
1002 return;
1003 } else if orig_name == Some(kw::SelfLower) {
1004 Some(self.r.graph_root.to_module())
1005 } else {
1006 let tcx = self.r.tcx;
1007 let crate_id = self.r.cstore_mut().process_extern_crate(
1008 self.r.tcx,
1009 item,
1010 local_def_id,
1011 &tcx.definitions_untracked(),
1012 );
1013 crate_id.map(|crate_id| {
1014 self.r.extern_crate_map.insert(local_def_id, crate_id);
1015 self.r.expect_module(crate_id.as_def_id())
1016 })
1017 }
1018 .map(|module| {
1019 let used = self.process_macro_use_imports(item, module);
1020 let decl = self.r.arenas.new_pub_def_decl(module.res().unwrap(), sp, expansion);
1021 (used, Some(ModuleOrUniformRoot::Module(module)), decl)
1022 })
1023 .unwrap_or((true, None, self.r.dummy_decl));
1024 let import = self.r.arenas.alloc_import(ImportData {
1025 kind: ImportKind::ExternCrate { source: orig_name, target: orig_ident, id: item.id },
1026 root_id: item.id,
1027 parent_scope,
1028 imported_module: CmCell::new(module),
1029 has_attributes: !item.attrs.is_empty(),
1030 use_span_with_attributes: item.span_with_attributes(),
1031 use_span: item.span,
1032 root_span: item.span,
1033 span: item.span,
1034 module_path: Vec::new(),
1035 vis,
1036 vis_span: item.vis.span,
1037 on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, item),
1038 });
1039 if used {
1040 self.r.import_use_map.insert(import, Used::Other);
1041 }
1042 self.r.potentially_unused_imports.push(import);
1043 let import_decl = self.r.new_import_decl(decl, import);
1044 let ident = IdentKey::new(orig_ident);
1045 if ident.name != kw::Underscore && parent == self.r.graph_root.to_module() {
1046 if let Some(entry) = self.r.extern_prelude.get(&ident)
1049 && expansion != LocalExpnId::ROOT
1050 && orig_name.is_some()
1051 && entry.item_decl.is_none()
1052 {
1053 self.r.dcx().emit_err(
1054 errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
1055 );
1056 }
1057
1058 use indexmap::map::Entry;
1059 match self.r.extern_prelude.entry(ident) {
1060 Entry::Occupied(mut occupied) => {
1061 let entry = occupied.get_mut();
1062 if entry.item_decl.is_some() {
1063 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");
1064 self.r.tcx.dcx().span_delayed_bug(item.span, msg);
1065 } else {
1066 entry.item_decl = Some((import_decl, orig_ident.span, orig_name.is_some()));
1067 }
1068 entry
1069 }
1070 Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry {
1071 item_decl: Some((import_decl, orig_ident.span, true)),
1072 flag_decl: None,
1073 }),
1074 };
1075 }
1076 self.r.plant_decl_into_local_module(ident, orig_ident.span, TypeNS, import_decl);
1077 }
1078
1079 fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, ident: Ident) {
1081 let feed = self.r.feed(item.id);
1082 let local_def_id = feed.key();
1083 let def_id = local_def_id.to_def_id();
1084 let ns = match item.kind {
1085 ForeignItemKind::Fn(..) => ValueNS,
1086 ForeignItemKind::Static(..) => ValueNS,
1087 ForeignItemKind::TyAlias(..) => TypeNS,
1088 ForeignItemKind::MacCall(..) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1089 };
1090 let parent = self.parent_scope.module.expect_local();
1091 let expansion = self.parent_scope.expansion;
1092 let vis = self.resolve_visibility(&item.vis);
1093 self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion);
1094 self.r.feed_visibility(feed, vis);
1095 }
1096
1097 fn build_reduced_graph_for_block(&mut self, block: &Block) {
1098 let parent = self.parent_scope.module.expect_local();
1099 let expansion = self.parent_scope.expansion;
1100 if self.block_needs_anonymous_module(block) {
1101 let module = self.r.new_local_module(
1102 Some(parent),
1103 ModuleKind::Block,
1104 expansion.to_expn_id(),
1105 block.span,
1106 parent.no_implicit_prelude,
1107 );
1108 self.r.block_map.insert(block.id, module);
1109 self.parent_scope.module = module.to_module(); }
1111 }
1112
1113 fn add_macro_use_decl(
1114 &mut self,
1115 name: Symbol,
1116 decl: Decl<'ra>,
1117 span: Span,
1118 allow_shadowing: bool,
1119 ) {
1120 if self.r.macro_use_prelude.insert(name, decl).is_some() && !allow_shadowing {
1121 self.r.dcx().emit_err(errors::MacroUseNameAlreadyInUse { span, name });
1122 }
1123 }
1124
1125 fn process_macro_use_imports(&mut self, item: &Item, module: Module<'ra>) -> bool {
1127 let mut import_all = None;
1128 let mut single_imports = ThinVec::new();
1129 if let Some(Attribute::Parsed(AttributeKind::MacroUse { span, arguments })) =
1130 AttributeParser::parse_limited(self.r.tcx.sess, &item.attrs, &[sym::macro_use])
1131 {
1132 if self.parent_scope.module.parent.is_some() {
1133 self.r
1134 .dcx()
1135 .emit_err(errors::ExternCrateLoadingMacroNotAtCrateRoot { span: item.span });
1136 }
1137 if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
1138 && orig_name == kw::SelfLower
1139 {
1140 self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span });
1141 }
1142
1143 match arguments {
1144 MacroUseArgs::UseAll => import_all = Some(span),
1145 MacroUseArgs::UseSpecific(imports) => single_imports = imports,
1146 }
1147 }
1148
1149 let macro_use_import = |this: &Self, span, warn_private| {
1150 this.r.arenas.alloc_import(ImportData {
1151 kind: ImportKind::MacroUse { warn_private },
1152 root_id: item.id,
1153 parent_scope: this.parent_scope,
1154 imported_module: CmCell::new(Some(ModuleOrUniformRoot::Module(module))),
1155 use_span_with_attributes: item.span_with_attributes(),
1156 has_attributes: !item.attrs.is_empty(),
1157 use_span: item.span,
1158 root_span: span,
1159 span,
1160 module_path: Vec::new(),
1161 vis: Visibility::Restricted(CRATE_DEF_ID),
1162 vis_span: item.vis.span,
1163 on_unknown_attr: OnUnknownData::from_attrs(this.r.tcx, item),
1164 })
1165 };
1166
1167 let allow_shadowing = self.parent_scope.expansion == LocalExpnId::ROOT;
1168 if let Some(span) = import_all {
1169 let import = macro_use_import(self, span, false);
1170 self.r.potentially_unused_imports.push(import);
1171 module.for_each_child_mut(self, |this, ident, _, ns, binding| {
1172 if ns == MacroNS {
1173 let import =
1174 if this.r.is_accessible_from(binding.vis(), this.parent_scope.module) {
1175 import
1176 } else {
1177 if this.r.macro_use_prelude.contains_key(&ident.name) {
1180 return;
1182 }
1183 macro_use_import(this, span, true)
1184 };
1185 let import_decl = this.r.new_import_decl(binding, import);
1186 this.add_macro_use_decl(ident.name, import_decl, span, allow_shadowing);
1187 }
1188 });
1189 } else {
1190 for ident in single_imports.iter().cloned() {
1191 let result = self.r.cm().maybe_resolve_ident_in_module(
1192 ModuleOrUniformRoot::Module(module),
1193 ident,
1194 MacroNS,
1195 &self.parent_scope,
1196 None,
1197 );
1198 if let Ok(binding) = result {
1199 let import = macro_use_import(self, ident.span, false);
1200 self.r.potentially_unused_imports.push(import);
1201 let import_decl = self.r.new_import_decl(binding, import);
1202 self.add_macro_use_decl(ident.name, import_decl, ident.span, allow_shadowing);
1203 } else {
1204 self.r.dcx().emit_err(errors::ImportedMacroNotFound { span: ident.span });
1205 }
1206 }
1207 }
1208 import_all.is_some() || !single_imports.is_empty()
1209 }
1210
1211 fn contains_macro_use(&self, attrs: &[ast::Attribute]) -> bool {
1213 for attr in attrs {
1214 if attr.has_name(sym::macro_escape) {
1215 let inner_attribute = #[allow(non_exhaustive_omitted_patterns)] match attr.style {
ast::AttrStyle::Inner => true,
_ => false,
}matches!(attr.style, ast::AttrStyle::Inner);
1216 self.r
1217 .dcx()
1218 .emit_warn(errors::MacroExternDeprecated { span: attr.span, inner_attribute });
1219 } else if !attr.has_name(sym::macro_use) {
1220 continue;
1221 }
1222
1223 if !attr.is_word() {
1224 self.r.dcx().emit_err(errors::ArgumentsMacroUseNotAllowed { span: attr.span });
1225 }
1226 return true;
1227 }
1228
1229 false
1230 }
1231
1232 fn visit_invoc(&mut self, id: NodeId) -> LocalExpnId {
1233 let invoc_id = id.placeholder_to_expn_id();
1234 let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
1235 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");
1236 invoc_id
1237 }
1238
1239 fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> {
1242 let invoc_id = self.visit_invoc(id);
1243 self.parent_scope.module.unexpanded_invocations.borrow_mut(self.r).insert(invoc_id);
1244 self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
1245 }
1246
1247 fn proc_macro_stub(
1248 &self,
1249 item: &ast::Item,
1250 fn_ident: Ident,
1251 ) -> Option<(MacroKind, Ident, Span)> {
1252 if ast::attr::contains_name(&item.attrs, sym::proc_macro) {
1253 return Some((MacroKind::Bang, fn_ident, item.span));
1254 } else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
1255 return Some((MacroKind::Attr, fn_ident, item.span));
1256 } else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
1257 && let Some(meta_item_inner) =
1258 attr.meta_item_list().and_then(|list| list.get(0).cloned())
1259 && let Some(ident) = meta_item_inner.ident()
1260 {
1261 return Some((MacroKind::Derive, ident, ident.span));
1262 }
1263 None
1264 }
1265
1266 fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) {
1270 if !ident.as_str().starts_with('_') {
1271 self.r.unused_macros.insert(def_id, (node_id, ident));
1272 let nrules = self.r.local_macro_map[&def_id].nrules;
1273 self.r.unused_macro_rules.insert(node_id, DenseBitSet::new_filled(nrules));
1274 }
1275 }
1276
1277 fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'ra> {
1278 let parent_scope = self.parent_scope;
1279 let expansion = parent_scope.expansion;
1280 let feed = self.r.feed(item.id);
1281 let def_id = feed.key();
1282 let (res, orig_ident, span, macro_rules) = match &item.kind {
1283 ItemKind::MacroDef(ident, def) => {
1284 (self.res(def_id), *ident, item.span, def.macro_rules)
1285 }
1286 ItemKind::Fn(box ast::Fn { ident: fn_ident, .. }) => {
1287 match self.proc_macro_stub(item, *fn_ident) {
1288 Some((macro_kind, ident, span)) => {
1289 let macro_kinds = macro_kind.into();
1290 let res = Res::Def(DefKind::Macro(macro_kinds), def_id.to_def_id());
1291 let macro_data = MacroData::new(self.r.dummy_ext(macro_kind));
1292 self.r.new_local_macro(def_id, macro_data);
1293 self.r.proc_macro_stubs.insert(def_id);
1294 (res, ident, span, false)
1295 }
1296 None => return parent_scope.macro_rules,
1297 }
1298 }
1299 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1300 };
1301
1302 self.r.local_macro_def_scopes.insert(def_id, parent_scope.module.expect_local());
1303
1304 if macro_rules {
1305 let ident = IdentKey::new(orig_ident);
1306 self.r.macro_names.insert(ident);
1307 let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export);
1308 let vis = if is_macro_export {
1309 Visibility::Public
1310 } else {
1311 Visibility::Restricted(CRATE_DEF_ID)
1312 };
1313 let decl = self.r.arenas.new_def_decl(
1314 res,
1315 vis.to_def_id(),
1316 span,
1317 expansion,
1318 Some(parent_scope.module),
1319 );
1320 self.r.all_macro_rules.insert(ident.name);
1321 if is_macro_export {
1322 let import = self.r.arenas.alloc_import(ImportData {
1323 kind: ImportKind::MacroExport,
1324 root_id: item.id,
1325 parent_scope: ParentScope {
1326 module: self.r.graph_root.to_module(),
1327 ..parent_scope
1328 },
1329 imported_module: CmCell::new(None),
1330 has_attributes: false,
1331 use_span_with_attributes: span,
1332 use_span: span,
1333 root_span: span,
1334 span,
1335 module_path: Vec::new(),
1336 vis,
1337 vis_span: item.vis.span,
1338 on_unknown_attr: OnUnknownData::from_attrs(self.r.tcx, item),
1339 });
1340 self.r.import_use_map.insert(import, Used::Other);
1341 let import_decl = self.r.new_import_decl(decl, import);
1342 self.r.plant_decl_into_local_module(ident, orig_ident.span, MacroNS, import_decl);
1343 } else {
1344 self.r.check_reserved_macro_name(ident.name, orig_ident.span, res);
1345 self.insert_unused_macro(orig_ident, def_id, item.id);
1346 }
1347 self.r.feed_visibility(feed, vis);
1348 let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Def(
1349 self.r.arenas.alloc_macro_rules_decl(MacroRulesDecl {
1350 parent_macro_rules_scope: parent_scope.macro_rules,
1351 decl,
1352 ident,
1353 orig_ident_span: orig_ident.span,
1354 }),
1355 ));
1356 self.r.macro_rules_scopes.insert(def_id, scope);
1357 scope
1358 } else {
1359 let module = parent_scope.module.expect_local();
1360 let vis = match item.kind {
1361 ItemKind::Fn(..) => {
1364 self.try_resolve_visibility(&item.vis, false).unwrap_or(Visibility::Public)
1365 }
1366 _ => self.resolve_visibility(&item.vis),
1367 };
1368 if !vis.is_public() {
1369 self.insert_unused_macro(orig_ident, def_id, item.id);
1370 }
1371 self.r.define_local(module, orig_ident, MacroNS, res, vis, span, expansion);
1372 self.r.feed_visibility(feed, vis);
1373 self.parent_scope.macro_rules
1374 }
1375 }
1376}
1377
1378macro_rules! method {
1379 ($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
1380 fn $visit(&mut self, node: &'a $ty) {
1381 if let $invoc(..) = node.kind {
1382 self.visit_invoc(node.id);
1383 } else {
1384 visit::$walk(self, node);
1385 }
1386 }
1387 };
1388}
1389
1390impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
1391 self
&'a ast::Expr
node
if let ast::ExprKind::MacCall(..) = node.kind {
self.visit_invoc(node.id);
} else { visit::walk_expr(self, node); }method!(visit_expr: ast::Expr, ast::ExprKind::MacCall, walk_expr);
1392 self
&'a ast::Pat
node
if let ast::PatKind::MacCall(..) = node.kind {
self.visit_invoc(node.id);
} else { visit::walk_pat(self, node); }method!(visit_pat: ast::Pat, ast::PatKind::MacCall, walk_pat);
1393 self
&'a ast::Ty
node
if let ast::TyKind::MacCall(..) = node.kind {
self.visit_invoc(node.id);
} else { visit::walk_ty(self, node); }method!(visit_ty: ast::Ty, ast::TyKind::MacCall, walk_ty);
1394
1395 fn visit_item(&mut self, item: &'a Item) {
1396 let orig_module_scope = self.parent_scope.module;
1397 self.parent_scope.macro_rules = match item.kind {
1398 ItemKind::MacroDef(..) => {
1399 let macro_rules_scope = self.define_macro(item);
1400 visit::walk_item(self, item);
1401 macro_rules_scope
1402 }
1403 ItemKind::MacCall(..) => self.visit_invoc_in_module(item.id),
1404 _ => {
1405 let orig_macro_rules_scope = self.parent_scope.macro_rules;
1406 self.build_reduced_graph_for_item(item);
1407 match item.kind {
1408 ItemKind::Mod(..) => {
1409 self.visit_vis(&item.vis);
1412 item.kind.walk(&item.attrs, item.span, item.id, &item.vis, (), self);
1413 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);
1414 }
1415 _ => visit::walk_item(self, item),
1416 }
1417 match item.kind {
1418 ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => {
1419 self.parent_scope.macro_rules
1420 }
1421 _ => orig_macro_rules_scope,
1422 }
1423 }
1424 };
1425 self.parent_scope.module = orig_module_scope;
1426 }
1427
1428 fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
1429 if let ast::StmtKind::MacCall(..) = stmt.kind {
1430 self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
1431 } else {
1432 visit::walk_stmt(self, stmt);
1433 }
1434 }
1435
1436 fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
1437 let ident = match foreign_item.kind {
1438 ForeignItemKind::Static(box StaticItem { ident, .. })
1439 | ForeignItemKind::Fn(box Fn { ident, .. })
1440 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => ident,
1441 ForeignItemKind::MacCall(_) => {
1442 self.visit_invoc_in_module(foreign_item.id);
1443 return;
1444 }
1445 };
1446
1447 self.build_reduced_graph_for_foreign_item(foreign_item, ident);
1448 visit::walk_item(self, foreign_item);
1449 }
1450
1451 fn visit_block(&mut self, block: &'a Block) {
1452 let orig_current_module = self.parent_scope.module;
1453 let orig_current_macro_rules_scope = self.parent_scope.macro_rules;
1454 self.build_reduced_graph_for_block(block);
1455 visit::walk_block(self, block);
1456 self.parent_scope.module = orig_current_module;
1457 self.parent_scope.macro_rules = orig_current_macro_rules_scope;
1458 }
1459
1460 fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
1461 let (ident, ns) = match item.kind {
1462 AssocItemKind::Const(box ConstItem { ident, .. })
1463 | AssocItemKind::Fn(box Fn { ident, .. })
1464 | AssocItemKind::Delegation(box Delegation { ident, .. }) => (ident, ValueNS),
1465
1466 AssocItemKind::Type(box TyAlias { ident, .. }) => (ident, TypeNS),
1467
1468 AssocItemKind::MacCall(_) => {
1469 match ctxt {
1470 AssocCtxt::Trait => {
1471 self.visit_invoc_in_module(item.id);
1472 }
1473 AssocCtxt::Impl { .. } => {
1474 let invoc_id = item.id.placeholder_to_expn_id();
1475 if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
1476 self.r
1477 .impl_unexpanded_invocations
1478 .entry(self.r.invocation_parent(invoc_id))
1479 .or_default()
1480 .insert(invoc_id);
1481 }
1482 self.visit_invoc(item.id);
1483 }
1484 }
1485 return;
1486 }
1487
1488 AssocItemKind::DelegationMac(..) => {
1489 ::rustc_middle::util::bug::span_bug_fmt(item.span,
format_args!("delegation mac should already have been removed"))span_bug!(item.span, "delegation mac should already have been removed")
1490 }
1491 };
1492 let vis = self.resolve_visibility(&item.vis);
1493 let feed = self.r.feed(item.id);
1494 let local_def_id = feed.key();
1495 let def_id = local_def_id.to_def_id();
1496
1497 if !(#[allow(non_exhaustive_omitted_patterns)] match ctxt {
AssocCtxt::Impl { of_trait: true } => true,
_ => false,
}matches!(ctxt, AssocCtxt::Impl { of_trait: true })
1498 && #[allow(non_exhaustive_omitted_patterns)] match item.vis.kind {
ast::VisibilityKind::Inherited => true,
_ => false,
}matches!(item.vis.kind, ast::VisibilityKind::Inherited))
1499 {
1500 self.r.feed_visibility(feed, vis);
1504 }
1505
1506 if ctxt == AssocCtxt::Trait {
1507 let parent = self.parent_scope.module.expect_local();
1508 let expansion = self.parent_scope.expansion;
1509 self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion);
1510 } else if !#[allow(non_exhaustive_omitted_patterns)] match &item.kind {
AssocItemKind::Delegation(deleg) if deleg.from_glob => true,
_ => false,
}matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob)
1511 && ident.name != kw::Underscore
1512 {
1513 let impl_def_id = self.r.tcx.local_parent(local_def_id);
1515 let key = BindingKey::new(IdentKey::new(ident), ns);
1516 self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
1517 }
1518
1519 visit::walk_assoc_item(self, item, ctxt);
1520 }
1521
1522 fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
1523 if !attr.is_doc_comment() && attr::is_builtin_attr(attr) {
1524 self.r
1525 .builtin_attrs
1526 .push((attr.get_normal_item().path.segments[0].ident, self.parent_scope));
1527 }
1528 visit::walk_attribute(self, attr);
1529 }
1530
1531 fn visit_arm(&mut self, arm: &'a ast::Arm) {
1532 if arm.is_placeholder {
1533 self.visit_invoc(arm.id);
1534 } else {
1535 visit::walk_arm(self, arm);
1536 }
1537 }
1538
1539 fn visit_expr_field(&mut self, f: &'a ast::ExprField) {
1540 if f.is_placeholder {
1541 self.visit_invoc(f.id);
1542 } else {
1543 visit::walk_expr_field(self, f);
1544 }
1545 }
1546
1547 fn visit_pat_field(&mut self, fp: &'a ast::PatField) {
1548 if fp.is_placeholder {
1549 self.visit_invoc(fp.id);
1550 } else {
1551 visit::walk_pat_field(self, fp);
1552 }
1553 }
1554
1555 fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
1556 if param.is_placeholder {
1557 self.visit_invoc(param.id);
1558 } else {
1559 visit::walk_generic_param(self, param);
1560 }
1561 }
1562
1563 fn visit_param(&mut self, p: &'a ast::Param) {
1564 if p.is_placeholder {
1565 self.visit_invoc(p.id);
1566 } else {
1567 visit::walk_param(self, p);
1568 }
1569 }
1570
1571 fn visit_field_def(&mut self, sf: &'a ast::FieldDef) {
1572 if sf.is_placeholder {
1573 self.visit_invoc(sf.id);
1574 } else {
1575 let vis = self.resolve_visibility(&sf.vis);
1576 self.r.feed_visibility(self.r.feed(sf.id), vis);
1577 visit::walk_field_def(self, sf);
1578 }
1579 }
1580
1581 fn visit_variant(&mut self, variant: &'a ast::Variant) {
1584 if variant.is_placeholder {
1585 self.visit_invoc_in_module(variant.id);
1586 return;
1587 }
1588
1589 let parent = self.parent_scope.module.expect_local();
1590 let expn_id = self.parent_scope.expansion;
1591 let ident = variant.ident;
1592
1593 let feed = self.r.feed(variant.id);
1595 let def_id = feed.key();
1596 let vis = self.resolve_visibility(&variant.vis);
1597 self.r.define_local(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id);
1598 self.r.feed_visibility(feed, vis);
1599
1600 let ctor_vis =
1602 if vis.is_public() && ast::attr::contains_name(&variant.attrs, sym::non_exhaustive) {
1603 Visibility::Restricted(CRATE_DEF_ID)
1604 } else {
1605 vis
1606 };
1607
1608 if let Some(ctor_node_id) = variant.data.ctor_node_id() {
1610 let feed = self.r.feed(ctor_node_id);
1611 let ctor_def_id = feed.key();
1612 let ctor_res = self.res(ctor_def_id);
1613 self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id);
1614 self.r.feed_visibility(feed, ctor_vis);
1615 }
1616
1617 self.insert_field_idents(def_id, variant.data.fields());
1619 self.insert_field_visibilities_local(def_id.to_def_id(), variant.data.fields());
1620
1621 visit::walk_variant(self, variant);
1622 }
1623
1624 fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
1625 if p.is_placeholder {
1626 self.visit_invoc(p.id);
1627 } else {
1628 visit::walk_where_predicate(self, p);
1629 }
1630 }
1631
1632 fn visit_crate(&mut self, krate: &'a ast::Crate) {
1633 if krate.is_placeholder {
1634 self.visit_invoc_in_module(krate.id);
1635 } else {
1636 for elem in &krate.items {
match ::rustc_ast_ir::visit::VisitorResult::branch(self.visit_item(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_item, &krate.items);
1639 for elem in &krate.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, &krate.attrs);
1640 self.contains_macro_use(&krate.attrs);
1641 }
1642 }
1643}