Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve/metadata: Stop encoding macros as reexports #91795

Merged
merged 4 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
),
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
let body = P(self.lower_mac_args(body));

hir::ItemKind::Macro(ast::MacroDef { body, macro_rules })
let macro_kind = self.resolver.decl_macro_kind(self.resolver.local_def_id(id));
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind)
}
ItemKind::MacCall(..) => {
panic!("`TyMac` should have been expanded by now")
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ use rustc_session::lint::LintBuffer;
use rustc_session::parse::feature_err;
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
use rustc_session::Session;
use rustc_span::hygiene::ExpnId;
use rustc_span::hygiene::{ExpnId, MacroKind};
use rustc_span::source_map::{respan, DesugaringKind};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
Expand Down Expand Up @@ -210,6 +210,8 @@ pub trait ResolverAstLowering {
expn_id: ExpnId,
span: Span,
) -> LocalDefId;

fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind;
}

/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable_Generic;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{def_id::LocalDefId, BytePos, MultiSpan, Span, DUMMY_SP};
Expand Down Expand Up @@ -2803,7 +2804,7 @@ pub enum ItemKind<'hir> {
/// A function declaration.
Fn(FnSig<'hir>, Generics<'hir>, BodyId),
/// A MBE macro definition (`macro_rules!` or `macro`).
Macro(ast::MacroDef),
Macro(ast::MacroDef, MacroKind),
/// A module.
Mod(Mod<'hir>),
/// An external module, e.g. `extern { .. }`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
item.span,
item.hir_id(),
),
ItemKind::Macro(_) => {
ItemKind::Macro(..) => {
visitor.visit_id(item.hir_id());
}
ItemKind::Mod(ref module) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ impl<'a> State<'a> {
self.end(); // need to close a box
self.ann.nested(self, Nested::Body(body));
}
hir::ItemKind::Macro(ref macro_def) => {
hir::ItemKind::Macro(ref macro_def, _) => {
self.print_mac_def(macro_def, &item.ident, item.span, |state| {
state.print_visibility(&item.vis)
});
Expand Down
38 changes: 28 additions & 10 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::rmeta::table::{FixedSizeEncoding, Table};
use crate::rmeta::*;

use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_attr as attr;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
Expand Down Expand Up @@ -1076,6 +1077,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
res,
vis: ty::Visibility::Public,
span: ident.span,
macro_rules: false,
});
}
}
Expand All @@ -1087,17 +1089,19 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
for child_index in children.decode((self, sess)) {
if let Some(ident) = self.opt_item_ident(child_index, sess) {
let kind = self.def_kind(child_index);
if matches!(kind, DefKind::Macro(..)) {
// FIXME: Macros are currently encoded twice, once as items and once as
// reexports. We ignore the items here and only use the reexports.
continue;
}
let def_id = self.local_def_id(child_index);
let res = Res::Def(kind, def_id);
let vis = self.get_visibility(child_index);
let span = self.get_span(child_index, sess);
let macro_rules = match kind {
DefKind::Macro(..) => match self.kind(child_index) {
EntryKind::MacroDef(_, macro_rules) => macro_rules,
_ => unreachable!(),
},
_ => false,
};

callback(ModChild { ident, res, vis, span });
callback(ModChild { ident, res, vis, span, macro_rules });

// For non-re-export structs and variants add their constructors to children.
// Re-export lists automatically contain constructors when necessary.
Expand All @@ -1109,7 +1113,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let ctor_res =
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
let vis = self.get_visibility(ctor_def_id.index);
callback(ModChild { ident, res: ctor_res, vis, span });
callback(ModChild {
ident,
res: ctor_res,
vis,
span,
macro_rules: false,
});
}
}
DefKind::Variant => {
Expand All @@ -1134,7 +1144,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
vis = ty::Visibility::Restricted(crate_def_id);
}
}
callback(ModChild { ident, res: ctor_res, vis, span });
callback(ModChild {
ident,
res: ctor_res,
vis,
span,
macro_rules: false,
});
}
_ => {}
}
Expand Down Expand Up @@ -1402,9 +1418,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
}

