1 //! After we obtain a fresh AST fragment from a macro, code in this module helps to integrate
2 //! that fragment into the module structures that are already partially built.
4 //! Items from the fragment are placed into modules,
5 //! unexpanded macros in the fragment are visited and registered.
6 //! Imports are also considered items and placed into modules here, but not resolved yet.
8 use crate::def_collector
::collect_definitions
;
9 use crate::imports
::{Import, ImportKind}
;
10 use crate::macros
::{LegacyBinding, LegacyScope}
;
11 use crate::Namespace
::{self, MacroNS, TypeNS, ValueNS}
;
12 use crate::{CrateLint, Determinacy, PathResult, ResolutionError, VisResolutionError}
;
14 ExternPreludeEntry
, ModuleOrUniformRoot
, ParentScope
, PerNS
, Resolver
, ResolverArenas
,
16 use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}
;
19 use rustc
::hir
::exports
::Export
;
20 use rustc
::middle
::cstore
::CrateStore
;
22 use rustc_ast
::ast
::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}
;
23 use rustc_ast
::ast
::{AssocItem, AssocItemKind, MetaItemKind, StmtKind}
;
24 use rustc_ast
::ast
::{Ident, Name}
;
25 use rustc_ast
::token
::{self, Token}
;
26 use rustc_ast
::visit
::{self, AssocCtxt, Visitor}
;
27 use rustc_attr
as attr
;
28 use rustc_data_structures
::sync
::Lrc
;
29 use rustc_errors
::{struct_span_err, Applicability}
;
30 use rustc_expand
::base
::SyntaxExtension
;
31 use rustc_expand
::expand
::AstFragment
;
32 use rustc_hir
::def
::{self, *}
;
33 use rustc_hir
::def_id
::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}
;
34 use rustc_metadata
::creader
::LoadedMacro
;
35 use rustc_span
::hygiene
::{ExpnId, MacroKind}
;
36 use rustc_span
::source_map
::{respan, Spanned}
;
37 use rustc_span
::symbol
::{kw, sym}
;
38 use rustc_span
::{Span, DUMMY_SP}
;
44 type Res
= def
::Res
<NodeId
>;
46 impl<'a
> ToNameBinding
<'a
> for (Module
<'a
>, ty
::Visibility
, Span
, ExpnId
) {
47 fn to_name_binding(self, arenas
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
> {
48 arenas
.alloc_name_binding(NameBinding
{
49 kind
: NameBindingKind
::Module(self.0),
58 impl<'a
> ToNameBinding
<'a
> for (Res
, ty
::Visibility
, Span
, ExpnId
) {
59 fn to_name_binding(self, arenas
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
> {
60 arenas
.alloc_name_binding(NameBinding
{
61 kind
: NameBindingKind
::Res(self.0, false),
72 impl<'a
> ToNameBinding
<'a
> for (Res
, ty
::Visibility
, Span
, ExpnId
, IsMacroExport
) {
73 fn to_name_binding(self, arenas
: &'a ResolverArenas
<'a
>) -> &'a NameBinding
<'a
> {
74 arenas
.alloc_name_binding(NameBinding
{
75 kind
: NameBindingKind
::Res(self.0, true),
84 impl<'a
> Resolver
<'a
> {
85 /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
86 /// otherwise, reports an error.
87 crate fn define
<T
>(&mut self, parent
: Module
<'a
>, ident
: Ident
, ns
: Namespace
, def
: T
)
91 let binding
= def
.to_name_binding(self.arenas
);
92 let key
= self.new_key(ident
, ns
);
93 if let Err(old_binding
) = self.try_define(parent
, key
, binding
) {
94 self.report_conflict(parent
, ident
, ns
, old_binding
, &binding
);
98 crate fn get_module(&mut self, def_id
: DefId
) -> Module
<'a
> {
99 if def_id
.krate
== LOCAL_CRATE
{
100 return self.module_map
[&def_id
];
103 if let Some(&module
) = self.extern_module_map
.get(&def_id
) {
107 let (name
, parent
) = if def_id
.index
== CRATE_DEF_INDEX
{
108 (self.cstore().crate_name_untracked(def_id
.krate
), None
)
110 let def_key
= self.cstore().def_key(def_id
);
112 def_key
.disambiguated_data
.data
.get_opt_name().unwrap(),
113 Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }
)),
117 let kind
= ModuleKind
::Def(DefKind
::Mod
, def_id
, name
);
118 let module
= self.arenas
.alloc_module(ModuleData
::new(
125 self.extern_module_map
.insert(def_id
, module
);
129 crate fn macro_def_scope(&mut self, expn_id
: ExpnId
) -> Module
<'a
> {
130 let def_id
= match self.macro_defs
.get(&expn_id
) {
131 Some(def_id
) => *def_id
,
132 None
=> return self.ast_transform_scopes
.get(&expn_id
).unwrap_or(&self.graph_root
),
134 if let Some(id
) = self.definitions
.as_local_node_id(def_id
) {
135 self.local_macro_def_scopes
[&id
]
137 let module_def_id
= ty
::DefIdTree
::parent(&*self, def_id
).unwrap();
138 self.get_module(module_def_id
)
142 crate fn get_macro(&mut self, res
: Res
) -> Option
<Lrc
<SyntaxExtension
>> {
144 Res
::Def(DefKind
::Macro(..), def_id
) => self.get_macro_by_def_id(def_id
),
145 Res
::NonMacroAttr(attr_kind
) => Some(self.non_macro_attr(attr_kind
.is_used())),
150 crate fn get_macro_by_def_id(&mut self, def_id
: DefId
) -> Option
<Lrc
<SyntaxExtension
>> {
151 if let Some(ext
) = self.macro_map
.get(&def_id
) {
152 return Some(ext
.clone());
155 let ext
= Lrc
::new(match self.cstore().load_macro_untracked(def_id
, &self.session
) {
156 LoadedMacro
::MacroDef(item
, edition
) => self.compile_macro(&item
, edition
),
157 LoadedMacro
::ProcMacro(ext
) => ext
,
160 self.macro_map
.insert(def_id
, ext
.clone());
164 crate fn build_reduced_graph(
166 fragment
: &AstFragment
,
167 parent_scope
: ParentScope
<'a
>,
168 ) -> LegacyScope
<'a
> {
169 collect_definitions(&mut self.definitions
, fragment
, parent_scope
.expansion
);
170 let mut visitor
= BuildReducedGraphVisitor { r: self, parent_scope }
;
171 fragment
.visit_with(&mut visitor
);
172 visitor
.parent_scope
.legacy
175 crate fn build_reduced_graph_external(&mut self, module
: Module
<'a
>) {
176 let def_id
= module
.def_id().expect("unpopulated module without a def-id");
177 for child
in self.cstore().item_children_untracked(def_id
, self.session
) {
178 let child
= child
.map_id(|_
| panic
!("unexpected id"));
179 BuildReducedGraphVisitor { r: self, parent_scope: ParentScope::module(module) }
180 .build_reduced_graph_for_external_crate_res(child
);
185 struct BuildReducedGraphVisitor
<'a
, 'b
> {
186 r
: &'b
mut Resolver
<'a
>,
187 parent_scope
: ParentScope
<'a
>,
190 impl<'a
> AsMut
<Resolver
<'a
>> for BuildReducedGraphVisitor
<'a
, '_
> {
191 fn as_mut(&mut self) -> &mut Resolver
<'a
> {
196 impl<'a
, 'b
> BuildReducedGraphVisitor
<'a
, 'b
> {
197 fn resolve_visibility(&mut self, vis
: &ast
::Visibility
) -> ty
::Visibility
{
198 self.resolve_visibility_speculative(vis
, false).unwrap_or_else(|err
| {
199 self.r
.report_vis_error(err
);
200 ty
::Visibility
::Public
204 fn resolve_visibility_speculative
<'ast
>(
206 vis
: &'ast ast
::Visibility
,
208 ) -> Result
<ty
::Visibility
, VisResolutionError
<'ast
>> {
209 let parent_scope
= &self.parent_scope
;
211 ast
::VisibilityKind
::Public
=> Ok(ty
::Visibility
::Public
),
212 ast
::VisibilityKind
::Crate(..) => {
213 Ok(ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
)))
215 ast
::VisibilityKind
::Inherited
=> {
216 Ok(ty
::Visibility
::Restricted(parent_scope
.module
.normal_ancestor_id
))
218 ast
::VisibilityKind
::Restricted { ref path, id, .. }
=> {
219 // For visibilities we are not ready to provide correct implementation of "uniform
220 // paths" right now, so on 2018 edition we only allow module-relative paths for now.
221 // On 2015 edition visibilities are resolved as crate-relative by default,
222 // so we are prepending a root segment if necessary.
223 let ident
= path
.segments
.get(0).expect("empty path in visibility").ident
;
224 let crate_root
= if ident
.is_path_segment_keyword() {
226 } else if ident
.span
.rust_2015() {
227 Some(Segment
::from_ident(Ident
::new(
229 path
.span
.shrink_to_lo().with_ctxt(ident
.span
.ctxt()),
232 return Err(VisResolutionError
::Relative2018(ident
.span
, path
));
235 let segments
= crate_root
237 .chain(path
.segments
.iter().map(|seg
| seg
.into()))
238 .collect
::<Vec
<_
>>();
239 let expected_found_error
= |res
| {
240 Err(VisResolutionError
::ExpectedFound(
242 Segment
::names_to_string(&segments
),
246 match self.r
.resolve_path(
252 CrateLint
::SimplePath(id
),
254 PathResult
::Module(ModuleOrUniformRoot
::Module(module
)) => {
255 let res
= module
.res().expect("visibility resolved to unnamed block");
257 self.r
.record_partial_res(id
, PartialRes
::new(res
));
259 if module
.is_normal() {
261 Ok(ty
::Visibility
::Public
)
263 let vis
= ty
::Visibility
::Restricted(res
.def_id());
264 if self.r
.is_accessible_from(vis
, parent_scope
.module
) {
267 Err(VisResolutionError
::AncestorOnly(path
.span
))
271 expected_found_error(res
)
274 PathResult
::Module(..) => Err(VisResolutionError
::ModuleOnly(path
.span
)),
275 PathResult
::NonModule(partial_res
) => {
276 expected_found_error(partial_res
.base_res())
278 PathResult
::Failed { span, label, suggestion, .. }
=> {
279 Err(VisResolutionError
::FailedToResolve(span
, label
, suggestion
))
281 PathResult
::Indeterminate
=> Err(VisResolutionError
::Indeterminate(path
.span
)),
287 fn insert_field_names_local(&mut self, def_id
: DefId
, vdata
: &ast
::VariantData
) {
288 let field_names
= vdata
291 .map(|field
| respan(field
.span
, field
.ident
.map_or(kw
::Invalid
, |ident
| ident
.name
)))
293 self.insert_field_names(def_id
, field_names
);
296 fn insert_field_names(&mut self, def_id
: DefId
, field_names
: Vec
<Spanned
<Name
>>) {
297 if !field_names
.is_empty() {
298 self.r
.field_names
.insert(def_id
, field_names
);
302 fn block_needs_anonymous_module(&mut self, block
: &Block
) -> bool
{
303 // If any statements are items, we need to create an anonymous module
304 block
.stmts
.iter().any(|statement
| match statement
.kind
{
305 StmtKind
::Item(_
) | StmtKind
::Mac(_
) => true,
310 // Add an import to the current module.
313 module_path
: Vec
<Segment
>,
314 kind
: ImportKind
<'a
>,
322 let current_module
= self.parent_scope
.module
;
323 let import
= self.r
.arenas
.alloc_import(Import
{
325 parent_scope
: self.parent_scope
,
327 imported_module
: Cell
::new(None
),
331 use_span_with_attributes
: item
.span_with_attributes(),
332 has_attributes
: !item
.attrs
.is_empty(),
336 used
: Cell
::new(false),
339 debug
!("add_import({:?})", import
);
341 self.r
.indeterminate_imports
.push(import
);
343 // Don't add unresolved underscore imports to modules
344 ImportKind
::Single { target: Ident { name: kw::Underscore, .. }
, .. } => {}
345 ImportKind
::Single { target, type_ns_only, .. }
=> {
346 self.r
.per_ns(|this
, ns
| {
347 if !type_ns_only
|| ns
== TypeNS
{
348 let key
= this
.new_key(target
, ns
);
349 let mut resolution
= this
.resolution(current_module
, key
).borrow_mut();
350 resolution
.add_single_import(import
);
354 // We don't add prelude imports to the globs since they only affect lexical scopes,
355 // which are not relevant to import resolution.
356 ImportKind
::Glob { is_prelude: true, .. }
=> {}
357 ImportKind
::Glob { .. }
=> current_module
.globs
.borrow_mut().push(import
),
362 fn build_reduced_graph_for_use_tree(
364 // This particular use tree
365 use_tree
: &ast
::UseTree
,
367 parent_prefix
: &[Segment
],
369 // The whole `use` item
375 "build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
376 parent_prefix
, use_tree
, nested
379 let mut prefix_iter
= parent_prefix
382 .chain(use_tree
.prefix
.segments
.iter().map(|seg
| seg
.into()))
385 // On 2015 edition imports are resolved as crate-relative by default,
386 // so prefixes are prepended with crate root segment if necessary.
387 // The root is prepended lazily, when the first non-empty prefix or terminating glob
388 // appears, so imports in braced groups can have roots prepended independently.
389 let is_glob
= if let ast
::UseTreeKind
::Glob
= use_tree
.kind { true }
else { false }
;
390 let crate_root
= match prefix_iter
.peek() {
391 Some(seg
) if !seg
.ident
.is_path_segment_keyword() && seg
.ident
.span
.rust_2015() => {
392 Some(seg
.ident
.span
.ctxt())
394 None
if is_glob
&& use_tree
.span
.rust_2015() => Some(use_tree
.span
.ctxt()),
398 Segment
::from_ident(Ident
::new(
400 use_tree
.prefix
.span
.shrink_to_lo().with_ctxt(ctxt
),
404 let prefix
= crate_root
.into_iter().chain(prefix_iter
).collect
::<Vec
<_
>>();
405 debug
!("build_reduced_graph_for_use_tree: prefix={:?}", prefix
);
407 let empty_for_self
= |prefix
: &[Segment
]| {
408 prefix
.is_empty() || prefix
.len() == 1 && prefix
[0].ident
.name
== kw
::PathRoot
410 match use_tree
.kind
{
411 ast
::UseTreeKind
::Simple(rename
, ..) => {
412 let mut ident
= use_tree
.ident();
413 let mut module_path
= prefix
;
414 let mut source
= module_path
.pop().unwrap();
415 let mut type_ns_only
= false;
418 // Correctly handle `self`
419 if source
.ident
.name
== kw
::SelfLower
{
422 if empty_for_self(&module_path
) {
425 ResolutionError
::SelfImportOnlyInImportListWithNonEmptyPrefix
,
430 // Replace `use foo::self;` with `use foo;`
431 source
= module_path
.pop().unwrap();
432 if rename
.is_none() {
433 ident
= source
.ident
;
438 if source
.ident
.name
== kw
::SelfLower
{
441 ResolutionError
::SelfImportsOnlyAllowedWithin
,
445 // Disallow `use $crate;`
446 if source
.ident
.name
== kw
::DollarCrate
&& module_path
.is_empty() {
447 let crate_root
= self.r
.resolve_crate_root(source
.ident
);
448 let crate_name
= match crate_root
.kind
{
449 ModuleKind
::Def(.., name
) => name
,
450 ModuleKind
::Block(..) => unreachable
!(),
452 // HACK(eddyb) unclear how good this is, but keeping `$crate`
453 // in `source` breaks `src/test/compile-fail/import-crate-var.rs`,
454 // while the current crate doesn't have a valid `crate_name`.
455 if crate_name
!= kw
::Invalid
{
456 // `crate_name` should not be interpreted as relative.
457 module_path
.push(Segment
{
458 ident
: Ident { name: kw::PathRoot, span: source.ident.span }
,
459 id
: Some(self.r
.next_node_id()),
461 source
.ident
.name
= crate_name
;
463 if rename
.is_none() {
464 ident
.name
= crate_name
;
469 .struct_span_err(item
.span
, "`$crate` may not be imported")
474 if ident
.name
== kw
::Crate
{
475 self.r
.session
.span_err(
477 "crate root imports need to be explicitly named: \
478 `use crate as name;`",
482 let kind
= ImportKind
::Single
{
483 source
: source
.ident
,
485 source_bindings
: PerNS
{
486 type_ns
: Cell
::new(Err(Determinacy
::Undetermined
)),
487 value_ns
: Cell
::new(Err(Determinacy
::Undetermined
)),
488 macro_ns
: Cell
::new(Err(Determinacy
::Undetermined
)),
490 target_bindings
: PerNS
{
491 type_ns
: Cell
::new(None
),
492 value_ns
: Cell
::new(None
),
493 macro_ns
: Cell
::new(None
),
509 ast
::UseTreeKind
::Glob
=> {
510 let kind
= ImportKind
::Glob
{
511 is_prelude
: attr
::contains_name(&item
.attrs
, sym
::prelude_import
),
512 max_vis
: Cell
::new(ty
::Visibility
::Invisible
),
514 self.add_import(prefix
, kind
, use_tree
.span
, id
, item
, root_span
, item
.id
, vis
);
516 ast
::UseTreeKind
::Nested(ref items
) => {
517 // Ensure there is at most one `self` in the list
518 let self_spans
= items
520 .filter_map(|&(ref use_tree
, _
)| {
521 if let ast
::UseTreeKind
::Simple(..) = use_tree
.kind
{
522 if use_tree
.ident().name
== kw
::SelfLower
{
523 return Some(use_tree
.span
);
529 .collect
::<Vec
<_
>>();
530 if self_spans
.len() > 1 {
531 let mut e
= self.r
.into_struct_error(
533 ResolutionError
::SelfImportCanOnlyAppearOnceInTheList
,
536 for other_span
in self_spans
.iter().skip(1) {
537 e
.span_label(*other_span
, "another `self` import appears here");
543 for &(ref tree
, id
) in items
{
544 self.build_reduced_graph_for_use_tree(
545 // This particular use tree
546 tree
, id
, &prefix
, true, // The whole `use` item
547 item
, vis
, root_span
,
551 // Empty groups `a::b::{}` are turned into synthetic `self` imports
552 // `a::b::c::{self as _}`, so that their prefixes are correctly
553 // resolved and checked for privacy/stability/etc.
554 if items
.is_empty() && !empty_for_self(&prefix
) {
555 let new_span
= prefix
[prefix
.len() - 1].ident
.span
;
556 let tree
= ast
::UseTree
{
557 prefix
: ast
::Path
::from_ident(Ident
::new(kw
::SelfLower
, new_span
)),
558 kind
: ast
::UseTreeKind
::Simple(
559 Some(Ident
::new(kw
::Underscore
, new_span
)),
565 self.build_reduced_graph_for_use_tree(
566 // This particular use tree
571 // The whole `use` item
573 ty
::Visibility
::Invisible
,
581 /// Constructs the reduced graph for one item.
582 fn build_reduced_graph_for_item(&mut self, item
: &'b Item
) {
583 let parent_scope
= &self.parent_scope
;
584 let parent
= parent_scope
.module
;
585 let expansion
= parent_scope
.expansion
;
586 let ident
= item
.ident
;
588 let vis
= self.resolve_visibility(&item
.vis
);
591 ItemKind
::Use(ref use_tree
) => {
592 self.build_reduced_graph_for_use_tree(
593 // This particular use tree
598 // The whole `use` item
605 ItemKind
::ExternCrate(orig_name
) => {
606 let module
= if orig_name
.is_none() && ident
.name
== kw
::SelfLower
{
609 .struct_span_err(item
.span
, "`extern crate self;` requires renaming")
613 "extern crate self as name;".into(),
614 Applicability
::HasPlaceholders
,
618 } else if orig_name
== Some(kw
::SelfLower
) {
622 self.r
.crate_loader
.process_extern_crate(item
, &self.r
.definitions
);
623 self.r
.extern_crate_map
.insert(item
.id
, crate_id
);
624 self.r
.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }
)
627 let used
= self.process_legacy_macro_imports(item
, module
);
629 (module
, ty
::Visibility
::Public
, sp
, expansion
).to_name_binding(self.r
.arenas
);
630 let import
= self.r
.arenas
.alloc_import(Import
{
631 kind
: ImportKind
::ExternCrate { source: orig_name, target: ident }
,
634 parent_scope
: self.parent_scope
,
635 imported_module
: Cell
::new(Some(ModuleOrUniformRoot
::Module(module
))),
636 has_attributes
: !item
.attrs
.is_empty(),
637 use_span_with_attributes
: item
.span_with_attributes(),
639 root_span
: item
.span
,
641 module_path
: Vec
::new(),
643 used
: Cell
::new(used
),
645 self.r
.potentially_unused_imports
.push(import
);
646 let imported_binding
= self.r
.import(binding
, import
);
647 if ptr
::eq(parent
, self.r
.graph_root
) {
648 if let Some(entry
) = self.r
.extern_prelude
.get(&ident
.modern()) {
649 if expansion
!= ExpnId
::root()
650 && orig_name
.is_some()
651 && entry
.extern_crate_item
.is_none()
653 let msg
= "macro-expanded `extern crate` items cannot \
654 shadow names passed with `--extern`";
655 self.r
.session
.span_err(item
.span
, msg
);
659 self.r
.extern_prelude
.entry(ident
.modern()).or_insert(ExternPreludeEntry
{
660 extern_crate_item
: None
,
661 introduced_by_item
: true,
663 entry
.extern_crate_item
= Some(imported_binding
);
664 if orig_name
.is_some() {
665 entry
.introduced_by_item
= true;
668 self.r
.define(parent
, ident
, TypeNS
, imported_binding
);
671 ItemKind
::Mod(..) if ident
.name
== kw
::Invalid
=> {}
// Crate root
673 ItemKind
::Mod(..) => {
674 let def_id
= self.r
.definitions
.local_def_id(item
.id
);
675 let module_kind
= ModuleKind
::Def(DefKind
::Mod
, def_id
, ident
.name
);
676 let module
= self.r
.arenas
.alloc_module(ModuleData
{
677 no_implicit_prelude
: parent
.no_implicit_prelude
|| {
678 attr
::contains_name(&item
.attrs
, sym
::no_implicit_prelude
)
680 ..ModuleData
::new(Some(parent
), module_kind
, def_id
, expansion
, item
.span
)
682 self.r
.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
683 self.r
.module_map
.insert(def_id
, module
);
685 // Descend into the module.
686 self.parent_scope
.module
= module
;
689 // These items live in the value namespace.
690 ItemKind
::Static(..) => {
691 let res
= Res
::Def(DefKind
::Static
, self.r
.definitions
.local_def_id(item
.id
));
692 self.r
.define(parent
, ident
, ValueNS
, (res
, vis
, sp
, expansion
));
694 ItemKind
::Const(..) => {
695 let res
= Res
::Def(DefKind
::Const
, self.r
.definitions
.local_def_id(item
.id
));
696 self.r
.define(parent
, ident
, ValueNS
, (res
, vis
, sp
, expansion
));
698 ItemKind
::Fn(..) => {
699 let res
= Res
::Def(DefKind
::Fn
, self.r
.definitions
.local_def_id(item
.id
));
700 self.r
.define(parent
, ident
, ValueNS
, (res
, vis
, sp
, expansion
));
702 // Functions introducing procedural macros reserve a slot
703 // in the macro namespace as well (see #52225).
704 self.define_macro(item
);
707 // These items live in the type namespace.
708 ItemKind
::TyAlias(_
, _
, _
, ref ty
) => {
709 let def_kind
= match ty
.as_deref().and_then(|ty
| ty
.kind
.opaque_top_hack()) {
710 None
=> DefKind
::TyAlias
,
711 Some(_
) => DefKind
::OpaqueTy
,
713 let res
= Res
::Def(def_kind
, self.r
.definitions
.local_def_id(item
.id
));
714 self.r
.define(parent
, ident
, TypeNS
, (res
, vis
, sp
, expansion
));
717 ItemKind
::Enum(_
, _
) => {
718 let def_id
= self.r
.definitions
.local_def_id(item
.id
);
719 self.r
.variant_vis
.insert(def_id
, vis
);
720 let module_kind
= ModuleKind
::Def(DefKind
::Enum
, def_id
, ident
.name
);
721 let module
= self.r
.new_module(
724 parent
.normal_ancestor_id
,
728 self.r
.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
729 self.parent_scope
.module
= module
;
732 ItemKind
::TraitAlias(..) => {
733 let res
= Res
::Def(DefKind
::TraitAlias
, self.r
.definitions
.local_def_id(item
.id
));
734 self.r
.define(parent
, ident
, TypeNS
, (res
, vis
, sp
, expansion
));
737 // These items live in both the type and value namespaces.
738 ItemKind
::Struct(ref vdata
, _
) => {
739 // Define a name in the type namespace.
740 let def_id
= self.r
.definitions
.local_def_id(item
.id
);
741 let res
= Res
::Def(DefKind
::Struct
, def_id
);
742 self.r
.define(parent
, ident
, TypeNS
, (res
, vis
, sp
, expansion
));
744 // Record field names for error reporting.
745 self.insert_field_names_local(def_id
, vdata
);
747 // If this is a tuple or unit struct, define a name
748 // in the value namespace as well.
749 if let Some(ctor_node_id
) = vdata
.ctor_id() {
750 let mut ctor_vis
= vis
;
751 // If the structure is marked as non_exhaustive then lower the visibility
752 // to within the crate.
753 if vis
== ty
::Visibility
::Public
754 && attr
::contains_name(&item
.attrs
, sym
::non_exhaustive
)
756 ctor_vis
= ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
));
758 for field
in vdata
.fields() {
759 // NOTE: The field may be an expansion placeholder, but expansion sets
760 // correct visibilities for unnamed field placeholders specifically, so the
761 // constructor visibility should still be determined correctly.
762 if let Ok(field_vis
) = self.resolve_visibility_speculative(&field
.vis
, true)
764 if ctor_vis
.is_at_least(field_vis
, &*self.r
) {
765 ctor_vis
= field_vis
;
769 let ctor_res
= Res
::Def(
770 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::from_ast(vdata
)),
771 self.r
.definitions
.local_def_id(ctor_node_id
),
773 self.r
.define(parent
, ident
, ValueNS
, (ctor_res
, ctor_vis
, sp
, expansion
));
774 self.r
.struct_constructors
.insert(def_id
, (ctor_res
, ctor_vis
));
778 ItemKind
::Union(ref vdata
, _
) => {
779 let def_id
= self.r
.definitions
.local_def_id(item
.id
);
780 let res
= Res
::Def(DefKind
::Union
, def_id
);
781 self.r
.define(parent
, ident
, TypeNS
, (res
, vis
, sp
, expansion
));
783 // Record field names for error reporting.
784 self.insert_field_names_local(def_id
, vdata
);
787 ItemKind
::Trait(..) => {
788 let def_id
= self.r
.definitions
.local_def_id(item
.id
);
790 // Add all the items within to a new module.
791 let module_kind
= ModuleKind
::Def(DefKind
::Trait
, def_id
, ident
.name
);
792 let module
= self.r
.new_module(
795 parent
.normal_ancestor_id
,
799 self.r
.define(parent
, ident
, TypeNS
, (module
, vis
, sp
, expansion
));
800 self.parent_scope
.module
= module
;
803 // These items do not add names to modules.
804 ItemKind
::Impl { .. }
| ItemKind
::ForeignMod(..) | ItemKind
::GlobalAsm(..) => {}
806 ItemKind
::MacroDef(..) | ItemKind
::Mac(_
) => unreachable
!(),
810 /// Constructs the reduced graph for one foreign item.
811 fn build_reduced_graph_for_foreign_item(&mut self, item
: &ForeignItem
) {
812 let (res
, ns
) = match item
.kind
{
813 ForeignItemKind
::Fn(..) => {
814 (Res
::Def(DefKind
::Fn
, self.r
.definitions
.local_def_id(item
.id
)), ValueNS
)
816 ForeignItemKind
::Static(..) => {
817 (Res
::Def(DefKind
::Static
, self.r
.definitions
.local_def_id(item
.id
)), ValueNS
)
819 ForeignItemKind
::TyAlias(..) => {
820 (Res
::Def(DefKind
::ForeignTy
, self.r
.definitions
.local_def_id(item
.id
)), TypeNS
)
822 ForeignItemKind
::Macro(_
) => unreachable
!(),
824 let parent
= self.parent_scope
.module
;
825 let expansion
= self.parent_scope
.expansion
;
826 let vis
= self.resolve_visibility(&item
.vis
);
827 self.r
.define(parent
, item
.ident
, ns
, (res
, vis
, item
.span
, expansion
));
830 fn build_reduced_graph_for_block(&mut self, block
: &Block
) {
831 let parent
= self.parent_scope
.module
;
832 let expansion
= self.parent_scope
.expansion
;
833 if self.block_needs_anonymous_module(block
) {
834 let module
= self.r
.new_module(
836 ModuleKind
::Block(block
.id
),
837 parent
.normal_ancestor_id
,
841 self.r
.block_map
.insert(block
.id
, module
);
842 self.parent_scope
.module
= module
; // Descend into the block.
846 /// Builds the reduced graph for a single item in an external crate.
847 fn build_reduced_graph_for_external_crate_res(&mut self, child
: Export
<NodeId
>) {
848 let parent
= self.parent_scope
.module
;
849 let Export { ident, res, vis, span }
= child
;
850 let expansion
= ExpnId
::root(); // FIXME(jseyfried) intercrate hygiene
851 // Record primary definitions.
853 Res
::Def(kind @ DefKind
::Mod
, def_id
)
854 | Res
::Def(kind @ DefKind
::Enum
, def_id
)
855 | Res
::Def(kind @ DefKind
::Trait
, def_id
) => {
856 let module
= self.r
.new_module(
858 ModuleKind
::Def(kind
, def_id
, ident
.name
),
863 self.r
.define(parent
, ident
, TypeNS
, (module
, vis
, span
, expansion
));
865 Res
::Def(DefKind
::Struct
, _
)
866 | Res
::Def(DefKind
::Union
, _
)
867 | Res
::Def(DefKind
::Variant
, _
)
868 | Res
::Def(DefKind
::TyAlias
, _
)
869 | Res
::Def(DefKind
::ForeignTy
, _
)
870 | Res
::Def(DefKind
::OpaqueTy
, _
)
871 | Res
::Def(DefKind
::TraitAlias
, _
)
872 | Res
::Def(DefKind
::AssocTy
, _
)
873 | Res
::Def(DefKind
::AssocOpaqueTy
, _
)
875 | Res
::ToolMod
=> self.r
.define(parent
, ident
, TypeNS
, (res
, vis
, span
, expansion
)),
876 Res
::Def(DefKind
::Fn
, _
)
877 | Res
::Def(DefKind
::Method
, _
)
878 | Res
::Def(DefKind
::Static
, _
)
879 | Res
::Def(DefKind
::Const
, _
)
880 | Res
::Def(DefKind
::AssocConst
, _
)
881 | Res
::Def(DefKind
::Ctor(..), _
) => {
882 self.r
.define(parent
, ident
, ValueNS
, (res
, vis
, span
, expansion
))
884 Res
::Def(DefKind
::Macro(..), _
) | Res
::NonMacroAttr(..) => {
885 self.r
.define(parent
, ident
, MacroNS
, (res
, vis
, span
, expansion
))
887 Res
::Def(DefKind
::TyParam
, _
)
888 | Res
::Def(DefKind
::ConstParam
, _
)
892 | Res
::Err
=> bug
!("unexpected resolution: {:?}", res
),
894 // Record some extra data for better diagnostics.
895 let cstore
= self.r
.cstore();
897 Res
::Def(DefKind
::Struct
, def_id
) | Res
::Def(DefKind
::Union
, def_id
) => {
898 let field_names
= cstore
.struct_field_names_untracked(def_id
, self.r
.session
);
899 self.insert_field_names(def_id
, field_names
);
901 Res
::Def(DefKind
::Method
, def_id
) => {
902 if cstore
.associated_item_cloned_untracked(def_id
).method_has_self_argument
{
903 self.r
.has_self
.insert(def_id
);
906 Res
::Def(DefKind
::Ctor(CtorOf
::Struct
, ..), def_id
) => {
907 let parent
= cstore
.def_key(def_id
).parent
;
908 if let Some(struct_def_id
) = parent
.map(|index
| DefId { index, ..def_id }
) {
909 self.r
.struct_constructors
.insert(struct_def_id
, (res
, vis
));
916 fn legacy_import_macro(
919 binding
: &'a NameBinding
<'a
>,
921 allow_shadowing
: bool
,
923 if self.r
.macro_use_prelude
.insert(name
, binding
).is_some() && !allow_shadowing
{
924 let msg
= format
!("`{}` is already in scope", name
);
926 "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
927 self.r
.session
.struct_span_err(span
, &msg
).note(note
).emit();
931 /// Returns `true` if we should consider the underlying `extern crate` to be used.
932 fn process_legacy_macro_imports(&mut self, item
: &Item
, module
: Module
<'a
>) -> bool
{
933 let mut import_all
= None
;
934 let mut single_imports
= Vec
::new();
935 for attr
in &item
.attrs
{
936 if attr
.check_name(sym
::macro_use
) {
937 if self.parent_scope
.module
.parent
.is_some() {
942 "an `extern crate` loading macros must be at the crate root"
946 if let ItemKind
::ExternCrate(Some(orig_name
)) = item
.kind
{
947 if orig_name
== kw
::SelfLower
{
952 "`#[macro_use]` is not supported on `extern crate self`",
958 |span
| struct_span_err
!(self.r
.session
, span
, E0466
, "bad macro import").emit();
960 Some(meta
) => match meta
.kind
{
961 MetaItemKind
::Word
=> {
962 import_all
= Some(meta
.span
);
965 MetaItemKind
::List(nested_metas
) => {
966 for nested_meta
in nested_metas
{
967 match nested_meta
.ident() {
968 Some(ident
) if nested_meta
.is_word() => {
969 single_imports
.push(ident
)
971 _
=> ill_formed(nested_meta
.span()),
975 MetaItemKind
::NameValue(..) => ill_formed(meta
.span
),
977 None
=> ill_formed(attr
.span
),
982 let macro_use_import
= |this
: &Self, span
| {
983 this
.r
.arenas
.alloc_import(Import
{
984 kind
: ImportKind
::MacroUse
,
987 parent_scope
: this
.parent_scope
,
988 imported_module
: Cell
::new(Some(ModuleOrUniformRoot
::Module(module
))),
989 use_span_with_attributes
: item
.span_with_attributes(),
990 has_attributes
: !item
.attrs
.is_empty(),
994 module_path
: Vec
::new(),
995 vis
: Cell
::new(ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
))),
996 used
: Cell
::new(false),
1000 let allow_shadowing
= self.parent_scope
.expansion
== ExpnId
::root();
1001 if let Some(span
) = import_all
{
1002 let import
= macro_use_import(self, span
);
1003 self.r
.potentially_unused_imports
.push(import
);
1004 module
.for_each_child(self, |this
, ident
, ns
, binding
| {
1006 let imported_binding
= this
.r
.import(binding
, import
);
1007 this
.legacy_import_macro(ident
.name
, imported_binding
, span
, allow_shadowing
);
1011 for ident
in single_imports
.iter().cloned() {
1012 let result
= self.r
.resolve_ident_in_module(
1013 ModuleOrUniformRoot
::Module(module
),
1020 if let Ok(binding
) = result
{
1021 let import
= macro_use_import(self, ident
.span
);
1022 self.r
.potentially_unused_imports
.push(import
);
1023 let imported_binding
= self.r
.import(binding
, import
);
1024 self.legacy_import_macro(
1031 struct_span_err
!(self.r
.session
, ident
.span
, E0469
, "imported macro not found")
1036 import_all
.is_some() || !single_imports
.is_empty()
1039 /// Returns `true` if this attribute list contains `macro_use`.
1040 fn contains_macro_use(&mut self, attrs
: &[ast
::Attribute
]) -> bool
{
1042 if attr
.check_name(sym
::macro_escape
) {
1043 let msg
= "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`";
1044 let mut err
= self.r
.session
.struct_span_warn(attr
.span
, msg
);
1045 if let ast
::AttrStyle
::Inner
= attr
.style
{
1046 err
.help("try an outer attribute: `#[macro_use]`").emit();
1050 } else if !attr
.check_name(sym
::macro_use
) {
1054 if !attr
.is_word() {
1055 self.r
.session
.span_err(attr
.span
, "arguments to `macro_use` are not allowed here");
1063 fn visit_invoc(&mut self, id
: NodeId
) -> LegacyScope
<'a
> {
1064 let invoc_id
= id
.placeholder_to_expn_id();
1066 self.parent_scope
.module
.unexpanded_invocations
.borrow_mut().insert(invoc_id
);
1068 let old_parent_scope
= self.r
.invocation_parent_scopes
.insert(invoc_id
, self.parent_scope
);
1069 assert
!(old_parent_scope
.is_none(), "invocation data is reset for an invocation");
1071 LegacyScope
::Invocation(invoc_id
)
1074 fn proc_macro_stub(item
: &ast
::Item
) -> Option
<(MacroKind
, Ident
, Span
)> {
1075 if attr
::contains_name(&item
.attrs
, sym
::proc_macro
) {
1076 return Some((MacroKind
::Bang
, item
.ident
, item
.span
));
1077 } else if attr
::contains_name(&item
.attrs
, sym
::proc_macro_attribute
) {
1078 return Some((MacroKind
::Attr
, item
.ident
, item
.span
));
1079 } else if let Some(attr
) = attr
::find_by_name(&item
.attrs
, sym
::proc_macro_derive
) {
1080 if let Some(nested_meta
) = attr
.meta_item_list().and_then(|list
| list
.get(0).cloned()) {
1081 if let Some(ident
) = nested_meta
.ident() {
1082 return Some((MacroKind
::Derive
, ident
, ident
.span
));
1089 // Mark the given macro as unused unless its name starts with `_`.
1090 // Macro uses will remove items from this set, and the remaining
1091 // items will be reported as `unused_macros`.
1092 fn insert_unused_macro(&mut self, ident
: Ident
, node_id
: NodeId
, span
: Span
) {
1093 if !ident
.as_str().starts_with('_'
) {
1094 self.r
.unused_macros
.insert(node_id
, span
);
1098 fn define_macro(&mut self, item
: &ast
::Item
) -> LegacyScope
<'a
> {
1099 let parent_scope
= self.parent_scope
;
1100 let expansion
= parent_scope
.expansion
;
1101 let (ext
, ident
, span
, is_legacy
) = match &item
.kind
{
1102 ItemKind
::MacroDef(def
) => {
1103 let ext
= Lrc
::new(self.r
.compile_macro(item
, self.r
.session
.edition()));
1104 (ext
, item
.ident
, item
.span
, def
.legacy
)
1106 ItemKind
::Fn(..) => match Self::proc_macro_stub(item
) {
1107 Some((macro_kind
, ident
, span
)) => {
1108 self.r
.proc_macro_stubs
.insert(item
.id
);
1109 (self.r
.dummy_ext(macro_kind
), ident
, span
, false)
1111 None
=> return parent_scope
.legacy
,
1113 _
=> unreachable
!(),
1116 let def_id
= self.r
.definitions
.local_def_id(item
.id
);
1117 let res
= Res
::Def(DefKind
::Macro(ext
.macro_kind()), def_id
);
1118 self.r
.macro_map
.insert(def_id
, ext
);
1119 self.r
.local_macro_def_scopes
.insert(item
.id
, parent_scope
.module
);
1122 let ident
= ident
.modern();
1123 self.r
.macro_names
.insert(ident
);
1124 let is_macro_export
= attr
::contains_name(&item
.attrs
, sym
::macro_export
);
1125 let vis
= if is_macro_export
{
1126 ty
::Visibility
::Public
1128 ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
))
1130 let binding
= (res
, vis
, span
, expansion
).to_name_binding(self.r
.arenas
);
1131 self.r
.set_binding_parent_module(binding
, parent_scope
.module
);
1132 self.r
.all_macros
.insert(ident
.name
, res
);
1133 if is_macro_export
{
1134 let module
= self.r
.graph_root
;
1135 self.r
.define(module
, ident
, MacroNS
, (res
, vis
, span
, expansion
, IsMacroExport
));
1137 self.r
.check_reserved_macro_name(ident
, res
);
1138 self.insert_unused_macro(ident
, item
.id
, span
);
1140 LegacyScope
::Binding(self.r
.arenas
.alloc_legacy_binding(LegacyBinding
{
1141 parent_legacy_scope
: parent_scope
.legacy
,
1146 let module
= parent_scope
.module
;
1147 let vis
= self.resolve_visibility(&item
.vis
);
1148 if vis
!= ty
::Visibility
::Public
{
1149 self.insert_unused_macro(ident
, item
.id
, span
);
1151 self.r
.define(module
, ident
, MacroNS
, (res
, vis
, span
, expansion
));
1152 self.parent_scope
.legacy
1157 macro_rules
! method
{
1158 ($visit
:ident
: $ty
:ty
, $invoc
:path
, $walk
:ident
) => {
1159 fn $
visit(&mut self, node
: &'b $ty
) {
1160 if let $
invoc(..) = node
.kind
{
1161 self.visit_invoc(node
.id
);
1163 visit
::$
walk(self, node
);
1169 impl<'a
, 'b
> Visitor
<'b
> for BuildReducedGraphVisitor
<'a
, 'b
> {
1170 method
!(visit_expr
: ast
::Expr
, ast
::ExprKind
::Mac
, walk_expr
);
1171 method
!(visit_pat
: ast
::Pat
, ast
::PatKind
::Mac
, walk_pat
);
1172 method
!(visit_ty
: ast
::Ty
, ast
::TyKind
::Mac
, walk_ty
);
1174 fn visit_item(&mut self, item
: &'b Item
) {
1175 let macro_use
= match item
.kind
{
1176 ItemKind
::MacroDef(..) => {
1177 self.parent_scope
.legacy
= self.define_macro(item
);
1180 ItemKind
::Mac(..) => {
1181 self.parent_scope
.legacy
= self.visit_invoc(item
.id
);
1184 ItemKind
::Mod(..) => self.contains_macro_use(&item
.attrs
),
1187 let orig_current_module
= self.parent_scope
.module
;
1188 let orig_current_legacy_scope
= self.parent_scope
.legacy
;
1189 self.build_reduced_graph_for_item(item
);
1190 visit
::walk_item(self, item
);
1191 self.parent_scope
.module
= orig_current_module
;
1193 self.parent_scope
.legacy
= orig_current_legacy_scope
;
1197 fn visit_stmt(&mut self, stmt
: &'b ast
::Stmt
) {
1198 if let ast
::StmtKind
::Mac(..) = stmt
.kind
{
1199 self.parent_scope
.legacy
= self.visit_invoc(stmt
.id
);
1201 visit
::walk_stmt(self, stmt
);
1205 fn visit_foreign_item(&mut self, foreign_item
: &'b ForeignItem
) {
1206 if let ForeignItemKind
::Macro(_
) = foreign_item
.kind
{
1207 self.visit_invoc(foreign_item
.id
);
1211 self.build_reduced_graph_for_foreign_item(foreign_item
);
1212 visit
::walk_foreign_item(self, foreign_item
);
1215 fn visit_block(&mut self, block
: &'b Block
) {
1216 let orig_current_module
= self.parent_scope
.module
;
1217 let orig_current_legacy_scope
= self.parent_scope
.legacy
;
1218 self.build_reduced_graph_for_block(block
);
1219 visit
::walk_block(self, block
);
1220 self.parent_scope
.module
= orig_current_module
;
1221 self.parent_scope
.legacy
= orig_current_legacy_scope
;
1224 fn visit_assoc_item(&mut self, item
: &'b AssocItem
, ctxt
: AssocCtxt
) {
1225 let parent
= self.parent_scope
.module
;
1227 if let AssocItemKind
::Macro(_
) = item
.kind
{
1228 self.visit_invoc(item
.id
);
1232 if let AssocCtxt
::Impl
= ctxt
{
1233 self.resolve_visibility(&item
.vis
);
1234 visit
::walk_assoc_item(self, item
, ctxt
);
1238 // Add the item to the trait info.
1239 let item_def_id
= self.r
.definitions
.local_def_id(item
.id
);
1240 let (res
, ns
) = match item
.kind
{
1241 AssocItemKind
::Const(..) => (Res
::Def(DefKind
::AssocConst
, item_def_id
), ValueNS
),
1242 AssocItemKind
::Fn(_
, ref sig
, _
, _
) => {
1243 if sig
.decl
.has_self() {
1244 self.r
.has_self
.insert(item_def_id
);
1246 (Res
::Def(DefKind
::Method
, item_def_id
), ValueNS
)
1248 AssocItemKind
::TyAlias(..) => (Res
::Def(DefKind
::AssocTy
, item_def_id
), TypeNS
),
1249 AssocItemKind
::Macro(_
) => bug
!(), // handled above
1252 let vis
= ty
::Visibility
::Public
;
1253 let expansion
= self.parent_scope
.expansion
;
1254 self.r
.define(parent
, item
.ident
, ns
, (res
, vis
, item
.span
, expansion
));
1256 visit
::walk_assoc_item(self, item
, ctxt
);
1259 fn visit_token(&mut self, t
: Token
) {
1260 if let token
::Interpolated(nt
) = t
.kind
{
1261 if let token
::NtExpr(ref expr
) = *nt
{
1262 if let ast
::ExprKind
::Mac(..) = expr
.kind
{
1263 self.visit_invoc(expr
.id
);
1269 fn visit_attribute(&mut self, attr
: &'b ast
::Attribute
) {
1270 if !attr
.is_doc_comment() && attr
::is_builtin_attr(attr
) {
1273 .push((attr
.get_normal_item().path
.segments
[0].ident
, self.parent_scope
));
1275 visit
::walk_attribute(self, attr
);
1278 fn visit_arm(&mut self, arm
: &'b ast
::Arm
) {
1279 if arm
.is_placeholder
{
1280 self.visit_invoc(arm
.id
);
1282 visit
::walk_arm(self, arm
);
1286 fn visit_field(&mut self, f
: &'b ast
::Field
) {
1287 if f
.is_placeholder
{
1288 self.visit_invoc(f
.id
);
1290 visit
::walk_field(self, f
);
1294 fn visit_field_pattern(&mut self, fp
: &'b ast
::FieldPat
) {
1295 if fp
.is_placeholder
{
1296 self.visit_invoc(fp
.id
);
1298 visit
::walk_field_pattern(self, fp
);
1302 fn visit_generic_param(&mut self, param
: &'b ast
::GenericParam
) {
1303 if param
.is_placeholder
{
1304 self.visit_invoc(param
.id
);
1306 visit
::walk_generic_param(self, param
);
1310 fn visit_param(&mut self, p
: &'b ast
::Param
) {
1311 if p
.is_placeholder
{
1312 self.visit_invoc(p
.id
);
1314 visit
::walk_param(self, p
);
1318 fn visit_struct_field(&mut self, sf
: &'b ast
::StructField
) {
1319 if sf
.is_placeholder
{
1320 self.visit_invoc(sf
.id
);
1322 self.resolve_visibility(&sf
.vis
);
1323 visit
::walk_struct_field(self, sf
);
1327 // Constructs the reduced graph for one variant. Variants exist in the
1328 // type and value namespaces.
1329 fn visit_variant(&mut self, variant
: &'b ast
::Variant
) {
1330 if variant
.is_placeholder
{
1331 self.visit_invoc(variant
.id
);
1335 let parent
= self.parent_scope
.module
;
1336 let vis
= self.r
.variant_vis
[&parent
.def_id().expect("enum without def-id")];
1337 let expn_id
= self.parent_scope
.expansion
;
1338 let ident
= variant
.ident
;
1340 // Define a name in the type namespace.
1341 let def_id
= self.r
.definitions
.local_def_id(variant
.id
);
1342 let res
= Res
::Def(DefKind
::Variant
, def_id
);
1343 self.r
.define(parent
, ident
, TypeNS
, (res
, vis
, variant
.span
, expn_id
));
1345 // If the variant is marked as non_exhaustive then lower the visibility to within the
1347 let mut ctor_vis
= vis
;
1348 let has_non_exhaustive
= attr
::contains_name(&variant
.attrs
, sym
::non_exhaustive
);
1349 if has_non_exhaustive
&& vis
== ty
::Visibility
::Public
{
1350 ctor_vis
= ty
::Visibility
::Restricted(DefId
::local(CRATE_DEF_INDEX
));
1353 // Define a constructor name in the value namespace.
1354 // Braced variants, unlike structs, generate unusable names in
1355 // value namespace, they are reserved for possible future use.
1356 // It's ok to use the variant's id as a ctor id since an
1357 // error will be reported on any use of such resolution anyway.
1358 let ctor_node_id
= variant
.data
.ctor_id().unwrap_or(variant
.id
);
1359 let ctor_def_id
= self.r
.definitions
.local_def_id(ctor_node_id
);
1360 let ctor_kind
= CtorKind
::from_ast(&variant
.data
);
1361 let ctor_res
= Res
::Def(DefKind
::Ctor(CtorOf
::Variant
, ctor_kind
), ctor_def_id
);
1362 self.r
.define(parent
, ident
, ValueNS
, (ctor_res
, ctor_vis
, variant
.span
, expn_id
));
1364 visit
::walk_variant(self, variant
);