Skip to content

Commit 68afa32

Browse files
authored
Rollup merge of #103760 - petrochenkov:macimp, r=cjgillot
resolve: Turn the binding from `#[macro_export]` into a proper `Import` Continuation of #91795. ```rust #[macro_export] macro_rules! m { /*...*/ } ``` is desugared to something like ```rust macro_rules! m { /*...*/ } // Non-modularized macro_rules item pub use m; // It's modularized reexport ``` This PR adjusts the internal representation to better match this model.
2 parents 9f603fe + 8431751 commit 68afa32

11 files changed

+237
-164
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

+22-33
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,7 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a>
5656
impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span, LocalExpnId) {
5757
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
5858
arenas.alloc_name_binding(NameBinding {
59-
kind: NameBindingKind::Res(self.0, false),
60-
ambiguity: None,
61-
vis: self.1.to_def_id(),
62-
span: self.2,
63-
expansion: self.3,
64-
})
65-
}
66-
}
67-
68-
struct IsMacroExport;
69-
70-
impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId, IsMacroExport) {
71-
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
72-
arenas.alloc_name_binding(NameBinding {
73-
kind: NameBindingKind::Res(self.0, true),
59+
kind: NameBindingKind::Res(self.0),
7460
ambiguity: None,
7561
vis: self.1.to_def_id(),
7662
span: self.2,
@@ -364,7 +350,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
364350
module_path: Vec<Segment>,
365351
kind: ImportKind<'a>,
366352
span: Span,
367-
id: NodeId,
368353
item: &ast::Item,
369354
root_span: Span,
370355
root_id: NodeId,
@@ -377,7 +362,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
377362
module_path,
378363
imported_module: Cell::new(None),
379364
span,
380-
id,
381365
use_span: item.span,
382366
use_span_with_attributes: item.span_with_attributes(),
383367
has_attributes: !item.attrs.is_empty(),
@@ -574,27 +558,20 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
574558
},
575559
type_ns_only,
576560
nested,
561+
id,
577562
additional_ids: (id1, id2),
578563
};
579564

580-
self.add_import(
581-
module_path,
582-
kind,
583-
use_tree.span,
584-
id,
585-
item,
586-
root_span,
587-
item.id,
588-
vis,
589-
);
565+
self.add_import(module_path, kind, use_tree.span, item, root_span, item.id, vis);
590566
}
591567
ast::UseTreeKind::Glob => {
592568
let kind = ImportKind::Glob {
593569
is_prelude: self.r.session.contains_name(&item.attrs, sym::prelude_import),
594570
max_vis: Cell::new(None),
571+
id,
595572
};
596573
self.r.visibilities.insert(self.r.local_def_id(id), vis);
597-
self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis);
574+
self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis);
598575
}
599576
ast::UseTreeKind::Nested(ref items) => {
600577
// Ensure there is at most one `self` in the list
@@ -881,9 +858,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
881858
})
882859
.unwrap_or((true, None, self.r.dummy_binding));
883860
let import = self.r.arenas.alloc_import(Import {
884-
kind: ImportKind::ExternCrate { source: orig_name, target: ident },
861+
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
885862
root_id: item.id,
886-
id: item.id,
887863
parent_scope: self.parent_scope,
888864
imported_module: Cell::new(module),
889865
has_attributes: !item.attrs.is_empty(),
@@ -1118,7 +1094,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
11181094
this.r.arenas.alloc_import(Import {
11191095
kind: ImportKind::MacroUse,
11201096
root_id: item.id,
1121-
id: item.id,
11221097
parent_scope: this.parent_scope,
11231098
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
11241099
use_span_with_attributes: item.span_with_attributes(),
@@ -1278,8 +1253,22 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
12781253
let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas);
12791254
self.r.set_binding_parent_module(binding, parent_scope.module);
12801255
if is_macro_export {
1281-
let module = self.r.graph_root;
1282-
self.r.define(module, ident, MacroNS, (res, vis, span, expansion, IsMacroExport));
1256+
let import = self.r.arenas.alloc_import(Import {
1257+
kind: ImportKind::MacroExport,
1258+
root_id: item.id,
1259+
parent_scope: self.parent_scope,
1260+
imported_module: Cell::new(None),
1261+
has_attributes: false,
1262+
use_span_with_attributes: span,
1263+
use_span: span,
1264+
root_span: span,
1265+
span: span,
1266+
module_path: Vec::new(),
1267+
vis: Cell::new(Some(vis)),
1268+
used: Cell::new(true),
1269+
});
1270+
let import_binding = self.r.import(binding, import);
1271+
self.r.define(self.r.graph_root, ident, MacroNS, import_binding);
12831272
} else {
12841273
self.r.check_reserved_macro_name(ident, res);
12851274
self.insert_unused_macro(ident, def_id, item.id, &rule_spans);

compiler/rustc_resolve/src/check_unused.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ impl Resolver<'_> {
234234
if !import.span.is_dummy() {
235235
self.lint_buffer.buffer_lint(
236236
MACRO_USE_EXTERN_CRATE,
237-
import.id,
237+
import.root_id,
238238
import.span,
239239
"deprecated `#[macro_use]` attribute used to \
240240
import macros should be replaced at use sites \
@@ -244,13 +244,13 @@ impl Resolver<'_> {
244244
}
245245
}
246246
}
247-
ImportKind::ExternCrate { .. } => {
248-
let def_id = self.local_def_id(import.id);
247+
ImportKind::ExternCrate { id, .. } => {
248+
let def_id = self.local_def_id(id);
249249
self.maybe_unused_extern_crates.push((def_id, import.span));
250250
}
251251
ImportKind::MacroUse => {
252252
let msg = "unused `#[macro_use]` import";
253-
self.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.id, import.span, msg);
253+
self.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.root_id, import.span, msg);
254254
}
255255
_ => {}
256256
}

compiler/rustc_resolve/src/diagnostics.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,12 @@ impl<'a> Resolver<'a> {
190190
ModuleKind::Block => "block",
191191
};
192192

193-
let old_noun = match old_binding.is_import() {
193+
let old_noun = match old_binding.is_import_user_facing() {
194194
true => "import",
195195
false => "definition",
196196
};
197197

198-
let new_participle = match new_binding.is_import() {
198+
let new_participle = match new_binding.is_import_user_facing() {
199199
true => "imported",
200200
false => "defined",
201201
};
@@ -226,7 +226,7 @@ impl<'a> Resolver<'a> {
226226
true => struct_span_err!(self.session, span, E0254, "{}", msg),
227227
false => struct_span_err!(self.session, span, E0260, "{}", msg),
228228
},
229-
_ => match (old_binding.is_import(), new_binding.is_import()) {
229+
_ => match (old_binding.is_import_user_facing(), new_binding.is_import_user_facing()) {
230230
(false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
231231
(true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
232232
_ => struct_span_err!(self.session, span, E0255, "{}", msg),
@@ -248,14 +248,18 @@ impl<'a> Resolver<'a> {
248248

249249
// See https://github.com/rust-lang/rust/issues/32354
250250
use NameBindingKind::Import;
251+
let can_suggest = |binding: &NameBinding<'_>, import: &self::Import<'_>| {
252+
!binding.span.is_dummy()
253+
&& !matches!(import.kind, ImportKind::MacroUse | ImportKind::MacroExport)
254+
};
251255
let import = match (&new_binding.kind, &old_binding.kind) {
252256
// If there are two imports where one or both have attributes then prefer removing the
253257
// import without attributes.
254258
(Import { import: new, .. }, Import { import: old, .. })
255259
if {
256-
!new_binding.span.is_dummy()
257-
&& !old_binding.span.is_dummy()
258-
&& (new.has_attributes || old.has_attributes)
260+
(new.has_attributes || old.has_attributes)
261+
&& can_suggest(old_binding, old)
262+
&& can_suggest(new_binding, new)
259263
} =>
260264
{
261265
if old.has_attributes {
@@ -265,10 +269,10 @@ impl<'a> Resolver<'a> {
265269
}
266270
}
267271
// Otherwise prioritize the new binding.
268-
(Import { import, .. }, other) if !new_binding.span.is_dummy() => {
272+
(Import { import, .. }, other) if can_suggest(new_binding, import) => {
269273
Some((import, new_binding.span, other.is_import()))
270274
}
271-
(other, Import { import, .. }) if !old_binding.span.is_dummy() => {
275+
(other, Import { import, .. }) if can_suggest(old_binding, import) => {
272276
Some((import, old_binding.span, other.is_import()))
273277
}
274278
_ => None,
@@ -353,7 +357,7 @@ impl<'a> Resolver<'a> {
353357
}
354358
}
355359
}
356-
ImportKind::ExternCrate { source, target } => {
360+
ImportKind::ExternCrate { source, target, .. } => {
357361
suggestion = Some(format!(
358362
"extern crate {} as {};",
359363
source.unwrap_or(target.name),
@@ -1683,7 +1687,7 @@ impl<'a> Resolver<'a> {
16831687
let a = if built_in.is_empty() { res.article() } else { "a" };
16841688
format!("{a}{built_in} {thing}{from}", thing = res.descr())
16851689
} else {
1686-
let introduced = if b.is_import() { "imported" } else { "defined" };
1690+
let introduced = if b.is_import_user_facing() { "imported" } else { "defined" };
16871691
format!("the {thing} {introduced} here", thing = res.descr())
16881692
}
16891693
}
@@ -1742,10 +1746,10 @@ impl<'a> Resolver<'a> {
17421746
/// If the binding refers to a tuple struct constructor with fields,
17431747
/// returns the span of its fields.
17441748
fn ctor_fields_span(&self, binding: &NameBinding<'_>) -> Option<Span> {
1745-
if let NameBindingKind::Res(
1746-
Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id),
1747-
_,
1748-
) = binding.kind
1749+
if let NameBindingKind::Res(Res::Def(
1750+
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn),
1751+
ctor_def_id,
1752+
)) = binding.kind
17491753
{
17501754
let def_id = self.parent(ctor_def_id);
17511755
let fields = self.field_names.get(&def_id)?;
@@ -1789,7 +1793,9 @@ impl<'a> Resolver<'a> {
17891793
next_ident = source;
17901794
Some(binding)
17911795
}
1792-
ImportKind::Glob { .. } | ImportKind::MacroUse => Some(binding),
1796+
ImportKind::Glob { .. } | ImportKind::MacroUse | ImportKind::MacroExport => {
1797+
Some(binding)
1798+
}
17931799
ImportKind::ExternCrate { .. } => None,
17941800
},
17951801
_ => None,

compiler/rustc_resolve/src/effective_visibilities.rs

+36-24
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,45 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
5757
while let NameBindingKind::Import { binding: nested_binding, import, .. } =
5858
binding.kind
5959
{
60-
let mut update = |node_id| self.update(
61-
self.r.local_def_id(node_id),
62-
binding.vis.expect_local(),
63-
prev_parent_id,
64-
level,
65-
);
66-
// In theory all the import IDs have individual visibilities and effective
67-
// visibilities, but in practice these IDs go straigth to HIR where all
68-
// their few uses assume that their (effective) visibility applies to the
69-
// whole syntactic `use` item. So we update them all to the maximum value
70-
// among the potential individual effective visibilities. Maybe HIR for
71-
// imports shouldn't use three IDs at all.
72-
update(import.id);
73-
if let ImportKind::Single { additional_ids, .. } = import.kind {
74-
update(additional_ids.0);
75-
update(additional_ids.1);
60+
let mut update = |node_id| {
61+
self.update(
62+
self.r.local_def_id(node_id),
63+
binding.vis.expect_local(),
64+
prev_parent_id,
65+
level,
66+
)
67+
};
68+
match import.kind {
69+
ImportKind::Single { id, additional_ids, .. } => {
70+
// In theory all the import IDs have individual visibilities and
71+
// effective visibilities, but in practice these IDs go straigth to
72+
// HIR where all their few uses assume that their (effective)
73+
// visibility applies to the whole syntactic `use` item. So we
74+
// update them all to the maximum value among the potential
75+
// individual effective visibilities. Maybe HIR for imports
76+
// shouldn't use three IDs at all.
77+
update(id);
78+
update(additional_ids.0);
79+
update(additional_ids.1);
80+
prev_parent_id = self.r.local_def_id(id);
81+
}
82+
ImportKind::Glob { id, .. } | ImportKind::ExternCrate { id, .. } => {
83+
update(id);
84+
prev_parent_id = self.r.local_def_id(id);
85+
}
86+
ImportKind::MacroUse => {
87+
// In theory we should reset the parent id to something private
88+
// here, but `macro_use` imports always refer to external items,
89+
// so it doesn't matter and we can just do nothing.
90+
}
91+
ImportKind::MacroExport => {
92+
// In theory we should reset the parent id to something public
93+
// here, but it has the same effect as leaving the previous parent,
94+
// so we can just do nothing.
95+
}
7696
}
7797

7898
level = Level::Reexported;
79-
prev_parent_id = self.r.local_def_id(import.id);
8099
binding = nested_binding;
81100
}
82101
}
@@ -138,13 +157,6 @@ impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> {
138157
self.update(def_id, Visibility::Public, parent_id, Level::Direct);
139158
}
140159

141-
// Only exported `macro_rules!` items are public, but they always are
142-
ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
143-
let parent_id = self.r.local_parent(def_id);
144-
let vis = self.r.visibilities[&def_id];
145-
self.update(def_id, vis, parent_id, Level::Direct);
146-
}
147-
148160
ast::ItemKind::Mod(..) => {
149161
self.set_bindings_effective_visibilities(def_id);
150162
visit::walk_item(self, item);

compiler/rustc_resolve/src/ident.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::late::{
1717
};
1818
use crate::macros::{sub_namespace_match, MacroRulesScope};
1919
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
20-
use crate::{ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
20+
use crate::{Import, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
2121
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res};
2222
use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding, Weak};
2323

@@ -860,7 +860,11 @@ impl<'a> Resolver<'a> {
860860
}
861861

862862
if !restricted_shadowing && binding.expansion != LocalExpnId::ROOT {
863-
if let NameBindingKind::Res(_, true) = binding.kind {
863+
if let NameBindingKind::Import {
864+
import: Import { kind: ImportKind::MacroExport, .. },
865+
..
866+
} = binding.kind
867+
{
864868
self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
865869
}
866870
}

0 commit comments

Comments
 (0)