fn get_macro(self, id: DefIndex, sess: &Session) -> MacroDef {
fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef {
match self.kind(id) {
EntryKind::MacroDef(macro_def) => macro_def.decode((self, sess)),
EntryKind::MacroDef(mac_args, macro_rules) => {
ast::MacroDef { body: P(mac_args.decode((self, sess))), macro_rules }
}
_ => bug!(),
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1406,8 +1406,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

EntryKind::Fn(self.lazy(data))
}
hir::ItemKind::Macro(ref macro_def) => {
EntryKind::MacroDef(self.lazy(macro_def.clone()))
hir::ItemKind::Macro(ref macro_def, _) => {
EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules)
}
hir::ItemKind::Mod(ref m) => {
return self.encode_info_for_mod(item.def_id, m);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use decoder::Metadata;
use def_path_hash_map::DefPathHashMapRef;
use table::{Table, TableBuilder};

use rustc_ast::{self as ast, MacroDef};
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::MetadataRef;
Expand Down Expand Up @@ -350,7 +350,7 @@ enum EntryKind {
Fn(Lazy<FnData>),
ForeignFn(Lazy<FnData>),
Mod(Lazy<[ModChild]>),
MacroDef(Lazy<MacroDef>),
MacroDef(Lazy<ast::MacArgs>, /*macro_rules*/ bool),
ProcMacro(MacroKind),
Closure,
Generator,
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use rustc_hir::*;
use rustc_index::vec::Idx;
use rustc_middle::hir::nested_filter;
use rustc_span::def_id::StableCrateId;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
Expand Down Expand Up @@ -232,7 +231,7 @@ impl<'hir> Map<'hir> {
ItemKind::Static(..) => DefKind::Static,
ItemKind::Const(..) => DefKind::Const,
ItemKind::Fn(..) => DefKind::Fn,
ItemKind::Macro(..) => DefKind::Macro(MacroKind::Bang),
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
ItemKind::Mod(..) => DefKind::Mod,
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
ItemKind::TyAlias(..) => DefKind::TyAlias,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ pub struct ModChild {
pub vis: ty::Visibility,
/// Span of the item.
pub span: Span,
/// A proper `macro_rules` item (not a reexport).
pub macro_rules: bool,
}
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1951,7 +1951,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
// Historically we've run more checks on non-exported than exported macros,
// so this lets us continue to run them while maintaining backwards compatibility.
// In the long run, the checks should be harmonized.
if let ItemKind::Macro(ref macro_def) = item.kind {
if let ItemKind::Macro(ref macro_def, _) = item.kind {
let def_id = item.def_id.to_def_id();
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
// privacy and mark them reachable.
DefKind::Macro(_) => {
let item = self.tcx.hir().expect_item(def_id);
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }) = item.kind {
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind {
if vis.is_accessible_from(module.to_def_id(), self.tcx) {
self.update(def_id, level);
}
Expand Down Expand Up @@ -686,7 +686,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
}
}
}
hir::ItemKind::Macro(ref macro_def) => {
hir::ItemKind::Macro(ref macro_def, _) => {
self.update_reachability_from_macro(item.def_id, macro_def);
}
hir::ItemKind::ForeignMod { items, .. } => {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_resolve/src/access_levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
ast::ItemKind::Impl(..) => return,

// Only exported `macro_rules!` items are public, but they always are
ast::ItemKind::MacroDef(..) => {
ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
let is_macro_export =
item.attrs.iter().any(|attr| attr.has_name(sym::macro_export));
if is_macro_export { Some(AccessLevel::Public) } else { None }
Expand All @@ -155,7 +155,8 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
| ast::ItemKind::Struct(..)
| ast::ItemKind::Union(..)
| ast::ItemKind::Trait(..)
| ast::ItemKind::TraitAlias(..) => {
| ast::ItemKind::TraitAlias(..)
| ast::ItemKind::MacroDef(..) => {
if item.vis.kind.is_pub() {
self.prev_level
} else {
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
/// Builds the reduced graph for a single item in an external crate.
fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) {
let parent = self.parent_scope.module;
let ModChild { ident, res, vis, span } = child;
let ModChild { ident, res, vis, span, macro_rules } = child;
let res = res.expect_non_local();
let expansion = self.parent_scope.expansion;
// Record primary definitions.
Expand Down Expand Up @@ -972,7 +972,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
_,
) => self.r.define(parent, ident, ValueNS, (res, vis, span, expansion)),
Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
self.r.define(parent, ident, MacroNS, (res, vis, span, expansion))
if !macro_rules {
self.r.define(parent, ident, MacroNS, (res, vis, span, expansion))
}
}
Res::Def(
DefKind::TyParam
Expand Down
22 changes: 15 additions & 7 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1399,14 +1399,22 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
let mut reexports = Vec::new();

module.for_each_child(self.r, |_, ident, _, binding| {
// Filter away ambiguous imports and anything that has def-site hygiene.
// FIXME: Implement actual cross-crate hygiene.
let is_good_import =
binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion();
if is_good_import || binding.is_macro_def() {
// FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
// into the crate root to actual `NameBindingKind::Import`.
if binding.is_import()
|| matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
{
let res = binding.res().expect_non_local();
if res != def::Res::Err {
reexports.push(ModChild { ident, res, vis: binding.vis, span: binding.span });
// Ambiguous imports are treated as errors at this point and are
// not exposed to other crates (see #36837 for more details).
if res != def::Res::Err && !binding.is_ambiguity() {
reexports.push(ModChild {
ident,
res,
vis: binding.vis,
span: binding.span,
macro_rules: false,
});
}
}
});
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,10 +845,6 @@ impl<'a> NameBinding<'a> {
)
}

fn is_macro_def(&self) -> bool {
matches!(self.kind, NameBindingKind::Res(Res::Def(DefKind::Macro(..), _), _))
}

fn macro_kind(&self) -> Option<MacroKind> {
self.res().macro_kind()
}
Expand Down Expand Up @@ -990,6 +986,9 @@ pub struct Resolver<'a> {
crate_loader: CrateLoader<'a>,
macro_names: FxHashSet<Ident>,
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
/// A small map keeping true kinds of built-in macros that appear to be fn-like on
/// the surface (`macro` items in libcore), but are actually attributes or derives.
builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
registered_attrs: FxHashSet<Ident>,
registered_tools: RegisteredTools,
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
Expand Down Expand Up @@ -1261,6 +1260,10 @@ impl ResolverAstLowering for Resolver<'_> {

def_id
}

fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind {
self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang)
}
}

impl<'a> Resolver<'a> {
Expand Down Expand Up @@ -1381,6 +1384,7 @@ impl<'a> Resolver<'a> {
crate_loader: CrateLoader::new(session, metadata_loader, crate_name),
macro_names: FxHashSet::default(),
builtin_macros: Default::default(),
builtin_macro_kinds: Default::default(),
registered_attrs,
registered_tools,
macro_use_prelude: FxHashMap::default(),
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,13 @@ impl<'a> Resolver<'a> {
// while still taking everything else from the source code.
// If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
BuiltinMacroState::NotYetSeen(ext) => result.kind = ext,
BuiltinMacroState::NotYetSeen(ext) => {
result.kind = ext;
if item.id != ast::DUMMY_NODE_ID {
self.builtin_macro_kinds
.insert(self.local_def_id(item.id), result.macro_kind());
}
}
BuiltinMacroState::AlreadySeen(span) => {
struct_span_err!(
self.session,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_save_analysis/src/sig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ impl<'hir> Sig for hir::Item<'hir> {

Ok(sig)
}
hir::ItemKind::Macro(_) => {
hir::ItemKind::Macro(..) => {
let mut text = "macro".to_owned();
let name = self.ident.to_string();
text.push_str(&name);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
// These don't define types.
hir::ItemKind::ExternCrate(_)
| hir::ItemKind::Use(..)
| hir::ItemKind::Macro(_)
| hir::ItemKind::Macro(..)
| hir::ItemKind::Mod(_)
| hir::ItemKind::GlobalAsm(_) => {}
hir::ItemKind::ForeignMod { items, .. } => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1855,7 +1855,7 @@ fn clean_maybe_renamed_item(
ItemKind::Fn(ref sig, ref generics, body_id) => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
}
ItemKind::Macro(ref macro_def) => {
ItemKind::Macro(ref macro_def, _) => {
let ty_vis = cx.tcx.visibility(def_id).clean(cx);
MacroItem(Macro {
source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>

fn visit_item(&mut self, item: &'hir hir::Item<'_>) {
let name = match &item.kind {
hir::ItemKind::Macro(ref macro_def) => {
hir::ItemKind::Macro(ref macro_def, _) => {
// FIXME(#88038): Non exported macros have historically not been tested,
// but we really ought to start testing them.
let def_id = item.def_id.to_def_id();
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {

om.items.push((item, renamed))
}
hir::ItemKind::Macro(ref macro_def) => {
hir::ItemKind::Macro(ref macro_def, _) => {
// `#[macro_export] macro_rules!` items are handled seperately in `visit()`,
// above, since they need to be documented at the module top level. Accordingly,
// we only want to handle macros if one of three conditions holds:
Expand Down
Loading