1use std::cell::Cell;
9use std::sync::Arc;
10
11use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
12use rustc_ast::{
13 self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
14 ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StaticItem, StmtKind, TyAlias,
15};
16use rustc_attr_parsing as attr;
17use rustc_expand::base::ResolverExpand;
18use rustc_expand::expand::AstFragment;
19use rustc_hir::def::{self, *};
20use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
21use rustc_index::bit_set::DenseBitSet;
22use rustc_metadata::creader::LoadedMacro;
23use rustc_middle::bug;
24use rustc_middle::metadata::ModChild;
25use rustc_middle::ty::{Feed, Visibility};
26use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
27use rustc_span::{Ident, Span, Symbol, kw, sym};
28use tracing::debug;
29
30use crate::Namespace::{MacroNS, TypeNS, ValueNS};
31use crate::def_collector::collect_definitions;
32use crate::imports::{ImportData, ImportKind};
33use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
34use crate::{
35 BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot,
36 NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Used,
37 VisResolutionError, errors,
38};
39
40type Res = def::Res<NodeId>;
41
42impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
43 pub(crate) fn define_binding(
46 &mut self,
47 parent: Module<'ra>,
48 ident: Ident,
49 ns: Namespace,
50 binding: NameBinding<'ra>,
51 ) {
52 let key = self.new_disambiguated_key(ident, ns);
53 if let Err(old_binding) = self.try_define(parent, key, binding, false) {
54 self.report_conflict(parent, ident, ns, old_binding, binding);
55 }
56 }
57
58 fn define(
59 &mut self,
60 parent: Module<'ra>,
61 ident: Ident,
62 ns: Namespace,
63 res: Res,
64 vis: Visibility<impl Into<DefId>>,
65 span: Span,
66 expn_id: LocalExpnId,
67 ) {
68 let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id);
69 self.define_binding(parent, ident, ns, binding)
70 }
71
72 pub(crate) fn get_nearest_non_block_module(&self, mut def_id: DefId) -> Module<'ra> {
89 loop {
90 match self.get_module(def_id) {
91 Some(module) => return module,
92 None => def_id = self.tcx.parent(def_id),
93 }
94 }
95 }
96
97 pub(crate) fn expect_module(&self, def_id: DefId) -> Module<'ra> {
98 self.get_module(def_id).expect("argument `DefId` is not a module")
99 }
100
101 pub(crate) fn get_module(&self, def_id: DefId) -> Option<Module<'ra>> {
105 match def_id.as_local() {
106 Some(local_def_id) => self.local_module_map.get(&local_def_id).copied(),
107 None => {
108 if let module @ Some(..) = self.extern_module_map.borrow().get(&def_id) {
109 return module.copied();
110 }
111
112 let def_kind = self.cstore().def_kind_untracked(def_id);
114 if def_kind.is_module_like() {
115 let parent = self
116 .tcx
117 .opt_parent(def_id)
118 .map(|parent_id| self.get_nearest_non_block_module(parent_id));
119 let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess);
122 return Some(self.new_extern_module(
123 parent,
124 ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
125 expn_id,
126 self.def_span(def_id),
127 parent.is_some_and(|module| module.no_implicit_prelude),
129 ));
130 }
131
132 None
133 }
134 }
135 }
136
137 pub(crate) fn expn_def_scope(&self, expn_id: ExpnId) -> Module<'ra> {
138 match expn_id.expn_data().macro_def_id {
139 Some(def_id) => self.macro_def_scope(def_id),
140 None => expn_id
141 .as_local()
142 .and_then(|expn_id| self.ast_transform_scopes.get(&expn_id).copied())
143 .unwrap_or(self.graph_root),
144 }
145 }
146
147 pub(crate) fn macro_def_scope(&self, def_id: DefId) -> Module<'ra> {
148 if let Some(id) = def_id.as_local() {
149 self.local_macro_def_scopes[&id]
150 } else {
151 self.get_nearest_non_block_module(def_id)
152 }
153 }
154
155 pub(crate) fn get_macro(&self, res: Res) -> Option<&'ra MacroData> {
156 match res {
157 Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
158 Res::NonMacroAttr(_) => Some(self.non_macro_attr),
159 _ => None,
160 }
161 }
162
163 pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra MacroData {
164 match def_id.as_local() {
166 Some(local_def_id) => self.local_macro_map[&local_def_id],
167 None => *self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| {
168 let loaded_macro = self.cstore().load_macro_untracked(def_id, self.tcx);
169 let macro_data = match loaded_macro {
170 LoadedMacro::MacroDef { def, ident, attrs, span, edition } => {
171 self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition)
172 }
173 LoadedMacro::ProcMacro(ext) => MacroData::new(Arc::new(ext)),
174 };
175
176 self.arenas.alloc_macro(macro_data)
177 }),
178 }
179 }
180
181 pub(crate) fn build_reduced_graph(
182 &mut self,
183 fragment: &AstFragment,
184 parent_scope: ParentScope<'ra>,
185 ) -> MacroRulesScopeRef<'ra> {
186 collect_definitions(self, fragment, parent_scope.expansion);
187 let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
188 fragment.visit_with(&mut visitor);
189 visitor.parent_scope.macro_rules
190 }
191
192 pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'ra>) {
193 for child in self.tcx.module_children(module.def_id()) {
194 let parent_scope = ParentScope::module(module, self);
195 self.build_reduced_graph_for_external_crate_res(child, parent_scope)
196 }
197 }
198
199 fn build_reduced_graph_for_external_crate_res(
201 &mut self,
202 child: &ModChild,
203 parent_scope: ParentScope<'ra>,
204 ) {
205 let parent = parent_scope.module;
206 let ModChild { ident, res, vis, ref reexport_chain } = *child;
207 let span = self.def_span(
208 reexport_chain
209 .first()
210 .and_then(|reexport| reexport.id())
211 .unwrap_or_else(|| res.def_id()),
212 );
213 let res = res.expect_non_local();
214 let expansion = parent_scope.expansion;
215 match res {
217 Res::Def(
218 DefKind::Mod
219 | DefKind::Enum
220 | DefKind::Trait
221 | DefKind::Struct
222 | DefKind::Union
223 | DefKind::Variant
224 | DefKind::TyAlias
225 | DefKind::ForeignTy
226 | DefKind::OpaqueTy
227 | DefKind::TraitAlias
228 | DefKind::AssocTy,
229 _,
230 )
231 | Res::PrimTy(..)
232 | Res::ToolMod => self.define(parent, ident, TypeNS, res, vis, span, expansion),
233 Res::Def(
234 DefKind::Fn
235 | DefKind::AssocFn
236 | DefKind::Static { .. }
237 | DefKind::Const
238 | DefKind::AssocConst
239 | DefKind::Ctor(..),
240 _,
241 ) => self.define(parent, ident, ValueNS, res, vis, span, expansion),
242 Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
243 self.define(parent, ident, MacroNS, res, vis, span, expansion)
244 }
245 Res::Def(
246 DefKind::TyParam
247 | DefKind::ConstParam
248 | DefKind::ExternCrate
249 | DefKind::Use
250 | DefKind::ForeignMod
251 | DefKind::AnonConst
252 | DefKind::InlineConst
253 | DefKind::Field
254 | DefKind::LifetimeParam
255 | DefKind::GlobalAsm
256 | DefKind::Closure
257 | DefKind::SyntheticCoroutineBody
258 | DefKind::Impl { .. },
259 _,
260 )
261 | Res::Local(..)
262 | Res::SelfTyParam { .. }
263 | Res::SelfTyAlias { .. }
264 | Res::SelfCtor(..)
265 | Res::Err => bug!("unexpected resolution: {:?}", res),
266 }
267 }
268}
269
270struct BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
271 r: &'a mut Resolver<'ra, 'tcx>,
272 parent_scope: ParentScope<'ra>,
273}
274
275impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for BuildReducedGraphVisitor<'_, 'ra, 'tcx> {
276 fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
277 self.r
278 }
279}
280
281impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
282 fn res(&self, def_id: impl Into<DefId>) -> Res {
283 let def_id = def_id.into();
284 Res::Def(self.r.tcx.def_kind(def_id), def_id)
285 }
286
287 fn resolve_visibility(&mut self, vis: &ast::Visibility) -> Visibility {
288 self.try_resolve_visibility(vis, true).unwrap_or_else(|err| {
289 self.r.report_vis_error(err);
290 Visibility::Public
291 })
292 }
293
294 fn try_resolve_visibility<'ast>(
295 &mut self,
296 vis: &'ast ast::Visibility,
297 finalize: bool,
298 ) -> Result<Visibility, VisResolutionError<'ast>> {
299 let parent_scope = &self.parent_scope;
300 match vis.kind {
301 ast::VisibilityKind::Public => Ok(Visibility::Public),
302 ast::VisibilityKind::Inherited => {
303 Ok(match self.parent_scope.module.kind {
304 ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => {
308 self.r.tcx.visibility(def_id).expect_local()
309 }
310 _ => Visibility::Restricted(
312 self.parent_scope.module.nearest_parent_mod().expect_local(),
313 ),
314 })
315 }
316 ast::VisibilityKind::Restricted { ref path, id, .. } => {
317 let ident = path.segments.get(0).expect("empty path in visibility").ident;
322 let crate_root = if ident.is_path_segment_keyword() {
323 None
324 } else if ident.span.is_rust_2015() {
325 Some(Segment::from_ident(Ident::new(
326 kw::PathRoot,
327 path.span.shrink_to_lo().with_ctxt(ident.span.ctxt()),
328 )))
329 } else {
330 return Err(VisResolutionError::Relative2018(ident.span, path));
331 };
332
333 let segments = crate_root
334 .into_iter()
335 .chain(path.segments.iter().map(|seg| seg.into()))
336 .collect::<Vec<_>>();
337 let expected_found_error = |res| {
338 Err(VisResolutionError::ExpectedFound(
339 path.span,
340 Segment::names_to_string(&segments),
341 res,
342 ))
343 };
344 match self.r.resolve_path(
345 &segments,
346 None,
347 parent_scope,
348 finalize.then(|| Finalize::new(id, path.span)),
349 None,
350 None,
351 ) {
352 PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
353 let res = module.res().expect("visibility resolved to unnamed block");
354 if finalize {
355 self.r.record_partial_res(id, PartialRes::new(res));
356 }
357 if module.is_normal() {
358 match res {
359 Res::Err => Ok(Visibility::Public),
360 _ => {
361 let vis = Visibility::Restricted(res.def_id());
362 if self.r.is_accessible_from(vis, parent_scope.module) {
363 Ok(vis.expect_local())
364 } else {
365 Err(VisResolutionError::AncestorOnly(path.span))
366 }
367 }
368 }
369 } else {
370 expected_found_error(res)
371 }
372 }
373 PathResult::Module(..) => Err(VisResolutionError::ModuleOnly(path.span)),
374 PathResult::NonModule(partial_res) => {
375 expected_found_error(partial_res.expect_full_res())
376 }
377 PathResult::Failed { span, label, suggestion, .. } => {
378 Err(VisResolutionError::FailedToResolve(span, label, suggestion))
379 }
380 PathResult::Indeterminate => Err(VisResolutionError::Indeterminate(path.span)),
381 }
382 }
383 }
384 }
385
386 fn insert_field_idents(&mut self, def_id: LocalDefId, fields: &[ast::FieldDef]) {
387 if fields.iter().any(|field| field.is_placeholder) {
388 return;
390 }
391 let fields = fields
392 .iter()
393 .enumerate()
394 .map(|(i, field)| {
395 field.ident.unwrap_or_else(|| Ident::from_str_and_span(&format!("{i}"), field.span))
396 })
397 .collect();
398 self.r.field_names.insert(def_id, fields);
399 }
400
401 fn insert_field_visibilities_local(&mut self, def_id: DefId, fields: &[ast::FieldDef]) {
402 let field_vis = fields
403 .iter()
404 .map(|field| field.vis.span.until(field.ident.map_or(field.ty.span, |i| i.span)))
405 .collect();
406 self.r.field_visibility_spans.insert(def_id, field_vis);
407 }
408
409 fn block_needs_anonymous_module(&self, block: &Block) -> bool {
410 block
412 .stmts
413 .iter()
414 .any(|statement| matches!(statement.kind, StmtKind::Item(_) | StmtKind::MacCall(_)))
415 }
416
417 fn add_import(
419 &mut self,
420 module_path: Vec<Segment>,
421 kind: ImportKind<'ra>,
422 span: Span,
423 item: &ast::Item,
424 root_span: Span,
425 root_id: NodeId,
426 vis: Visibility,
427 ) {
428 let current_module = self.parent_scope.module;
429 let import = self.r.arenas.alloc_import(ImportData {
430 kind,
431 parent_scope: self.parent_scope,
432 module_path,
433 imported_module: Cell::new(None),
434 span,
435 use_span: item.span,
436 use_span_with_attributes: item.span_with_attributes(),
437 has_attributes: !item.attrs.is_empty(),
438 root_span,
439 root_id,
440 vis,
441 });
442
443 self.r.indeterminate_imports.push(import);
444 match import.kind {
445 ImportKind::Single { target: Ident { name: kw::Underscore, .. }, .. } => {}
447 ImportKind::Single { target, type_ns_only, .. } => {
448 self.r.per_ns(|this, ns| {
449 if !type_ns_only || ns == TypeNS {
450 let key = BindingKey::new(target, ns);
451 let mut resolution = this.resolution(current_module, key).borrow_mut();
452 resolution.single_imports.insert(import);
453 }
454 });
455 }
456 ImportKind::Glob { is_prelude: true, .. } => {}
459 ImportKind::Glob { .. } => current_module.globs.borrow_mut().push(import),
460 _ => unreachable!(),
461 }
462 }
463
464 fn build_reduced_graph_for_use_tree(
465 &mut self,
466 use_tree: &ast::UseTree,
468 id: NodeId,
469 parent_prefix: &[Segment],
470 nested: bool,
471 list_stem: bool,
472 item: &Item,
474 vis: Visibility,
475 root_span: Span,
476 ) {
477 debug!(
478 "build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
479 parent_prefix, use_tree, nested
480 );
481
482 if nested && !list_stem {
485 self.r.feed_visibility(self.r.feed(id), vis);
486 }
487
488 let mut prefix_iter = parent_prefix
489 .iter()
490 .cloned()
491 .chain(use_tree.prefix.segments.iter().map(|seg| seg.into()))
492 .peekable();
493
494 let is_glob = matches!(use_tree.kind, ast::UseTreeKind::Glob);
499 let crate_root = match prefix_iter.peek() {
500 Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.is_rust_2015() => {
501 Some(seg.ident.span.ctxt())
502 }
503 None if is_glob && use_tree.span.is_rust_2015() => Some(use_tree.span.ctxt()),
504 _ => None,
505 }
506 .map(|ctxt| {
507 Segment::from_ident(Ident::new(
508 kw::PathRoot,
509 use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt),
510 ))
511 });
512
513 let prefix = crate_root.into_iter().chain(prefix_iter).collect::<Vec<_>>();
514 debug!("build_reduced_graph_for_use_tree: prefix={:?}", prefix);
515
516 let empty_for_self = |prefix: &[Segment]| {
517 prefix.is_empty() || prefix.len() == 1 && prefix[0].ident.name == kw::PathRoot
518 };
519 match use_tree.kind {
520 ast::UseTreeKind::Simple(rename) => {
521 let mut ident = use_tree.ident();
522 let mut module_path = prefix;
523 let mut source = module_path.pop().unwrap();
524 let mut type_ns_only = false;
525
526 if nested {
527 if source.ident.name == kw::SelfLower {
529 type_ns_only = true;
530
531 if empty_for_self(&module_path) {
532 self.r.report_error(
533 use_tree.span,
534 ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix,
535 );
536 return;
537 }
538
539 let self_span = source.ident.span;
541 source = module_path.pop().unwrap();
542 if rename.is_none() {
543 ident = Ident::new(source.ident.name, self_span);
545 }
546 }
547 } else {
548 if source.ident.name == kw::SelfLower {
550 let parent = module_path.last();
551
552 let span = match parent {
553 Some(seg) => seg.ident.span.shrink_to_hi().to(source.ident.span),
555 None => source.ident.span,
556 };
557 let span_with_rename = match rename {
558 Some(rename) => source.ident.span.to(rename.span),
560 None => source.ident.span,
561 };
562 self.r.report_error(
563 span,
564 ResolutionError::SelfImportsOnlyAllowedWithin {
565 root: parent.is_none(),
566 span_with_rename,
567 },
568 );
569
570 if let Some(parent) = module_path.pop() {
572 source = parent;
573 if rename.is_none() {
574 ident = source.ident;
575 }
576 }
577 }
578
579 if source.ident.name == kw::DollarCrate && module_path.is_empty() {
581 let crate_root = self.r.resolve_crate_root(source.ident);
582 let crate_name = match crate_root.kind {
583 ModuleKind::Def(.., name) => name,
584 ModuleKind::Block => unreachable!(),
585 };
586 if let Some(crate_name) = crate_name {
590 module_path.push(Segment::from_ident_and_id(
592 Ident::new(kw::PathRoot, source.ident.span),
593 self.r.next_node_id(),
594 ));
595 source.ident.name = crate_name;
596 }
597 if rename.is_none() {
598 ident.name = sym::dummy;
599 }
600
601 self.r.dcx().emit_err(errors::CrateImported { span: item.span });
602 }
603 }
604
605 if ident.name == kw::Crate {
606 self.r.dcx().emit_err(errors::UnnamedCrateRootImport { span: ident.span });
607 }
608
609 let kind = ImportKind::Single {
610 source: source.ident,
611 target: ident,
612 bindings: Default::default(),
613 type_ns_only,
614 nested,
615 id,
616 };
617
618 self.add_import(module_path, kind, use_tree.span, item, root_span, item.id, vis);
619 }
620 ast::UseTreeKind::Glob => {
621 let kind = ImportKind::Glob {
622 is_prelude: ast::attr::contains_name(&item.attrs, sym::prelude_import),
623 max_vis: Cell::new(None),
624 id,
625 };
626
627 self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis);
628 }
629 ast::UseTreeKind::Nested { ref items, .. } => {
630 let self_spans = items
632 .iter()
633 .filter_map(|(use_tree, _)| {
634 if let ast::UseTreeKind::Simple(..) = use_tree.kind
635 && use_tree.ident().name == kw::SelfLower
636 {
637 return Some(use_tree.span);
638 }
639
640 None
641 })
642 .collect::<Vec<_>>();
643 if self_spans.len() > 1 {
644 let mut e = self.r.into_struct_error(
645 self_spans[0],
646 ResolutionError::SelfImportCanOnlyAppearOnceInTheList,
647 );
648
649 for other_span in self_spans.iter().skip(1) {
650 e.span_label(*other_span, "another `self` import appears here");
651 }
652
653 e.emit();
654 }
655
656 for &(ref tree, id) in items {
657 self.build_reduced_graph_for_use_tree(
658 tree, id, &prefix, true, false, item, vis, root_span,
661 );
662 }
663
664 if items.is_empty() && !empty_for_self(&prefix) {
668 let new_span = prefix[prefix.len() - 1].ident.span;
669 let tree = ast::UseTree {
670 prefix: ast::Path::from_ident(Ident::new(kw::SelfLower, new_span)),
671 kind: ast::UseTreeKind::Simple(Some(Ident::new(kw::Underscore, new_span))),
672 span: use_tree.span,
673 };
674 self.build_reduced_graph_for_use_tree(
675 &tree,
677 id,
678 &prefix,
679 true,
680 true,
681 item,
683 Visibility::Restricted(
684 self.parent_scope.module.nearest_parent_mod().expect_local(),
685 ),
686 root_span,
687 );
688 }
689 }
690 }
691 }
692
693 fn build_reduced_graph_for_struct_variant(
694 &mut self,
695 fields: &[ast::FieldDef],
696 ident: Ident,
697 feed: Feed<'tcx, LocalDefId>,
698 adt_res: Res,
699 adt_vis: Visibility,
700 adt_span: Span,
701 ) {
702 let parent_scope = &self.parent_scope;
703 let parent = parent_scope.module;
704 let expansion = parent_scope.expansion;
705
706 self.r.define(parent, ident, TypeNS, adt_res, adt_vis, adt_span, expansion);
708 self.r.feed_visibility(feed, adt_vis);
709 let def_id = feed.key();
710
711 self.insert_field_idents(def_id, fields);
713 self.insert_field_visibilities_local(def_id.to_def_id(), fields);
714 }
715
716 fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
718 let parent_scope = &self.parent_scope;
719 let parent = parent_scope.module;
720 let expansion = parent_scope.expansion;
721 let sp = item.span;
722 let vis = self.resolve_visibility(&item.vis);
723 let feed = self.r.feed(item.id);
724 let local_def_id = feed.key();
725 let def_id = local_def_id.to_def_id();
726 let def_kind = self.r.tcx.def_kind(def_id);
727 let res = Res::Def(def_kind, def_id);
728
729 self.r.feed_visibility(feed, vis);
730
731 match item.kind {
732 ItemKind::Use(ref use_tree) => {
733 self.build_reduced_graph_for_use_tree(
734 use_tree,
736 item.id,
737 &[],
738 false,
739 false,
740 item,
742 vis,
743 use_tree.span,
744 );
745 }
746
747 ItemKind::ExternCrate(orig_name, ident) => {
748 self.build_reduced_graph_for_extern_crate(
749 orig_name,
750 item,
751 ident,
752 local_def_id,
753 vis,
754 parent,
755 );
756 }
757
758 ItemKind::Mod(_, ident, ref mod_kind) => {
759 self.r.define(parent, ident, TypeNS, res, vis, sp, expansion);
760
761 if let ast::ModKind::Loaded(_, _, _, Err(_)) = mod_kind {
762 self.r.mods_with_parse_errors.insert(def_id);
763 }
764 self.parent_scope.module = self.r.new_local_module(
765 Some(parent),
766 ModuleKind::Def(def_kind, def_id, Some(ident.name)),
767 expansion.to_expn_id(),
768 item.span,
769 parent.no_implicit_prelude
770 || ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude),
771 );
772 }
773
774 ItemKind::Const(box ConstItem { ident, .. })
776 | ItemKind::Delegation(box Delegation { ident, .. })
777 | ItemKind::Static(box StaticItem { ident, .. }) => {
778 self.r.define(parent, ident, ValueNS, res, vis, sp, expansion);
779 }
780 ItemKind::Fn(box Fn { ident, .. }) => {
781 self.r.define(parent, ident, ValueNS, res, vis, sp, expansion);
782
783 self.define_macro(item);
786 }
787
788 ItemKind::TyAlias(box TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => {
790 self.r.define(parent, ident, TypeNS, res, vis, sp, expansion);
791 }
792
793 ItemKind::Enum(ident, _, _) | ItemKind::Trait(box ast::Trait { ident, .. }) => {
794 self.r.define(parent, ident, TypeNS, res, vis, sp, expansion);
795
796 self.parent_scope.module = self.r.new_local_module(
797 Some(parent),
798 ModuleKind::Def(def_kind, def_id, Some(ident.name)),
799 expansion.to_expn_id(),
800 item.span,
801 parent.no_implicit_prelude,
802 );
803 }
804
805 ItemKind::Struct(ident, _, ref vdata) => {
807 self.build_reduced_graph_for_struct_variant(
808 vdata.fields(),
809 ident,
810 feed,
811 res,
812 vis,
813 sp,
814 );
815
816 if let Some(ctor_node_id) = vdata.ctor_node_id() {
819 let mut ctor_vis = if vis.is_public()
822 && ast::attr::contains_name(&item.attrs, sym::non_exhaustive)
823 {
824 Visibility::Restricted(CRATE_DEF_ID)
825 } else {
826 vis
827 };
828
829 let mut ret_fields = Vec::with_capacity(vdata.fields().len());
830
831 for field in vdata.fields() {
832 let field_vis = self
836 .try_resolve_visibility(&field.vis, false)
837 .unwrap_or(Visibility::Public);
838 if ctor_vis.is_at_least(field_vis, self.r.tcx) {
839 ctor_vis = field_vis;
840 }
841 ret_fields.push(field_vis.to_def_id());
842 }
843 let feed = self.r.feed(ctor_node_id);
844 let ctor_def_id = feed.key();
845 let ctor_res = self.res(ctor_def_id);
846 self.r.define(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion);
847 self.r.feed_visibility(feed, ctor_vis);
848 self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata.fields());
850
851 self.r
852 .struct_constructors
853 .insert(local_def_id, (ctor_res, ctor_vis.to_def_id(), ret_fields));
854 }
855 }
856
857 ItemKind::Union(ident, _, ref vdata) => {
858 self.build_reduced_graph_for_struct_variant(
859 vdata.fields(),
860 ident,
861 feed,
862 res,
863 vis,
864 sp,
865 );
866 }
867
868 ItemKind::Impl(box Impl { of_trait: Some(..), .. })
870 | ItemKind::Impl { .. }
871 | ItemKind::ForeignMod(..)
872 | ItemKind::GlobalAsm(..) => {}
873
874 ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
875 unreachable!()
876 }
877 }
878 }
879
880 fn build_reduced_graph_for_extern_crate(
881 &mut self,
882 orig_name: Option<Symbol>,
883 item: &Item,
884 ident: Ident,
885 local_def_id: LocalDefId,
886 vis: Visibility,
887 parent: Module<'ra>,
888 ) {
889 let sp = item.span;
890 let parent_scope = self.parent_scope;
891 let expansion = parent_scope.expansion;
892
893 let (used, module, binding) = if orig_name.is_none() && ident.name == kw::SelfLower {
894 self.r.dcx().emit_err(errors::ExternCrateSelfRequiresRenaming { span: sp });
895 return;
896 } else if orig_name == Some(kw::SelfLower) {
897 Some(self.r.graph_root)
898 } else {
899 let tcx = self.r.tcx;
900 let crate_id = self.r.cstore_mut().process_extern_crate(
901 self.r.tcx,
902 item,
903 local_def_id,
904 &tcx.definitions_untracked(),
905 );
906 crate_id.map(|crate_id| {
907 self.r.extern_crate_map.insert(local_def_id, crate_id);
908 self.r.expect_module(crate_id.as_def_id())
909 })
910 }
911 .map(|module| {
912 let used = self.process_macro_use_imports(item, module);
913 let binding = self.r.arenas.new_pub_res_binding(module.res().unwrap(), sp, expansion);
914 (used, Some(ModuleOrUniformRoot::Module(module)), binding)
915 })
916 .unwrap_or((true, None, self.r.dummy_binding));
917 let import = self.r.arenas.alloc_import(ImportData {
918 kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
919 root_id: item.id,
920 parent_scope: self.parent_scope,
921 imported_module: Cell::new(module),
922 has_attributes: !item.attrs.is_empty(),
923 use_span_with_attributes: item.span_with_attributes(),
924 use_span: item.span,
925 root_span: item.span,
926 span: item.span,
927 module_path: Vec::new(),
928 vis,
929 });
930 if used {
931 self.r.import_use_map.insert(import, Used::Other);
932 }
933 self.r.potentially_unused_imports.push(import);
934 let imported_binding = self.r.import(binding, import);
935 if parent == self.r.graph_root {
936 let ident = ident.normalize_to_macros_2_0();
937 if let Some(entry) = self.r.extern_prelude.get(&ident)
938 && expansion != LocalExpnId::ROOT
939 && orig_name.is_some()
940 && !entry.is_import()
941 {
942 self.r.dcx().emit_err(
943 errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
944 );
945 return;
950 }
951 let entry = self
952 .r
953 .extern_prelude
954 .entry(ident)
955 .or_insert(ExternPreludeEntry { binding: None, introduced_by_item: true });
956 if orig_name.is_some() {
957 entry.introduced_by_item = true;
958 }
959 if !entry.is_import() {
962 entry.binding = Some(imported_binding)
963 } else if ident.name != kw::Underscore {
964 self.r.dcx().span_delayed_bug(
965 item.span,
966 format!("it had been define the external module '{ident}' multiple times"),
967 );
968 }
969 }
970 self.r.define_binding(parent, ident, TypeNS, imported_binding);
971 }
972
973 fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, ident: Ident) {
975 let feed = self.r.feed(item.id);
976 let local_def_id = feed.key();
977 let def_id = local_def_id.to_def_id();
978 let ns = match item.kind {
979 ForeignItemKind::Fn(..) => ValueNS,
980 ForeignItemKind::Static(..) => ValueNS,
981 ForeignItemKind::TyAlias(..) => TypeNS,
982 ForeignItemKind::MacCall(..) => unreachable!(),
983 };
984 let parent = self.parent_scope.module;
985 let expansion = self.parent_scope.expansion;
986 let vis = self.resolve_visibility(&item.vis);
987 self.r.define(parent, ident, ns, self.res(def_id), vis, item.span, expansion);
988 self.r.feed_visibility(feed, vis);
989 }
990
991 fn build_reduced_graph_for_block(&mut self, block: &Block) {
992 let parent = self.parent_scope.module;
993 let expansion = self.parent_scope.expansion;
994 if self.block_needs_anonymous_module(block) {
995 let module = self.r.new_local_module(
996 Some(parent),
997 ModuleKind::Block,
998 expansion.to_expn_id(),
999 block.span,
1000 parent.no_implicit_prelude,
1001 );
1002 self.r.block_map.insert(block.id, module);
1003 self.parent_scope.module = module; }
1005 }
1006
1007 fn add_macro_use_binding(
1008 &mut self,
1009 name: Symbol,
1010 binding: NameBinding<'ra>,
1011 span: Span,
1012 allow_shadowing: bool,
1013 ) {
1014 if self.r.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing {
1015 self.r.dcx().emit_err(errors::MacroUseNameAlreadyInUse { span, name });
1016 }
1017 }
1018
1019 fn process_macro_use_imports(&mut self, item: &Item, module: Module<'ra>) -> bool {
1021 let mut import_all = None;
1022 let mut single_imports = Vec::new();
1023 for attr in &item.attrs {
1024 if attr.has_name(sym::macro_use) {
1025 if self.parent_scope.module.parent.is_some() {
1026 self.r.dcx().emit_err(errors::ExternCrateLoadingMacroNotAtCrateRoot {
1027 span: item.span,
1028 });
1029 }
1030 if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
1031 && orig_name == kw::SelfLower
1032 {
1033 self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
1034 }
1035 let ill_formed = |span| {
1036 self.r.dcx().emit_err(errors::BadMacroImport { span });
1037 };
1038 match attr.meta() {
1039 Some(meta) => match meta.kind {
1040 MetaItemKind::Word => {
1041 import_all = Some(meta.span);
1042 break;
1043 }
1044 MetaItemKind::List(meta_item_inners) => {
1045 for meta_item_inner in meta_item_inners {
1046 match meta_item_inner.ident() {
1047 Some(ident) if meta_item_inner.is_word() => {
1048 single_imports.push(ident)
1049 }
1050 _ => ill_formed(meta_item_inner.span()),
1051 }
1052 }
1053 }
1054 MetaItemKind::NameValue(..) => ill_formed(meta.span),
1055 },
1056 None => ill_formed(attr.span),
1057 }
1058 }
1059 }
1060
1061 let macro_use_import = |this: &Self, span, warn_private| {
1062 this.r.arenas.alloc_import(ImportData {
1063 kind: ImportKind::MacroUse { warn_private },
1064 root_id: item.id,
1065 parent_scope: this.parent_scope,
1066 imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
1067 use_span_with_attributes: item.span_with_attributes(),
1068 has_attributes: !item.attrs.is_empty(),
1069 use_span: item.span,
1070 root_span: span,
1071 span,
1072 module_path: Vec::new(),
1073 vis: Visibility::Restricted(CRATE_DEF_ID),
1074 })
1075 };
1076
1077 let allow_shadowing = self.parent_scope.expansion == LocalExpnId::ROOT;
1078 if let Some(span) = import_all {
1079 let import = macro_use_import(self, span, false);
1080 self.r.potentially_unused_imports.push(import);
1081 module.for_each_child(self, |this, ident, ns, binding| {
1082 if ns == MacroNS {
1083 let import = if this.r.is_accessible_from(binding.vis, this.parent_scope.module)
1084 {
1085 import
1086 } else {
1087 if this.r.macro_use_prelude.contains_key(&ident.name) {
1090 return;
1092 }
1093 macro_use_import(this, span, true)
1094 };
1095 let import_binding = this.r.import(binding, import);
1096 this.add_macro_use_binding(ident.name, import_binding, span, allow_shadowing);
1097 }
1098 });
1099 } else {
1100 for ident in single_imports.iter().cloned() {
1101 let result = self.r.maybe_resolve_ident_in_module(
1102 ModuleOrUniformRoot::Module(module),
1103 ident,
1104 MacroNS,
1105 &self.parent_scope,
1106 None,
1107 );
1108 if let Ok(binding) = result {
1109 let import = macro_use_import(self, ident.span, false);
1110 self.r.potentially_unused_imports.push(import);
1111 let imported_binding = self.r.import(binding, import);
1112 self.add_macro_use_binding(
1113 ident.name,
1114 imported_binding,
1115 ident.span,
1116 allow_shadowing,
1117 );
1118 } else {
1119 self.r.dcx().emit_err(errors::ImportedMacroNotFound { span: ident.span });
1120 }
1121 }
1122 }
1123 import_all.is_some() || !single_imports.is_empty()
1124 }
1125
1126 fn contains_macro_use(&self, attrs: &[ast::Attribute]) -> bool {
1128 for attr in attrs {
1129 if attr.has_name(sym::macro_escape) {
1130 let inner_attribute = matches!(attr.style, ast::AttrStyle::Inner);
1131 self.r
1132 .dcx()
1133 .emit_warn(errors::MacroExternDeprecated { span: attr.span, inner_attribute });
1134 } else if !attr.has_name(sym::macro_use) {
1135 continue;
1136 }
1137
1138 if !attr.is_word() {
1139 self.r.dcx().emit_err(errors::ArgumentsMacroUseNotAllowed { span: attr.span });
1140 }
1141 return true;
1142 }
1143
1144 false
1145 }
1146
1147 fn visit_invoc(&mut self, id: NodeId) -> LocalExpnId {
1148 let invoc_id = id.placeholder_to_expn_id();
1149 let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
1150 assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
1151 invoc_id
1152 }
1153
1154 fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> {
1157 let invoc_id = self.visit_invoc(id);
1158 self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id);
1159 self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
1160 }
1161
1162 fn proc_macro_stub(
1163 &self,
1164 item: &ast::Item,
1165 fn_ident: Ident,
1166 ) -> Option<(MacroKind, Ident, Span)> {
1167 if ast::attr::contains_name(&item.attrs, sym::proc_macro) {
1168 return Some((MacroKind::Bang, fn_ident, item.span));
1169 } else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
1170 return Some((MacroKind::Attr, fn_ident, item.span));
1171 } else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
1172 && let Some(meta_item_inner) =
1173 attr.meta_item_list().and_then(|list| list.get(0).cloned())
1174 && let Some(ident) = meta_item_inner.ident()
1175 {
1176 return Some((MacroKind::Derive, ident, ident.span));
1177 }
1178 None
1179 }
1180
1181 fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) {
1185 if !ident.as_str().starts_with('_') {
1186 self.r.unused_macros.insert(def_id, (node_id, ident));
1187 let nrules = self.r.local_macro_map[&def_id].nrules;
1188 self.r.unused_macro_rules.insert(node_id, DenseBitSet::new_filled(nrules));
1189 }
1190 }
1191
1192 fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'ra> {
1193 let parent_scope = self.parent_scope;
1194 let expansion = parent_scope.expansion;
1195 let feed = self.r.feed(item.id);
1196 let def_id = feed.key();
1197 let (res, ident, span, macro_rules) = match &item.kind {
1198 ItemKind::MacroDef(ident, def) => {
1199 (self.res(def_id), *ident, item.span, def.macro_rules)
1200 }
1201 ItemKind::Fn(box ast::Fn { ident: fn_ident, .. }) => {
1202 match self.proc_macro_stub(item, *fn_ident) {
1203 Some((macro_kind, ident, span)) => {
1204 let res = Res::Def(DefKind::Macro(macro_kind), def_id.to_def_id());
1205 let macro_data = MacroData::new(self.r.dummy_ext(macro_kind));
1206 self.r.new_local_macro(def_id, macro_data);
1207 self.r.proc_macro_stubs.insert(def_id);
1208 (res, ident, span, false)
1209 }
1210 None => return parent_scope.macro_rules,
1211 }
1212 }
1213 _ => unreachable!(),
1214 };
1215
1216 self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
1217
1218 if macro_rules {
1219 let ident = ident.normalize_to_macros_2_0();
1220 self.r.macro_names.insert(ident);
1221 let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export);
1222 let vis = if is_macro_export {
1223 Visibility::Public
1224 } else {
1225 Visibility::Restricted(CRATE_DEF_ID)
1226 };
1227 let binding = self.r.arenas.new_res_binding(res, vis.to_def_id(), span, expansion);
1228 self.r.set_binding_parent_module(binding, parent_scope.module);
1229 self.r.all_macro_rules.insert(ident.name);
1230 if is_macro_export {
1231 let import = self.r.arenas.alloc_import(ImportData {
1232 kind: ImportKind::MacroExport,
1233 root_id: item.id,
1234 parent_scope: self.parent_scope,
1235 imported_module: Cell::new(None),
1236 has_attributes: false,
1237 use_span_with_attributes: span,
1238 use_span: span,
1239 root_span: span,
1240 span,
1241 module_path: Vec::new(),
1242 vis,
1243 });
1244 self.r.import_use_map.insert(import, Used::Other);
1245 let import_binding = self.r.import(binding, import);
1246 self.r.define_binding(self.r.graph_root, ident, MacroNS, import_binding);
1247 } else {
1248 self.r.check_reserved_macro_name(ident, res);
1249 self.insert_unused_macro(ident, def_id, item.id);
1250 }
1251 self.r.feed_visibility(feed, vis);
1252 let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding(
1253 self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding {
1254 parent_macro_rules_scope: parent_scope.macro_rules,
1255 binding,
1256 ident,
1257 }),
1258 ));
1259 self.r.macro_rules_scopes.insert(def_id, scope);
1260 scope
1261 } else {
1262 let module = parent_scope.module;
1263 let vis = match item.kind {
1264 ItemKind::Fn(..) => {
1267 self.try_resolve_visibility(&item.vis, false).unwrap_or(Visibility::Public)
1268 }
1269 _ => self.resolve_visibility(&item.vis),
1270 };
1271 if !vis.is_public() {
1272 self.insert_unused_macro(ident, def_id, item.id);
1273 }
1274 self.r.define(module, ident, MacroNS, res, vis, span, expansion);
1275 self.r.feed_visibility(feed, vis);
1276 self.parent_scope.macro_rules
1277 }
1278 }
1279}
1280
1281macro_rules! method {
1282 ($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
1283 fn $visit(&mut self, node: &'a $ty) {
1284 if let $invoc(..) = node.kind {
1285 self.visit_invoc(node.id);
1286 } else {
1287 visit::$walk(self, node);
1288 }
1289 }
1290 };
1291}
1292
1293impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
1294 method!(visit_expr: ast::Expr, ast::ExprKind::MacCall, walk_expr);
1295 method!(visit_pat: ast::Pat, ast::PatKind::MacCall, walk_pat);
1296 method!(visit_ty: ast::Ty, ast::TyKind::MacCall, walk_ty);
1297
1298 fn visit_item(&mut self, item: &'a Item) {
1299 let orig_module_scope = self.parent_scope.module;
1300 self.parent_scope.macro_rules = match item.kind {
1301 ItemKind::MacroDef(..) => {
1302 let macro_rules_scope = self.define_macro(item);
1303 visit::walk_item(self, item);
1304 macro_rules_scope
1305 }
1306 ItemKind::MacCall(..) => self.visit_invoc_in_module(item.id),
1307 _ => {
1308 let orig_macro_rules_scope = self.parent_scope.macro_rules;
1309 self.build_reduced_graph_for_item(item);
1310 match item.kind {
1311 ItemKind::Mod(..) => {
1312 self.visit_vis(&item.vis);
1315 item.kind.walk(item.span, item.id, &item.vis, (), self);
1316 visit::walk_list!(self, visit_attribute, &item.attrs);
1317 }
1318 _ => visit::walk_item(self, item),
1319 }
1320 match item.kind {
1321 ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => {
1322 self.parent_scope.macro_rules
1323 }
1324 _ => orig_macro_rules_scope,
1325 }
1326 }
1327 };
1328 self.parent_scope.module = orig_module_scope;
1329 }
1330
1331 fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
1332 if let ast::StmtKind::MacCall(..) = stmt.kind {
1333 self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
1334 } else {
1335 visit::walk_stmt(self, stmt);
1336 }
1337 }
1338
1339 fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
1340 let ident = match foreign_item.kind {
1341 ForeignItemKind::Static(box StaticItem { ident, .. })
1342 | ForeignItemKind::Fn(box Fn { ident, .. })
1343 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => ident,
1344 ForeignItemKind::MacCall(_) => {
1345 self.visit_invoc_in_module(foreign_item.id);
1346 return;
1347 }
1348 };
1349
1350 self.build_reduced_graph_for_foreign_item(foreign_item, ident);
1351 visit::walk_item(self, foreign_item);
1352 }
1353
1354 fn visit_block(&mut self, block: &'a Block) {
1355 let orig_current_module = self.parent_scope.module;
1356 let orig_current_macro_rules_scope = self.parent_scope.macro_rules;
1357 self.build_reduced_graph_for_block(block);
1358 visit::walk_block(self, block);
1359 self.parent_scope.module = orig_current_module;
1360 self.parent_scope.macro_rules = orig_current_macro_rules_scope;
1361 }
1362
1363 fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
1364 let (ident, ns) = match item.kind {
1365 AssocItemKind::Const(box ConstItem { ident, .. })
1366 | AssocItemKind::Fn(box Fn { ident, .. })
1367 | AssocItemKind::Delegation(box Delegation { ident, .. }) => (ident, ValueNS),
1368
1369 AssocItemKind::Type(box TyAlias { ident, .. }) => (ident, TypeNS),
1370
1371 AssocItemKind::MacCall(_) => {
1372 match ctxt {
1373 AssocCtxt::Trait => {
1374 self.visit_invoc_in_module(item.id);
1375 }
1376 AssocCtxt::Impl { .. } => {
1377 let invoc_id = item.id.placeholder_to_expn_id();
1378 if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
1379 self.r
1380 .impl_unexpanded_invocations
1381 .entry(self.r.invocation_parent(invoc_id))
1382 .or_default()
1383 .insert(invoc_id);
1384 }
1385 self.visit_invoc(item.id);
1386 }
1387 }
1388 return;
1389 }
1390
1391 AssocItemKind::DelegationMac(..) => bug!(),
1392 };
1393 let vis = self.resolve_visibility(&item.vis);
1394 let feed = self.r.feed(item.id);
1395 let local_def_id = feed.key();
1396 let def_id = local_def_id.to_def_id();
1397
1398 if !(matches!(ctxt, AssocCtxt::Impl { of_trait: true })
1399 && matches!(item.vis.kind, ast::VisibilityKind::Inherited))
1400 {
1401 self.r.feed_visibility(feed, vis);
1405 }
1406
1407 if ctxt == AssocCtxt::Trait {
1408 let parent = self.parent_scope.module;
1409 let expansion = self.parent_scope.expansion;
1410 self.r.define(parent, ident, ns, self.res(def_id), vis, item.span, expansion);
1411 } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) {
1412 let impl_def_id = self.r.tcx.local_parent(local_def_id);
1413 let key = BindingKey::new(ident.normalize_to_macros_2_0(), ns);
1414 self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
1415 }
1416
1417 visit::walk_assoc_item(self, item, ctxt);
1418 }
1419
1420 fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
1421 if !attr.is_doc_comment() && attr::is_builtin_attr(attr) {
1422 self.r
1423 .builtin_attrs
1424 .push((attr.get_normal_item().path.segments[0].ident, self.parent_scope));
1425 }
1426 visit::walk_attribute(self, attr);
1427 }
1428
1429 fn visit_arm(&mut self, arm: &'a ast::Arm) {
1430 if arm.is_placeholder {
1431 self.visit_invoc(arm.id);
1432 } else {
1433 visit::walk_arm(self, arm);
1434 }
1435 }
1436
1437 fn visit_expr_field(&mut self, f: &'a ast::ExprField) {
1438 if f.is_placeholder {
1439 self.visit_invoc(f.id);
1440 } else {
1441 visit::walk_expr_field(self, f);
1442 }
1443 }
1444
1445 fn visit_pat_field(&mut self, fp: &'a ast::PatField) {
1446 if fp.is_placeholder {
1447 self.visit_invoc(fp.id);
1448 } else {
1449 visit::walk_pat_field(self, fp);
1450 }
1451 }
1452
1453 fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
1454 if param.is_placeholder {
1455 self.visit_invoc(param.id);
1456 } else {
1457 visit::walk_generic_param(self, param);
1458 }
1459 }
1460
1461 fn visit_param(&mut self, p: &'a ast::Param) {
1462 if p.is_placeholder {
1463 self.visit_invoc(p.id);
1464 } else {
1465 visit::walk_param(self, p);
1466 }
1467 }
1468
1469 fn visit_field_def(&mut self, sf: &'a ast::FieldDef) {
1470 if sf.is_placeholder {
1471 self.visit_invoc(sf.id);
1472 } else {
1473 let vis = self.resolve_visibility(&sf.vis);
1474 self.r.feed_visibility(self.r.feed(sf.id), vis);
1475 visit::walk_field_def(self, sf);
1476 }
1477 }
1478
1479 fn visit_variant(&mut self, variant: &'a ast::Variant) {
1482 if variant.is_placeholder {
1483 self.visit_invoc_in_module(variant.id);
1484 return;
1485 }
1486
1487 let parent = self.parent_scope.module;
1488 let expn_id = self.parent_scope.expansion;
1489 let ident = variant.ident;
1490
1491 let feed = self.r.feed(variant.id);
1493 let def_id = feed.key();
1494 let vis = self.resolve_visibility(&variant.vis);
1495 self.r.define(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id);
1496 self.r.feed_visibility(feed, vis);
1497
1498 let ctor_vis =
1500 if vis.is_public() && ast::attr::contains_name(&variant.attrs, sym::non_exhaustive) {
1501 Visibility::Restricted(CRATE_DEF_ID)
1502 } else {
1503 vis
1504 };
1505
1506 if let Some(ctor_node_id) = variant.data.ctor_node_id() {
1508 let feed = self.r.feed(ctor_node_id);
1509 let ctor_def_id = feed.key();
1510 let ctor_res = self.res(ctor_def_id);
1511 self.r.define(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id);
1512 self.r.feed_visibility(feed, ctor_vis);
1513 }
1514
1515 self.insert_field_idents(def_id, variant.data.fields());
1517 self.insert_field_visibilities_local(def_id.to_def_id(), variant.data.fields());
1518
1519 visit::walk_variant(self, variant);
1520 }
1521
1522 fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
1523 if p.is_placeholder {
1524 self.visit_invoc(p.id);
1525 } else {
1526 visit::walk_where_predicate(self, p);
1527 }
1528 }
1529
1530 fn visit_crate(&mut self, krate: &'a ast::Crate) {
1531 if krate.is_placeholder {
1532 self.visit_invoc_in_module(krate.id);
1533 } else {
1534 visit::walk_list!(self, visit_item, &krate.items);
1537 visit::walk_list!(self, visit_attribute, &krate.attrs);
1538 self.contains_macro_use(&krate.attrs);
1539 }
1540 }
1541}