From 0f5e7cd51b551c677e850a4c51a142daee9d1531 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Fri, 30 Jul 2021 23:50:57 -0700 Subject: [PATCH 01/18] Treat macros as HIR items --- compiler/rustc_ast_lowering/src/item.rs | 44 ++++----- compiler/rustc_ast_lowering/src/lib.rs | 10 -- compiler/rustc_hir/src/def.rs | 7 ++ compiler/rustc_hir/src/hir.rs | 16 +--- compiler/rustc_hir/src/intravisit.rs | 5 +- compiler/rustc_hir/src/stable_hash_impls.rs | 2 +- compiler/rustc_hir/src/target.rs | 1 + compiler/rustc_hir_pretty/src/lib.rs | 23 +++++ compiler/rustc_lint/src/builtin.rs | 21 +---- compiler/rustc_lint/src/late.rs | 4 - compiler/rustc_lint/src/levels.rs | 3 - compiler/rustc_metadata/src/rmeta/decoder.rs | 7 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 21 ++--- .../rustc_middle/src/hir/map/collector.rs | 14 --- compiler/rustc_middle/src/hir/map/mod.rs | 13 +-- .../rustc_mir/src/monomorphize/collector.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 18 ++-- compiler/rustc_passes/src/diagnostic_items.rs | 4 - compiler/rustc_passes/src/lib_features.rs | 4 +- compiler/rustc_passes/src/reachable.rs | 1 + compiler/rustc_passes/src/stability.rs | 15 ++- compiler/rustc_privacy/src/lib.rs | 93 ++++++++++--------- compiler/rustc_resolve/src/late/lifetimes.rs | 1 + compiler/rustc_save_analysis/src/sig.rs | 8 ++ compiler/rustc_typeck/src/collect.rs | 1 + compiler/rustc_typeck/src/collect/type_of.rs | 1 + 26 files changed, 158 insertions(+), 180 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 3acf69ec2b7d0..02a62ebdb2d55 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -170,7 +170,6 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_item_id_use_tree(use_tree, i.id, &mut vec); vec } - ItemKind::MacroDef(..) => SmallVec::new(), ItemKind::Fn(..) | ItemKind::Impl(box ImplKind { of_trait: None, .. }) => { smallvec![i.id] } @@ -212,28 +211,6 @@ impl<'hir> LoweringContext<'_, 'hir> { pub fn lower_item(&mut self, i: &Item) -> Option> { let mut ident = i.ident; let mut vis = self.lower_visibility(&i.vis, None); - - if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind { - if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) { - let hir_id = self.lower_node_id(i.id); - self.lower_attrs(hir_id, &i.attrs); - let body = P(self.lower_mac_args(body)); - self.insert_macro_def(hir::MacroDef { - ident, - vis, - def_id: hir_id.expect_owner(), - span: i.span, - ast: MacroDef { body, macro_rules }, - }); - } else { - for a in i.attrs.iter() { - let a = self.lower_attr(a); - self.non_exported_macro_attrs.push(a); - } - } - return None; - } - let hir_id = self.lower_node_id(i.id); let attrs = self.lower_attrs(hir_id, &i.attrs); let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind); @@ -465,7 +442,26 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics(generics, ImplTraitContext::disallowed()), self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), ), - ItemKind::MacroDef(..) | ItemKind::MacCall(..) => { + ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { + let is_exported = !macro_rules + || attrs.map_or(false, |a| self.sess.contains_name(a, sym::macro_export)); + + let body = P(self.lower_mac_args(body)); + + hir::ItemKind::Macro { + // `is_exported` is duplicated, to make matching more convenient. + is_exported, + macro_def: hir::MacroDef { + is_exported, + ident: *ident, + vis: *vis, + def_id: hir_id.expect_owner(), + span, + ast: MacroDef { body, macro_rules }, + }, + } + } + ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 581f177ad14f6..3fe698c3946ec 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -103,7 +103,6 @@ struct LoweringContext<'a, 'hir: 'a> { /// The items being lowered are collected here. owners: IndexVec>>, bodies: BTreeMap>, - non_exported_macro_attrs: Vec, trait_impls: BTreeMap>, @@ -330,7 +329,6 @@ pub fn lower_crate<'a, 'hir>( trait_impls: BTreeMap::new(), modules: BTreeMap::new(), attrs: BTreeMap::default(), - non_exported_macro_attrs: Vec::new(), catch_scopes: Vec::new(), loop_scopes: Vec::new(), is_in_loop_condition: false, @@ -551,7 +549,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let krate = hir::Crate { - non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs), owners: self.owners, bodies: self.bodies, body_ids, @@ -600,13 +597,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id } - fn insert_macro_def(&mut self, item: hir::MacroDef<'hir>) { - let def_id = item.def_id; - let item = self.arena.alloc(item); - self.owners.ensure_contains_elem(def_id, || None); - self.owners[def_id] = Some(hir::OwnerNode::MacroDef(item)); - } - fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId { // Set up the counter if needed. self.item_local_id_counters.entry(owner).or_insert(0); diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 3816888db1062..1fdf02513bbdc 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -218,6 +218,13 @@ impl DefKind { | DefKind::Impl => None, } } + + pub fn is_macro(self) -> bool { + match self { + DefKind::Macro(..) => true, + _ => false, + } + } } /// The resolution of a path or export. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index fe1d190b4ec1a..d323b439fbfdf 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -670,9 +670,6 @@ pub struct ModuleItems { /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #[derive(Debug)] pub struct Crate<'hir> { - // Attributes from non-exported macros, kept only for collecting the library feature list. - pub non_exported_macro_attrs: &'hir [Attribute], - pub owners: IndexVec>>, pub bodies: BTreeMap>, pub trait_impls: BTreeMap>, @@ -768,13 +765,6 @@ impl Crate<'_> { _ => None, }) } - - pub fn exported_macros<'hir>(&'hir self) -> impl Iterator> + 'hir { - self.owners.iter().filter_map(|owner| match owner { - Some(OwnerNode::MacroDef(macro_def)) => Some(*macro_def), - _ => None, - }) - } } /// A macro definition, in this crate or imported from another. @@ -782,6 +772,7 @@ impl Crate<'_> { /// Not parsed directly, but created on macro import or `macro_rules!` expansion. #[derive(Debug)] pub struct MacroDef<'hir> { + pub is_exported: bool, pub ident: Ident, pub vis: Visibility<'hir>, pub def_id: LocalDefId, @@ -2605,7 +2596,7 @@ pub struct PolyTraitRef<'hir> { pub type Visibility<'hir> = Spanned>; -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] pub enum VisibilityKind<'hir> { Public, Crate(CrateSugar), @@ -2789,6 +2780,8 @@ pub enum ItemKind<'hir> { Mod(Mod<'hir>), /// An external module, e.g. `extern { .. }`. ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] }, + /// A MBE macro (`macro_rules!` or `macro`). + Macro { is_exported: bool, macro_def: MacroDef<'hir> }, /// Module-level inline assembly (from `global_asm!`). GlobalAsm(&'hir InlineAsm<'hir>), /// A type alias, e.g., `type Foo = Bar`. @@ -2852,6 +2845,7 @@ impl ItemKind<'_> { ItemKind::Fn(..) => "function", ItemKind::Mod(..) => "module", ItemKind::ForeignMod { .. } => "extern block", + ItemKind::Macro { .. } => "macro", ItemKind::GlobalAsm(..) => "global asm item", ItemKind::TyAlias(..) => "type alias", ItemKind::OpaqueTy(..) => "opaque type", diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index ae186d66004d7..4816e45e5bed5 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -484,7 +484,6 @@ pub trait Visitor<'v>: Sized { pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) { let top_mod = krate.module(); visitor.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID); - walk_list!(visitor, visit_macro_def, krate.exported_macros()); for (&id, attrs) in krate.attrs.iter() { for a in *attrs { visitor.visit_attribute(id, a) @@ -594,6 +593,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { visitor.visit_id(item.hir_id()); walk_list!(visitor, visit_foreign_item_ref, items); } + ItemKind::Macro { ref macro_def, .. } => { + visitor.visit_id(item.hir_id()); + visitor.visit_macro_def(macro_def) + } ItemKind::GlobalAsm(asm) => { visitor.visit_id(item.hir_id()); walk_inline_asm(visitor, asm); diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 560607528330b..891df8f144522 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -193,7 +193,7 @@ impl HashStable for Item<'_> { impl HashStable for MacroDef<'_> { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - let MacroDef { ident, def_id: _, ref ast, ref vis, span } = *self; + let MacroDef { is_exported: _, ident, def_id: _, ref ast, ref vis, span } = *self; hcx.hash_hir_item_like(|hcx| { ident.name.hash_stable(hcx, hasher); diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 473477bf22da2..ad7bc030cb251 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -113,6 +113,7 @@ impl Target { ItemKind::Fn(..) => Target::Fn, ItemKind::Mod(..) => Target::Mod, ItemKind::ForeignMod { .. } => Target::ForeignMod, + ItemKind::Macro { .. } => Target::MacroDef, ItemKind::GlobalAsm(..) => Target::GlobalAsm, ItemKind::TyAlias(..) => Target::TyAlias, ItemKind::OpaqueTy(..) => Target::OpaqueTy, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 9ad40db73ceea..9870599eb4a48 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -4,6 +4,7 @@ use rustc_ast as ast; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; +use rustc_ast_pretty::pprust::state::MacHeader; use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_hir as hir; use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node}; @@ -660,6 +661,28 @@ impl<'a> State<'a> { } self.bclose(item.span); } + hir::ItemKind::Macro { ref macro_def, .. } => { + let (kw, has_bang) = if macro_def.ast.macro_rules { + ("macro_rules", true) + } else { + self.print_visibility(&item.vis); + ("macro", false) + }; + + self.print_mac_common( + Some(MacHeader::Keyword(kw)), + has_bang, + Some(item.ident), + macro_def.ast.body.delim(), + ¯o_def.ast.body.inner_tokens(), + true, + item.span, + ); + + if macro_def.ast.body.need_semicolon() { + self.word(";"); + } + } hir::ItemKind::GlobalAsm(ref asm) => { self.head(visibility_qualified(&item.vis, "global_asm!")); self.print_inline_asm(asm); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 77c7040e6a76d..8fd468875787b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -586,24 +586,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) { self.check_missing_docs_attrs(cx, CRATE_DEF_ID, krate.module().inner, "the", "crate"); - - for macro_def in krate.exported_macros() { - // Non exported macros should be skipped, since `missing_docs` only - // applies to externally visible items. - if !cx.access_levels.is_exported(macro_def.def_id) { - continue; - } - - let attrs = cx.tcx.hir().attrs(macro_def.hir_id()); - let has_doc = attrs.iter().any(|a| has_doc(cx.sess(), a)); - if !has_doc { - cx.struct_span_lint( - MISSING_DOCS, - cx.tcx.sess.source_map().guess_head_span(macro_def.span), - |lint| lint.build("missing documentation for macro").emit(), - ); - } - } } fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { @@ -635,7 +617,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { return; } - hir::ItemKind::TyAlias(..) + hir::ItemKind::Macro { is_exported: true, .. } + | hir::ItemKind::TyAlias(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) | hir::ItemKind::Enum(..) diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 052efa851f7cf..30400da86b4b0 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -453,10 +453,6 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T) lint_callback!(cx, check_crate, krate); hir_visit::walk_crate(cx, krate); - for attr in krate.non_exported_macro_attrs { - // This HIR ID is a lie, since the macro ID isn't available. - cx.visit_attribute(hir::CRATE_HIR_ID, attr); - } lint_callback!(cx, check_crate_post, krate); }) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index bca3023664ab1..e294890e9739c 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -37,9 +37,6 @@ fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), &store, true); builder.levels.register_id(hir::CRATE_HIR_ID); - for macro_def in krate.exported_macros() { - builder.levels.register_id(macro_def.hir_id()); - } intravisit::walk_crate(&mut builder, krate); builder.levels.pop(push); diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8bdd4313de4c3..c11053619517f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1036,6 +1036,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.local_def_id(def_index), ); let ident = self.item_ident(def_index, sess); + callback(Export { ident, res, vis: ty::Visibility::Public, span: ident.span }); } } @@ -1100,7 +1101,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let vis = self.get_visibility(child_index); let def_id = self.local_def_id(child_index); let res = Res::Def(kind, def_id); - callback(Export { res, ident, vis, span }); + + if !kind.is_macro() { + callback(Export { res, ident, vis, span }); + } + // For non-re-export structs and variants add their constructors to children. // Re-export lists automatically contain constructors when necessary. match kind { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b7921c403bb7b..830fa6a430cde 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -448,9 +448,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } krate.visit_all_item_likes(&mut self.as_deep_visitor()); - for macro_def in krate.exported_macros() { - self.visit_macro_def(macro_def); - } } fn encode_def_path_table(&mut self) { @@ -1377,6 +1374,13 @@ impl EncodeContext<'a, 'tcx> { return self.encode_info_for_mod(item.def_id, m); } hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod, + hir::ItemKind::Macro { is_exported, ref macro_def } => { + if is_exported { + EntryKind::MacroDef(self.lazy(macro_def.ast.clone())) + } else { + return; + } + } hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm, hir::ItemKind::TyAlias(..) => EntryKind::Type, hir::ItemKind::OpaqueTy(..) => { @@ -1527,13 +1531,6 @@ impl EncodeContext<'a, 'tcx> { } } - /// Serialize the text of exported macros - fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) { - let def_id = macro_def.def_id.to_def_id(); - record!(self.tables.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone()))); - self.encode_ident_span(def_id, macro_def.ident); - } - fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) { record!(self.tables.kind[def_id] <- kind); if encode_type { @@ -1903,9 +1900,6 @@ impl Visitor<'tcx> for EncodeContext<'a, 'tcx> { intravisit::walk_generics(self, generics); self.encode_info_for_generics(generics); } - fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) { - self.encode_info_for_macro_def(macro_def); - } } impl EncodeContext<'a, 'tcx> { @@ -1962,6 +1956,7 @@ impl EncodeContext<'a, 'tcx> { | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Macro { .. } | hir::ItemKind::GlobalAsm(..) | hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index 5c166c74004a3..1351b4950f143 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -394,20 +394,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } } - fn visit_macro_def(&mut self, macro_def: &'hir MacroDef<'hir>) { - // Exported macros are visited directly from the crate root, - // so they do not have `parent_node` set. - // Find the correct enclosing module from their DefKey. - let def_key = self.definitions.def_key(macro_def.def_id); - let parent = def_key.parent.map_or(hir::CRATE_HIR_ID, |local_def_index| { - self.definitions.local_def_id_to_hir_id(LocalDefId { local_def_index }) - }); - self.insert_owner(macro_def.def_id, OwnerNode::MacroDef(macro_def)); - self.with_parent(parent, |this| { - this.insert_nested(macro_def.def_id); - }); - } - fn visit_variant(&mut self, v: &'hir Variant<'hir>, g: &'hir Generics<'hir>, item_id: HirId) { self.insert(v.span, v.id, Node::Variant(v)); self.with_parent(v.id, |this| { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index c313146b07222..28423753d7556 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -10,7 +10,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_hir::intravisit; -use rustc_hir::intravisit::Visitor; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::*; use rustc_index::vec::Idx; @@ -229,6 +228,7 @@ impl<'hir> Map<'hir> { ItemKind::ExternCrate(_) => DefKind::ExternCrate, ItemKind::Use(..) => DefKind::Use, ItemKind::ForeignMod { .. } => DefKind::ForeignMod, + ItemKind::Macro { .. } => DefKind::Macro(MacroKind::Bang), ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, ItemKind::Impl { .. } => DefKind::Impl, }, @@ -543,15 +543,6 @@ impl<'hir> Map<'hir> { } } - pub fn visit_exported_macros_in_krate(&self, visitor: &mut V) - where - V: Visitor<'hir>, - { - for macro_def in self.krate().exported_macros() { - visitor.visit_macro_def(macro_def); - } - } - /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`. pub fn parent_iter(&self, current_id: HirId) -> ParentHirIterator<'_, 'hir> { @@ -1013,7 +1004,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { source_file_names.hash_stable(&mut hcx, &mut stable_hasher); tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher); tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher); - tcx.untracked_crate.non_exported_macro_attrs.hash_stable(&mut hcx, &mut stable_hasher); let crate_hash: Fingerprint = stable_hasher.finish(); Svh::new(crate_hash.to_smaller_hash()) @@ -1064,6 +1054,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String { ItemKind::Fn(..) => "fn", ItemKind::Mod(..) => "mod", ItemKind::ForeignMod { .. } => "foreign mod", + ItemKind::Macro { .. } => "macro", ItemKind::GlobalAsm(..) => "global asm", ItemKind::TyAlias(..) => "ty", ItemKind::OpaqueTy(..) => "opaque type", diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 95c4237f38396..faac2a59a01ba 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -1150,6 +1150,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Macro { .. } | hir::ItemKind::TyAlias(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7cca11f20bb9f..6883a6d7a778e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1509,6 +1509,13 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { } fn visit_item(&mut self, item: &'tcx Item<'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 { is_exported: false, .. } = item.kind { + check_non_exported_macro_for_invalid_attrs(self.tcx, item); + } + let target = Target::from_item(item); self.check_attributes(item.hir_id(), &item.span, target, Some(ItemLike::Item(item))); intravisit::walk_item(self, item) @@ -1581,11 +1588,6 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { intravisit::walk_variant(self, variant, generics, item_id) } - fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) { - self.check_attributes(macro_def.hir_id(), ¯o_def.span, Target::MacroDef, None); - intravisit::walk_macro_def(self, macro_def); - } - fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { self.check_attributes(param.hir_id, ¶m.span, Target::Param, None); @@ -1634,7 +1636,9 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { } } -fn check_invalid_macro_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { +fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) { + let attrs = tcx.hir().attrs(item.hir_id()); + for attr in attrs { if tcx.sess.check_name(attr, sym::inline) { struct_span_err!( @@ -1655,8 +1659,6 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { if module_def_id.is_top_level_module() { check_attr_visitor.check_attributes(CRATE_HIR_ID, &DUMMY_SP, Target::Mod, None); check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs()); - tcx.hir().visit_exported_macros_in_krate(check_attr_visitor); - check_invalid_macro_level_attr(tcx, tcx.hir().krate().non_exported_macro_attrs); } } diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 3cf1d0cdd94b7..282c500c4e909 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -108,10 +108,6 @@ fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> FxHashMap for LibFeatureCollector<'tcx> { fn get_lib_features(tcx: TyCtxt<'_>, (): ()) -> LibFeatures { let mut collector = LibFeatureCollector::new(tcx); let krate = tcx.hir().krate(); - for attr in krate.non_exported_macro_attrs { - collector.visit_attribute(rustc_hir::CRATE_HIR_ID, attr); - } + intravisit::walk_crate(&mut collector, krate); collector.lib_features } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 963153a01a080..ebdf887455688 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -264,6 +264,7 @@ impl<'tcx> ReachableContext<'tcx> { | hir::ItemKind::TyAlias(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Macro { .. } | hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 484040de0fb66..4b245ce5c1696 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -613,14 +613,16 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { } fn visit_item(&mut self, i: &'tcx Item<'tcx>) { - // Inherent impls and foreign modules serve only as containers for other items, - // they don't have their own stability. They still can be annotated as unstable - // and propagate this unstability to children, but this annotation is completely - // optional. They inherit stability from their parents when unannotated. + // Inherent impls, foreign modules, and non exported macros serve only as + // containers for other items, they don't have their own stability. They still can + // be annotated as unstable and propagate this unstability to children, but this + // annotation is completely optional. They inherit stability from their parents + // when unannotated. if !matches!( i.kind, hir::ItemKind::Impl(hir::Impl { of_trait: None, .. }) | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Macro { is_exported: false, .. } ) { self.check_missing_stability(i.def_id, i.span); } @@ -663,11 +665,6 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { self.check_missing_stability(i.def_id, i.span); intravisit::walk_foreign_item(self, i); } - - fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) { - self.check_missing_stability(md.def_id, md.span); - } - // Note that we don't need to `check_missing_stability` for default generic parameters, // as we assume that any default generic parameters without attributes are automatically // stable (assuming they have not inherited instability from their parent). diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 1a0510d23cf13..3f40cab0f3e89 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -642,8 +642,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } // Foreign modules inherit level from parents. hir::ItemKind::ForeignMod { .. } => self.prev_level, + // Non-exported macros can't be visible by definition; + hir::ItemKind::Macro { is_exported: false, .. } => None, // Other `pub` items inherit levels from parents. - hir::ItemKind::Const(..) + hir::ItemKind::Macro { is_exported: true, .. } + | hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::ExternCrate(..) | hir::ItemKind::GlobalAsm(..) @@ -711,6 +714,48 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } + hir::ItemKind::Macro { macro_def: ref md, .. } => { + // Non-opaque macros cannot make other items more accessible than they already are. + let attrs = self.tcx.hir().attrs(md.hir_id()); + if attr::find_transparency(&self.tcx.sess, &attrs, md.ast.macro_rules).0 + != Transparency::Opaque + { + // `#[macro_export]`-ed `macro_rules!` are `Public` since they + // ignore their containing path to always appear at the crate root. + if md.ast.macro_rules { + self.update(item.def_id, Some(AccessLevel::Public)); + } + return; + } + + let macro_module_def_id = + ty::DefIdTree::parent(self.tcx, md.def_id.to_def_id()).unwrap().expect_local(); + if self.tcx.hir().opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) { + // The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252). + return; + } + + let level = if md.vis.node.is_pub() { self.get(macro_module_def_id) } else { None }; + let new_level = self.update(md.def_id, level); + if new_level.is_none() { + return; + } + + // Since we are starting from an externally visible module, + // all the parents in the loop below are also guaranteed to be modules. + let mut module_def_id = macro_module_def_id; + loop { + let changed_reachability = + self.update_macro_reachable(module_def_id, macro_module_def_id); + if changed_reachability || module_def_id == CRATE_DEF_ID { + break; + } + module_def_id = ty::DefIdTree::parent(self.tcx, module_def_id.to_def_id()) + .unwrap() + .expect_local(); + } + } + hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Use(..) | hir::ItemKind::Static(..) @@ -726,7 +771,8 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { // Mark all items in interfaces of reachable items as reachable. match item.kind { // The interface is empty. - hir::ItemKind::ExternCrate(..) => {} + hir::ItemKind::Macro { .. } | hir::ItemKind::ExternCrate(..) => {} + // All nested items are checked by `visit_item`. hir::ItemKind::Mod(..) => {} // Re-exports are handled in `visit_mod`. However, in order to avoid looping over @@ -879,47 +925,6 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { intravisit::walk_mod(self, m, id); } - - fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) { - // Non-opaque macros cannot make other items more accessible than they already are. - let attrs = self.tcx.hir().attrs(md.hir_id()); - if attr::find_transparency(&self.tcx.sess, &attrs, md.ast.macro_rules).0 - != Transparency::Opaque - { - // `#[macro_export]`-ed `macro_rules!` are `Public` since they - // ignore their containing path to always appear at the crate root. - if md.ast.macro_rules { - self.update(md.def_id, Some(AccessLevel::Public)); - } - return; - } - - let macro_module_def_id = - ty::DefIdTree::parent(self.tcx, md.def_id.to_def_id()).unwrap().expect_local(); - if self.tcx.hir().opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) { - // The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252). - return; - } - - let level = if md.vis.node.is_pub() { self.get(macro_module_def_id) } else { None }; - let new_level = self.update(md.def_id, level); - if new_level.is_none() { - return; - } - - // Since we are starting from an externally visible module, - // all the parents in the loop below are also guaranteed to be modules. - let mut module_def_id = macro_module_def_id; - loop { - let changed_reachability = - self.update_macro_reachable(module_def_id, macro_module_def_id); - if changed_reachability || module_def_id == CRATE_DEF_ID { - break; - } - module_def_id = - ty::DefIdTree::parent(self.tcx, module_def_id.to_def_id()).unwrap().expect_local(); - } - } } impl ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { @@ -1976,7 +1981,7 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> { // Checked in resolve. hir::ItemKind::Use(..) => {} // No subitems. - hir::ItemKind::GlobalAsm(..) => {} + hir::ItemKind::GlobalAsm(..) | hir::ItemKind::Macro { .. } => {} // Subitems of these items have inherited publicity. hir::ItemKind::Const(..) | hir::ItemKind::Static(..) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index e18dae0b8eebb..be3e7ea7d6fec 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -742,6 +742,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Use(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Macro { .. } | hir::ItemKind::GlobalAsm(..) => { // These sorts of items have no lifetime parameters at all. intravisit::walk_item(self, item); diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs index c3bc1c191ff09..bfcf1fde6b862 100644 --- a/compiler/rustc_save_analysis/src/sig.rs +++ b/compiler/rustc_save_analysis/src/sig.rs @@ -430,6 +430,14 @@ impl<'hir> Sig for hir::Item<'hir> { Ok(Signature { text, defs, refs: vec![] }) } + hir::ItemKind::Macro { .. } => { + let mut text = "macro".to_owned(); + let name = self.ident.to_string(); + text.push_str(&name); + text.push_str(&"! {}"); + + Ok(text_sig(text)) + } hir::ItemKind::TyAlias(ref ty, ref generics) => { let text = "type ".to_owned(); let mut sig = diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index eb94fde21099b..11a251bbc70ed 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -750,6 +750,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) | hir::ItemKind::Mod(_) + | hir::ItemKind::Macro { .. } | hir::ItemKind::GlobalAsm(_) => {} hir::ItemKind::ForeignMod { items, .. } => { for item in items { diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index e63c3346e02b1..861f56cbcf7ca 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -404,6 +404,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { | ItemKind::TraitAlias(..) | ItemKind::Mod(..) | ItemKind::ForeignMod { .. } + | ItemKind::Macro { .. } | ItemKind::GlobalAsm(..) | ItemKind::ExternCrate(..) | ItemKind::Use(..) => { From d493c1b2cfe958963a4e25cc5f1a800640265b99 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Thu, 5 Aug 2021 16:56:45 -0700 Subject: [PATCH 02/18] Lift `#[macro_export]` macros to top level in HIR --- compiler/rustc_ast_lowering/src/item.rs | 121 +++++++++++--------- compiler/rustc_ast_lowering/src/lib.rs | 57 ++++++++- compiler/rustc_resolve/src/def_collector.rs | 65 +++++++---- 3 files changed, 162 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 02a62ebdb2d55..0bbfa903c8f62 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::source_map::{respan, DesugaringKind}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; @@ -26,44 +26,44 @@ pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { } impl ItemLowerer<'_, '_, '_> { - fn with_trait_impl_ref(&mut self, impl_ref: &Option, f: impl FnOnce(&mut Self)) { + fn with_trait_impl_ref( + &mut self, + impl_ref: &Option, + f: impl FnOnce(&mut Self) -> T, + ) -> T { let old = self.lctx.is_in_trait_impl; self.lctx.is_in_trait_impl = impl_ref.is_some(); - f(self); + let ret = f(self); self.lctx.is_in_trait_impl = old; + ret } } impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { fn visit_item(&mut self, item: &'a Item) { - let mut item_hir_id = None; - self.lctx.with_hir_id_owner(item.id, |lctx| { - lctx.without_in_scope_lifetime_defs(|lctx| { - if let Some(hir_item) = lctx.lower_item(item) { - let id = lctx.insert_item(hir_item); - item_hir_id = Some(id); - } - }) + let hir_item = self.lctx.with_hir_id_owner(item.id, |lctx| { + lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item)) }); - - if let Some(hir_id) = item_hir_id { - self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { - let this = &mut ItemLowerer { lctx: this }; - match item.kind { - ItemKind::Mod(..) => { - let def_id = this.lctx.lower_node_id(item.id).expect_owner(); - let old_current_module = - mem::replace(&mut this.lctx.current_module, def_id); - visit::walk_item(this, item); - this.lctx.current_module = old_current_module; - } - ItemKind::Impl(box ImplKind { ref of_trait, .. }) => { - this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); - } - _ => visit::walk_item(this, item), + let force_top_level = self.lctx.check_force_top_level(item); + let hir_id = self.lctx.insert_item(hir_item, force_top_level); + + let was_at_top_level = mem::replace(&mut self.lctx.is_at_top_level, false); + self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { + let this = &mut ItemLowerer { lctx: this }; + match item.kind { + ItemKind::Mod(..) => { + let def_id = this.lctx.lower_node_id(item.id).expect_owner(); + let old_current_module = mem::replace(&mut this.lctx.current_module, def_id); + visit::walk_item(this, item); + this.lctx.current_module = old_current_module; } - }); - } + ItemKind::Impl(box ImplKind { ref of_trait, .. }) => { + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); + } + _ => visit::walk_item(this, item), + } + }); + self.lctx.is_at_top_level = was_at_top_level; } fn visit_fn(&mut self, fk: FnKind<'a>, sp: Span, _: NodeId) { @@ -113,7 +113,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn with_parent_item_lifetime_defs( &mut self, parent_hir_id: hir::ItemId, - f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T, + f: impl FnOnce(&mut Self) -> T, ) -> T { let old_len = self.in_scope_lifetimes.len(); @@ -137,10 +137,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Clears (and restores) the `in_scope_lifetimes` field. Used when // visiting nested items, which never inherit in-scope lifetimes // from their surrounding environment. - fn without_in_scope_lifetime_defs( - &mut self, - f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T, - ) -> T { + fn without_in_scope_lifetime_defs(&mut self, f: impl FnOnce(&mut Self) -> T) -> T { let old_in_scope_lifetimes = mem::replace(&mut self.in_scope_lifetimes, vec![]); // this vector is only used when walking over impl headers, @@ -157,10 +154,23 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn lower_mod(&mut self, items: &[P], inner: Span) -> hir::Mod<'hir> { - hir::Mod { - inner, - item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_id(x))), + let mut items: Vec<_> = items + .iter() + .filter_map(|x| { + if self.check_force_top_level(&x) { None } else { Some(self.lower_item_id(&x)) } + }) + .flatten() + .collect(); + + if self.current_hir_id_owner.0 == CRATE_DEF_ID { + let top_level_items = self.top_level_items.clone(); + for item in top_level_items { + let id = self.lower_item_id(&item)[0]; + items.push(id); + } } + + hir::Mod { inner, item_ids: self.arena.alloc_from_iter(items.into_iter()) } } pub(super) fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { @@ -208,13 +218,15 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub fn lower_item(&mut self, i: &Item) -> Option> { + pub fn lower_item(&mut self, i: &Item) -> hir::Item<'hir> { + let was_at_top_level = mem::replace(&mut self.is_at_top_level, false); let mut ident = i.ident; let mut vis = self.lower_visibility(&i.vis, None); let hir_id = self.lower_node_id(i.id); let attrs = self.lower_attrs(hir_id, &i.attrs); let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind); - Some(hir::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span }) + self.is_at_top_level = was_at_top_level; + hir::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span } } fn lower_item_kind( @@ -285,7 +297,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::Mod(_, ref mod_kind) => match mod_kind { ModKind::Loaded(items, _, inner_span) => { - hir::ItemKind::Mod(self.lower_mod(items, *inner_span)) + let module = self.lower_mod(items, *inner_span); + hir::ItemKind::Mod(module) } ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), }, @@ -537,13 +550,10 @@ impl<'hir> LoweringContext<'_, 'hir> { this.attrs.insert(new_id, attrs); } - this.insert_item(hir::Item { - def_id: new_id.expect_owner(), - ident, - kind, - vis, - span, - }); + this.insert_item( + hir::Item { def_id: new_id.expect_owner(), ident, kind, vis, span }, + false, + ); }); } @@ -611,13 +621,16 @@ impl<'hir> LoweringContext<'_, 'hir> { this.attrs.insert(new_hir_id, attrs); } - this.insert_item(hir::Item { - def_id: new_hir_id.expect_owner(), - ident, - kind, - vis, - span: use_tree.span, - }); + this.insert_item( + hir::Item { + def_id: new_hir_id.expect_owner(), + ident, + kind, + vis, + span: use_tree.span, + }, + false, + ); }); } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3fe698c3946ec..5a42b5bb2097a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -36,6 +36,7 @@ #![recursion_limit = "256"] use rustc_ast::node_id::NodeMap; +use rustc_ast::ptr::P; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; @@ -120,8 +121,11 @@ struct LoweringContext<'a, 'hir: 'a> { /// outside of an `async fn`. current_item: Option, + top_level_items: Vec, + catch_scopes: Vec, loop_scopes: Vec, + is_at_top_level: bool, is_in_loop_condition: bool, is_in_trait_impl: bool, is_in_dyn_type: bool, @@ -331,6 +335,7 @@ pub fn lower_crate<'a, 'hir>( attrs: BTreeMap::default(), catch_scopes: Vec::new(), loop_scopes: Vec::new(), + is_at_top_level: true, is_in_loop_condition: false, is_in_trait_impl: false, is_in_dyn_type: false, @@ -343,6 +348,7 @@ pub fn lower_crate<'a, 'hir>( generator_kind: None, task_context: None, current_item: None, + top_level_items: Vec::new(), lifetimes_to_define: Vec::new(), is_collecting_in_band_lifetimes: false, in_scope_lifetimes: Vec::new(), @@ -467,13 +473,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .count(); self.lctx.type_def_lifetime_params.insert(def_id.to_def_id(), count); } + ItemKind::MacroDef(..) => { + if self.lctx.check_force_top_level(item) { + self.lctx.top_level_items.push(item.clone()); + } + } ItemKind::Use(ref use_tree) => { self.allocate_use_tree_hir_id_counters(use_tree); } _ => {} } + let was_at_top_level = mem::replace(&mut self.lctx.is_at_top_level, false); + visit::walk_item(self, item); + + self.lctx.is_at_top_level = was_at_top_level; } fn visit_assoc_item(&mut self, item: &'tcx AssocItem, ctxt: AssocCtxt) { @@ -510,7 +525,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c); visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c); - let module = self.arena.alloc(self.lower_mod(&c.items, c.span)); + let mut items: Vec<_> = self.top_level_items.drain(..).map(|item| P(item)).collect(); + items.extend(c.items.clone()); + + let module = self.arena.alloc(self.lower_mod(items.as_slice(), c.span)); self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs); self.owners.ensure_contains_elem(CRATE_DEF_ID, || None); self.owners[CRATE_DEF_ID] = Some(hir::OwnerNode::Crate(module)); @@ -561,12 +579,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(krate) } - fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId { + fn insert_item(&mut self, item: hir::Item<'hir>, force_top_level: bool) -> hir::ItemId { let id = item.item_id(); let item = self.arena.alloc(item); + let module = if force_top_level { CRATE_DEF_ID } else { self.current_module }; self.owners.ensure_contains_elem(id.def_id, || None); self.owners[id.def_id] = Some(hir::OwnerNode::Item(item)); - self.modules.entry(self.current_module).or_default().items.insert(id); + self.modules.entry(module).or_default().items.insert(id); id } @@ -597,6 +616,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id } + /// This checks if an item is a `#[macro_use]` macro, and thus always + /// defined at the top level. As a special case, if the macro is already + /// at the top level, it remains at its current level. + fn check_force_top_level(&self, item: &Item) -> bool { + if self.is_at_top_level { + false + } else if let ItemKind::MacroDef(MacroDef { macro_rules, .. }) = item.kind { + macro_rules && self.sess.contains_name(&item.attrs, sym::macro_export) + } else { + false + } + } + fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId { // Set up the counter if needed. self.item_local_id_counters.entry(owner).or_insert(0); @@ -1593,7 +1625,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Insert the item into the global item list. This usually happens // automatically for all AST items. But this opaque type item // does not actually exist in the AST. - self.insert_item(opaque_ty_item); + self.insert_item(opaque_ty_item, false); } fn lifetimes_from_impl_trait_bounds( @@ -2382,7 +2414,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { [stmts @ .., Stmt { kind: StmtKind::Expr(e), .. }] => (stmts, Some(&*e)), stmts => (stmts, None), }; - let stmts = self.arena.alloc_from_iter(stmts.iter().flat_map(|stmt| self.lower_stmt(stmt))); + let stmts: Vec<_> = stmts + .iter() + .filter_map(|stmt| { + if let StmtKind::Item(ref item) = stmt.kind { + if self.check_force_top_level(item) { + None + } else { + Some(self.lower_stmt(stmt)) + } + } else { + Some(self.lower_stmt(stmt)) + } + }) + .flatten() + .collect(); + let stmts = self.arena.alloc_from_iter(stmts.into_iter()); let expr = expr.map(|e| self.lower_expr(e)); let rules = self.lower_block_check_mode(&b.rules); let hir_id = self.lower_node_id(b.id); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 6f4f1bdaea1b7..075555dc708c1 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -4,7 +4,7 @@ use rustc_ast::walk_list; use rustc_ast::*; use rustc_ast_lowering::ResolverAstLowering; use rustc_expand::expand::AstFragment; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::*; use rustc_span::hygiene::LocalExpnId; use rustc_span::symbol::{kw, sym}; @@ -29,9 +29,18 @@ struct DefCollector<'a, 'b> { } impl<'a, 'b> DefCollector<'a, 'b> { - fn create_def(&mut self, node_id: NodeId, data: DefPathData, span: Span) -> LocalDefId { - let parent_def = self.parent_def; - debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); + fn create_def( + &mut self, + node_id: NodeId, + data: DefPathData, + span: Span, + force_top_level: bool, + ) -> LocalDefId { + let parent_def = if force_top_level { CRATE_DEF_ID } else { self.parent_def }; + debug!( + "create_def(node_id={:?}, data={:?}, parent_def={:?}, force_top_level={:?}", + node_id, data, parent_def, force_top_level + ); self.resolver.create_def(parent_def, node_id, data, self.expansion.to_expn_id(), span) } @@ -65,7 +74,7 @@ impl<'a, 'b> DefCollector<'a, 'b> { self.visit_macro_invoc(field.id); } else { let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); - let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span); + let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span, false); self.with_parent(def, |this| visit::walk_field_def(this, field)); } } @@ -82,6 +91,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { fn visit_item(&mut self, i: &'a Item) { debug!("visit_item: {:?}", i); + let mut force_top_level = false; + // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better let def_data = match &i.kind { @@ -102,7 +113,14 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => { DefPathData::ValueNs(i.ident.name) } - ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name), + ItemKind::MacroDef(ref macro_def) => { + if macro_def.macro_rules + && self.resolver.session.contains_name(&i.attrs, sym::macro_export) + { + force_top_level = true; + } + DefPathData::MacroNs(i.ident.name) + } ItemKind::MacCall(..) => { visit::walk_item(self, i); return self.visit_macro_invoc(i.id); @@ -112,7 +130,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { return visit::walk_item(self, i); } }; - let def = self.create_def(i.id, def_data, i.span); + let def = self.create_def(i.id, def_data, i.span, force_top_level); self.with_parent(def, |this| { this.with_impl_trait(ImplTraitContext::Existential, |this| { @@ -120,7 +138,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { // If this is a unit or tuple-like struct, register the constructor. if let Some(ctor_hir_id) = struct_def.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, i.span); + this.create_def(ctor_hir_id, DefPathData::Ctor, i.span, false); } } _ => {} @@ -134,7 +152,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { if let FnKind::Fn(_, _, sig, _, body) = fn_kind { if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness { let return_impl_trait_id = - self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); + self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span, false); // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. Besides that, @@ -146,7 +164,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { self.with_parent(return_impl_trait_id, |this| { this.visit_fn_ret_ty(&sig.decl.output) }); - let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span); + let closure_def = + self.create_def(closure_id, DefPathData::ClosureExpr, span, false); self.with_parent(closure_def, |this| walk_list!(this, visit_block, body)); return; } @@ -156,11 +175,11 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { } fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) { - self.create_def(id, DefPathData::Misc, use_tree.span); + self.create_def(id, DefPathData::Misc, use_tree.span, false); match use_tree.kind { UseTreeKind::Simple(_, id1, id2) => { - self.create_def(id1, DefPathData::Misc, use_tree.prefix.span); - self.create_def(id2, DefPathData::Misc, use_tree.prefix.span); + self.create_def(id1, DefPathData::Misc, use_tree.prefix.span, false); + self.create_def(id2, DefPathData::Misc, use_tree.prefix.span, false); } UseTreeKind::Glob => (), UseTreeKind::Nested(..) => {} @@ -177,6 +196,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name), foreign_item.span, + false, ); self.with_parent(def, |this| { @@ -188,10 +208,10 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { if v.is_placeholder { return self.visit_macro_invoc(v.id); } - let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span); + let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span, false); self.with_parent(def, |this| { if let Some(ctor_hir_id) = v.data.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, v.span); + this.create_def(ctor_hir_id, DefPathData::Ctor, v.span, false); } visit::walk_variant(this, v) }); @@ -217,7 +237,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { GenericParamKind::Type { .. } => DefPathData::TypeNs(name), GenericParamKind::Const { .. } => DefPathData::ValueNs(name), }; - self.create_def(param.id, def_path_data, param.ident.span); + self.create_def(param.id, def_path_data, param.ident.span, false); // impl-Trait can happen inside generic parameters, like // ``` @@ -237,7 +257,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { AssocItemKind::MacCall(..) => return self.visit_macro_invoc(i.id), }; - let def = self.create_def(i.id, def_data, i.span); + let def = self.create_def(i.id, def_data, i.span, false); self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); } @@ -249,7 +269,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { } fn visit_anon_const(&mut self, constant: &'a AnonConst) { - let def = self.create_def(constant.id, DefPathData::AnonConst, constant.value.span); + let def = self.create_def(constant.id, DefPathData::AnonConst, constant.value.span, false); self.with_parent(def, |this| visit::walk_anon_const(this, constant)); } @@ -259,16 +279,17 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ExprKind::Closure(_, asyncness, ..) => { // Async closures desugar to closures inside of closures, so // we must create two defs. - let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span); + let closure_def = + self.create_def(expr.id, DefPathData::ClosureExpr, expr.span, false); match asyncness { Async::Yes { closure_id, .. } => { - self.create_def(closure_id, DefPathData::ClosureExpr, expr.span) + self.create_def(closure_id, DefPathData::ClosureExpr, expr.span, false) } Async::No => closure_def, } } ExprKind::Async(_, async_id, _) => { - self.create_def(async_id, DefPathData::ClosureExpr, expr.span) + self.create_def(async_id, DefPathData::ClosureExpr, expr.span, false) } _ => self.parent_def, }; @@ -289,7 +310,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ty.span, ), ImplTraitContext::Existential => { - self.create_def(node_id, DefPathData::ImplTrait, ty.span) + self.create_def(node_id, DefPathData::ImplTrait, ty.span, false) } }; self.with_parent(parent_def, |this| visit::walk_ty(this, ty)) From f08d2b5dec1af4a88884b777f2ab934164216620 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Fri, 30 Jul 2021 23:10:32 -0700 Subject: [PATCH 03/18] Remove obsolete `MacroDef` variant of `OwnerNode` --- compiler/rustc_hir/src/hir.rs | 32 ++++-------------------- compiler/rustc_hir_pretty/src/lib.rs | 1 - compiler/rustc_middle/src/hir/map/mod.rs | 13 ---------- compiler/rustc_passes/src/reachable.rs | 3 +-- 4 files changed, 6 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index d323b439fbfdf..53c98a0db7f39 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -740,7 +740,7 @@ impl Crate<'_> { OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), OwnerNode::ImplItem(item) => visitor.visit_impl_item(item), OwnerNode::TraitItem(item) => visitor.visit_trait_item(item), - OwnerNode::MacroDef(_) | OwnerNode::Crate(_) => {} + OwnerNode::Crate(_) => {} } } } @@ -755,7 +755,7 @@ impl Crate<'_> { Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item), Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item), Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item), - Some(OwnerNode::MacroDef(_)) | Some(OwnerNode::Crate(_)) | None => {} + Some(OwnerNode::Crate(_)) | None => {} }) } @@ -2984,7 +2984,6 @@ pub enum OwnerNode<'hir> { ForeignItem(&'hir ForeignItem<'hir>), TraitItem(&'hir TraitItem<'hir>), ImplItem(&'hir ImplItem<'hir>), - MacroDef(&'hir MacroDef<'hir>), Crate(&'hir Mod<'hir>), } @@ -2994,8 +2993,7 @@ impl<'hir> OwnerNode<'hir> { OwnerNode::Item(Item { ident, .. }) | OwnerNode::ForeignItem(ForeignItem { ident, .. }) | OwnerNode::ImplItem(ImplItem { ident, .. }) - | OwnerNode::TraitItem(TraitItem { ident, .. }) - | OwnerNode::MacroDef(MacroDef { ident, .. }) => Some(*ident), + | OwnerNode::TraitItem(TraitItem { ident, .. }) => Some(*ident), OwnerNode::Crate(..) => None, } } @@ -3006,7 +3004,6 @@ impl<'hir> OwnerNode<'hir> { | OwnerNode::ForeignItem(ForeignItem { span, .. }) | OwnerNode::ImplItem(ImplItem { span, .. }) | OwnerNode::TraitItem(TraitItem { span, .. }) - | OwnerNode::MacroDef(MacroDef { span, .. }) | OwnerNode::Crate(Mod { inner: span, .. }) => *span, } } @@ -3050,8 +3047,7 @@ impl<'hir> OwnerNode<'hir> { OwnerNode::Item(Item { def_id, .. }) | OwnerNode::TraitItem(TraitItem { def_id, .. }) | OwnerNode::ImplItem(ImplItem { def_id, .. }) - | OwnerNode::ForeignItem(ForeignItem { def_id, .. }) - | OwnerNode::MacroDef(MacroDef { def_id, .. }) => *def_id, + | OwnerNode::ForeignItem(ForeignItem { def_id, .. }) => *def_id, OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner, } } @@ -3083,13 +3079,6 @@ impl<'hir> OwnerNode<'hir> { _ => panic!(), } } - - pub fn expect_macro_def(self) -> &'hir MacroDef<'hir> { - match self { - OwnerNode::MacroDef(n) => n, - _ => panic!(), - } - } } impl<'hir> Into> for &'hir Item<'hir> { @@ -3116,12 +3105,6 @@ impl<'hir> Into> for &'hir TraitItem<'hir> { } } -impl<'hir> Into> for &'hir MacroDef<'hir> { - fn into(self) -> OwnerNode<'hir> { - OwnerNode::MacroDef(self) - } -} - impl<'hir> Into> for OwnerNode<'hir> { fn into(self) -> Node<'hir> { match self { @@ -3129,7 +3112,6 @@ impl<'hir> Into> for OwnerNode<'hir> { OwnerNode::ForeignItem(n) => Node::ForeignItem(n), OwnerNode::ImplItem(n) => Node::ImplItem(n), OwnerNode::TraitItem(n) => Node::TraitItem(n), - OwnerNode::MacroDef(n) => Node::MacroDef(n), OwnerNode::Crate(n) => Node::Crate(n), } } @@ -3155,7 +3137,6 @@ pub enum Node<'hir> { Arm(&'hir Arm<'hir>), Block(&'hir Block<'hir>), Local(&'hir Local<'hir>), - MacroDef(&'hir MacroDef<'hir>), /// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants /// with synthesized constructors. @@ -3178,7 +3159,6 @@ impl<'hir> Node<'hir> { | Node::ForeignItem(ForeignItem { ident, .. }) | Node::Field(FieldDef { ident, .. }) | Node::Variant(Variant { ident, .. }) - | Node::MacroDef(MacroDef { ident, .. }) | Node::Item(Item { ident, .. }) => Some(*ident), _ => None, } @@ -3222,8 +3202,7 @@ impl<'hir> Node<'hir> { Node::Item(Item { def_id, .. }) | Node::TraitItem(TraitItem { def_id, .. }) | Node::ImplItem(ImplItem { def_id, .. }) - | Node::ForeignItem(ForeignItem { def_id, .. }) - | Node::MacroDef(MacroDef { def_id, .. }) => Some(HirId::make_owner(*def_id)), + | Node::ForeignItem(ForeignItem { def_id, .. }) => Some(HirId::make_owner(*def_id)), Node::Field(FieldDef { hir_id, .. }) | Node::AnonConst(AnonConst { hir_id, .. }) | Node::Expr(Expr { hir_id, .. }) @@ -3273,7 +3252,6 @@ impl<'hir> Node<'hir> { Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)), Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)), Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)), - Node::MacroDef(i) => Some(OwnerNode::MacroDef(i)), Node::Crate(i) => Some(OwnerNode::Crate(i)), _ => None, } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 9870599eb4a48..606f2efa66045 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -121,7 +121,6 @@ impl<'a> State<'a> { // printing. Node::Ctor(..) => panic!("cannot print isolated Ctor"), Node::Local(a) => self.print_local_decl(&a), - Node::MacroDef(_) => panic!("cannot print MacroDef"), Node::Crate(..) => panic!("cannot print Crate"), } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 28423753d7556..360b3094df221 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -266,7 +266,6 @@ impl<'hir> Map<'hir> { ExprKind::Closure(.., Some(_)) => DefKind::Generator, _ => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)), }, - Node::MacroDef(_) => DefKind::Macro(MacroKind::Bang), Node::GenericParam(param) => match param.kind { GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, GenericParamKind::Type { .. } => DefKind::TyParam, @@ -636,8 +635,6 @@ impl<'hir> Map<'hir> { /// in a module, trait, or impl. pub fn get_parent_item(&self, hir_id: HirId) -> HirId { if let Some((hir_id, _node)) = self.parent_owner_iter(hir_id).next() { - // A MacroDef does not have children. - debug_assert!(!matches!(_node, OwnerNode::MacroDef(_))); hir_id } else { CRATE_HIR_ID @@ -765,13 +762,6 @@ impl<'hir> Map<'hir> { } } - pub fn expect_macro_def(&self, id: HirId) -> &'hir MacroDef<'hir> { - match self.tcx.hir_owner(id.expect_owner()) { - Some(Owner { node: OwnerNode::MacroDef(macro_def) }) => macro_def, - _ => bug!("expected macro def, found {}", self.node_to_string(id)), - } - } - pub fn expect_expr(&self, id: HirId) -> &'hir Expr<'hir> { match self.find(id) { Some(Node::Expr(expr)) => expr, @@ -791,7 +781,6 @@ impl<'hir> Map<'hir> { Node::GenericParam(param) => param.name.ident().name, Node::Binding(&Pat { kind: PatKind::Binding(_, _, l, _), .. }) => l.name, Node::Ctor(..) => self.name(self.get_parent_item(id)), - Node::MacroDef(md) => md.ident.name, _ => return None, }) } @@ -858,7 +847,6 @@ impl<'hir> Map<'hir> { Node::Infer(i) => i.span, Node::Visibility(v) => bug!("unexpected Visibility {:?}", v), Node::Local(local) => local.span, - Node::MacroDef(macro_def) => macro_def.span, Node::Crate(item) => item.inner, }; Some(span) @@ -1109,7 +1097,6 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String { Some(Node::Lifetime(_)) => node_str("lifetime"), Some(Node::GenericParam(ref param)) => format!("generic_param {:?}{}", param, id_str), Some(Node::Visibility(ref vis)) => format!("visibility {:?}{}", vis, id_str), - Some(Node::MacroDef(_)) => format!("macro {}{}", path_str(), id_str), Some(Node::Crate(..)) => String::from("root_crate"), None => format!("unknown node{}", id_str), } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index ebdf887455688..29978a49ab874 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -309,8 +309,7 @@ impl<'tcx> ReachableContext<'tcx> { | Node::Ctor(..) | Node::Field(_) | Node::Ty(_) - | Node::Crate(_) - | Node::MacroDef(_) => {} + | Node::Crate(_) => {} _ => { bug!( "found unexpected node kind in worklist: {} ({:?})", From 5c5fdef34cb35f624cb448faf63dd8d07e29c6b2 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Thu, 5 Aug 2021 16:58:46 -0700 Subject: [PATCH 04/18] Teach rustdoc that macros are now HIR items --- src/librustdoc/clean/mod.rs | 23 +++---------- src/librustdoc/doctree.rs | 12 ++----- src/librustdoc/visit_ast.rs | 64 +++++++------------------------------ 3 files changed, 18 insertions(+), 81 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3d65fcedaf4e5..8fb9065fafc66 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -91,7 +91,6 @@ impl Clean for doctree::Module<'_> { items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx))); items.extend(self.items.iter().map(|x| x.clean(cx)).flatten()); - items.extend(self.macros.iter().map(|x| x.clean(cx))); // determine if we should display the inner contents or // the outer `mod` item for the source code. @@ -1860,6 +1859,10 @@ impl Clean> for (&hir::Item<'_>, Option) { 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, .. } => MacroItem(Macro { + source: display_macro_source(cx, name, ¯o_def.ast, def_id, &item.vis), + imported_from: None, + }), ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => { let items = item_ids .iter() @@ -2137,24 +2140,6 @@ impl Clean for (&hir::ForeignItem<'_>, Option) { } } -impl Clean for (&hir::MacroDef<'_>, Option) { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { - let (item, renamed) = self; - let name = renamed.unwrap_or(item.ident.name); - let def_id = item.def_id.to_def_id(); - - Item::from_hir_id_and_parts( - item.hir_id(), - Some(name), - MacroItem(Macro { - source: display_macro_source(cx, name, &item.ast, def_id, &item.vis), - imported_from: None, - }), - cx, - ) - } -} - impl Clean for hir::TypeBinding<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> TypeBinding { TypeBinding { name: self.ident.name, kind: self.kind.clean(cx) } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index eadac89f79ef2..8f1e8f277c5fe 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -5,6 +5,7 @@ use rustc_span::{self, Span, Symbol}; use rustc_hir as hir; +#[derive(Debug)] crate struct Module<'hir> { crate name: Symbol, crate where_inner: Span, @@ -13,20 +14,11 @@ crate struct Module<'hir> { // (item, renamed) crate items: Vec<(&'hir hir::Item<'hir>, Option)>, crate foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option)>, - crate macros: Vec<(&'hir hir::MacroDef<'hir>, Option)>, } impl Module<'hir> { crate fn new(name: Symbol, id: hir::HirId, where_inner: Span) -> Module<'hir> { - Module { - name, - id, - where_inner, - mods: Vec::new(), - items: Vec::new(), - foreigns: Vec::new(), - macros: Vec::new(), - } + Module { name, id, where_inner, mods: Vec::new(), items: Vec::new(), foreigns: Vec::new() } } crate fn where_outer(&self, tcx: TyCtxt<'_>) -> Span { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e28910355357b..db8386862819b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -73,56 +73,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> { let span = krate.module().inner; - let mut top_level_module = self.visit_mod_contents( + let top_level_module = self.visit_mod_contents( &Spanned { span, node: hir::VisibilityKind::Public }, hir::CRATE_HIR_ID, &krate.module(), self.cx.tcx.crate_name(LOCAL_CRATE), ); - // Attach the crate's exported macros to the top-level module. - // In the case of macros 2.0 (`pub macro`), and for built-in `derive`s or attributes as - // well (_e.g._, `Copy`), these are wrongly bundled in there too, so we need to fix that by - // moving them back to their correct locations. - 'exported_macros: for def in krate.exported_macros() { - // The `def` of a macro in `exported_macros` should correspond to either: - // - a `#[macro_export] macro_rules!` macro, - // - a built-in `derive` (or attribute) macro such as the ones in `::core`, - // - a `pub macro`. - // Only the last two need to be fixed, thus: - if def.ast.macro_rules { - top_level_module.macros.push((def, None)); - continue 'exported_macros; - } - let tcx = self.cx.tcx; - // Note: this is not the same as `.parent_module()`. Indeed, the latter looks - // for the closest module _ancestor_, which is not necessarily a direct parent - // (since a direct parent isn't necessarily a module, c.f. #77828). - let macro_parent_def_id = { - use rustc_middle::ty::DefIdTree; - tcx.parent(def.def_id.to_def_id()).unwrap() - }; - let macro_parent_path = tcx.def_path(macro_parent_def_id); - // HACK: rustdoc has no way to lookup `doctree::Module`s by their HirId. Instead, - // lookup the module by its name, by looking at each path segment one at a time. - let mut cur_mod = &mut top_level_module; - for path_segment in macro_parent_path.data { - // Path segments may refer to a module (in which case they belong to the type - // namespace), which is _necessary_ for the macro to be accessible outside it - // (no "associated macros" as of yet). Else we bail with an outer `continue`. - let path_segment_ty_ns = match path_segment.data { - rustc_hir::definitions::DefPathData::TypeNs(symbol) => symbol, - _ => continue 'exported_macros, - }; - // Descend into the child module that matches this path segment (if any). - match cur_mod.mods.iter_mut().find(|child| child.name == path_segment_ty_ns) { - Some(child_mod) => cur_mod = &mut *child_mod, - None => continue 'exported_macros, - } - } - let cur_mod_def_id = tcx.hir().local_def_id(cur_mod.id).to_def_id(); - assert_eq!(cur_mod_def_id, macro_parent_def_id); - cur_mod.macros.push((def, None)); - } + self.cx.cache.exact_paths = self.exact_paths; top_level_module } @@ -238,10 +195,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.inlining = prev; true } - Node::MacroDef(def) if !glob => { - om.macros.push((def, renamed)); - true - } _ => false, }; self.view_item_stack.remove(&res_hir_id); @@ -257,7 +210,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { debug!("visiting item {:?}", item); let name = renamed.unwrap_or(item.ident.name); - if item.vis.node.is_pub() { + let is_pub = if let hir::ItemKind::Macro { is_exported: true, .. } = item.kind { + true + } else { + item.vis.node.is_pub() + }; + + if is_pub { self.store_path(item.def_id.to_def_id()); } @@ -269,7 +228,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } // If we're inlining, skip private items. - _ if self.inlining && !item.vis.node.is_pub() => {} + _ if self.inlining && !is_pub => {} hir::ItemKind::GlobalAsm(..) => {} hir::ItemKind::Use(_, hir::UseKind::ListStem) => {} hir::ItemKind::Use(ref path, kind) => { @@ -285,7 +244,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // If there was a private module in the current path then don't bother inlining // anything as it will probably be stripped anyway. - if item.vis.node.is_pub() && self.inside_public_path { + if is_pub && self.inside_public_path { let please_inline = attrs.iter().any(|item| match item.meta_item_list() { Some(ref list) if item.has_name(sym::doc) => { list.iter().any(|i| i.has_name(sym::inline)) @@ -311,6 +270,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om.mods.push(self.visit_mod_contents(&item.vis, item.hir_id(), m, name)); } hir::ItemKind::Fn(..) + | hir::ItemKind::Macro { .. } | hir::ItemKind::ExternCrate(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) From b9a85b3dd40f731432e95dcba1080906a30fe3b2 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Thu, 5 Aug 2021 22:09:25 -0700 Subject: [PATCH 05/18] Update tests --- src/test/rustdoc/macro-document-private.rs | 19 +++++++++++++++++++ src/test/rustdoc/macro-indirect-use.rs | 16 ++++++++++++++++ src/test/ui/lint/lint-level-macro-def.rs | 17 +++++++++++++++++ src/test/ui/lint/missing-doc-private-macro.rs | 4 ++-- .../ui/lint/missing-doc-private-macro.stderr | 4 ++-- src/test/ui/macros/macro-stability-rpass.rs | 3 ++- 6 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 src/test/rustdoc/macro-document-private.rs create mode 100644 src/test/rustdoc/macro-indirect-use.rs create mode 100644 src/test/ui/lint/lint-level-macro-def.rs diff --git a/src/test/rustdoc/macro-document-private.rs b/src/test/rustdoc/macro-document-private.rs new file mode 100644 index 0000000000000..d2496913ffcf2 --- /dev/null +++ b/src/test/rustdoc/macro-document-private.rs @@ -0,0 +1,19 @@ +// Checks that private macros are documented when `--document-private-items` +// is present. +// +// This is a regression test for issue #73754. +// +// compile-flags: --document-private-items + +#![feature(decl_macro)] + + +// @has macro_document_private/macro.some_macro.html +macro some_macro { + (a: tt) => {} +} + +// @has macro_document_private/macro.another_macro.html +macro_rules! another_macro { + (a: tt) => {} +} diff --git a/src/test/rustdoc/macro-indirect-use.rs b/src/test/rustdoc/macro-indirect-use.rs new file mode 100644 index 0000000000000..b2d9336cffc81 --- /dev/null +++ b/src/test/rustdoc/macro-indirect-use.rs @@ -0,0 +1,16 @@ +// Checks that it is possible to make a macro public through a `pub use` of its +// parent module. +// +// This is a regression test for issue #87257. + +#![feature(decl_macro)] + +mod outer { + pub mod inner { + pub macro some_macro() {} + } +} + +// @has macro_indirect_use/inner/index.html +// @has macro_indirect_use/inner/macro.some_macro.html +pub use outer::inner; diff --git a/src/test/ui/lint/lint-level-macro-def.rs b/src/test/ui/lint/lint-level-macro-def.rs new file mode 100644 index 0000000000000..720f4b453abf5 --- /dev/null +++ b/src/test/ui/lint/lint-level-macro-def.rs @@ -0,0 +1,17 @@ +// Checks that you can set a lint level specficially for a macro definition. +// +// This is a regression test for issue #59306. +// +// check-pass + + +#[deny(missing_docs)] +mod module { + #[allow(missing_docs)] + #[macro_export] + macro_rules! hello { + () => () + } +} + +fn main() {} diff --git a/src/test/ui/lint/missing-doc-private-macro.rs b/src/test/ui/lint/missing-doc-private-macro.rs index 8d1d5c568803b..0d4332ed08b26 100644 --- a/src/test/ui/lint/missing-doc-private-macro.rs +++ b/src/test/ui/lint/missing-doc-private-macro.rs @@ -29,13 +29,13 @@ mod submodule { #[macro_export] macro_rules! exported_to_top_level { - //~^ ERROR missing documentation for macro + //~^ ERROR missing documentation for a macro () => () } } pub macro top_level_pub_macro { - //~^ ERROR missing documentation for macro + //~^ ERROR missing documentation for a macro () => () } diff --git a/src/test/ui/lint/missing-doc-private-macro.stderr b/src/test/ui/lint/missing-doc-private-macro.stderr index a5d39faf40562..979b007d0ecd6 100644 --- a/src/test/ui/lint/missing-doc-private-macro.stderr +++ b/src/test/ui/lint/missing-doc-private-macro.stderr @@ -1,4 +1,4 @@ -error: missing documentation for macro +error: missing documentation for a macro --> $DIR/missing-doc-private-macro.rs:31:5 | LL | macro_rules! exported_to_top_level { @@ -10,7 +10,7 @@ note: the lint level is defined here LL | #![deny(missing_docs)] | ^^^^^^^^^^^^ -error: missing documentation for macro +error: missing documentation for a macro --> $DIR/missing-doc-private-macro.rs:37:1 | LL | pub macro top_level_pub_macro { diff --git a/src/test/ui/macros/macro-stability-rpass.rs b/src/test/ui/macros/macro-stability-rpass.rs index a5f538ba6b36a..2d02b95288df4 100644 --- a/src/test/ui/macros/macro-stability-rpass.rs +++ b/src/test/ui/macros/macro-stability-rpass.rs @@ -1,7 +1,8 @@ // run-pass // aux-build:unstable-macros.rs -#![feature(unstable_macros, local_unstable)] +#![unstable(feature = "one_two_three_testing", issue = "none")] +#![feature(staged_api, unstable_macros, local_unstable)] #[macro_use] extern crate unstable_macros; From 19b208cc3fae4965ceea85de2240731158229ca6 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Fri, 13 Aug 2021 22:13:35 -0700 Subject: [PATCH 06/18] Teach clippy that macros are now HIR items --- src/tools/clippy/clippy_lints/src/missing_doc.rs | 1 + src/tools/clippy/clippy_lints/src/missing_inline.rs | 1 + .../clippy/clippy_lints/src/utils/inspector.rs | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index d358e9fb876a7..acf54073d247c 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -123,6 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Mod(..) + | hir::ItemKind::Macro{ .. } | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 977e6d966e873..3f26ec2e73237 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -119,6 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Mod(..) + | hir::ItemKind::Macro { .. } | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::TraitAlias(..) diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index f7ddee12dcf64..c013bb9d27faf 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -408,6 +408,19 @@ fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) { }, hir::ItemKind::Mod(..) => println!("module"), hir::ItemKind::ForeignMod { abi, .. } => println!("foreign module with abi: {}", abi), + hir::ItemKind::Macro { ref macro_def, .. } => { + if macro_def.ast.macro_rules { + if macro_def.is_exported { + println!("exported macro introduced by `macro_rules!`"); + } else { + println!("nonexported macro introduced by `macro_rules!`"); + } + } else { + // There's no point in distinguishing exported and nonexported `macro` + // macros. That's defined their visibility, which was printed above. + println!("macro introduced by `macro`"); + } + } hir::ItemKind::GlobalAsm(asm) => println!("global asm: {:?}", asm), hir::ItemKind::TyAlias(..) => { println!("type alias for {:?}", cx.tcx.type_of(did)); From e26ce59cece118c5291c131e55b65ce04a2d936a Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Sat, 14 Aug 2021 16:53:19 -0700 Subject: [PATCH 07/18] Fix minor spacing error --- src/tools/clippy/clippy_lints/src/missing_doc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index acf54073d247c..9e8e84657c973 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -123,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Mod(..) - | hir::ItemKind::Macro{ .. } + | hir::ItemKind::Macro { .. } | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Trait(..) From 5f9b921bb9a9e8623ef8c25cb0fda61b8b834f66 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Sat, 14 Aug 2021 16:57:10 -0700 Subject: [PATCH 08/18] Revert "Lift `#[macro_export]` macros to top level in HIR" This reverts commit d493c1b2cfe958963a4e25cc5f1a800640265b99. --- compiler/rustc_ast_lowering/src/item.rs | 121 +++++++++----------- compiler/rustc_ast_lowering/src/lib.rs | 57 +-------- compiler/rustc_resolve/src/def_collector.rs | 65 ++++------- 3 files changed, 81 insertions(+), 162 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 0bbfa903c8f62..02a62ebdb2d55 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::def_id::LocalDefId; use rustc_span::source_map::{respan, DesugaringKind}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; @@ -26,44 +26,44 @@ pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { } impl ItemLowerer<'_, '_, '_> { - fn with_trait_impl_ref( - &mut self, - impl_ref: &Option, - f: impl FnOnce(&mut Self) -> T, - ) -> T { + fn with_trait_impl_ref(&mut self, impl_ref: &Option, f: impl FnOnce(&mut Self)) { let old = self.lctx.is_in_trait_impl; self.lctx.is_in_trait_impl = impl_ref.is_some(); - let ret = f(self); + f(self); self.lctx.is_in_trait_impl = old; - ret } } impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { fn visit_item(&mut self, item: &'a Item) { - let hir_item = self.lctx.with_hir_id_owner(item.id, |lctx| { - lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item)) - }); - let force_top_level = self.lctx.check_force_top_level(item); - let hir_id = self.lctx.insert_item(hir_item, force_top_level); - - let was_at_top_level = mem::replace(&mut self.lctx.is_at_top_level, false); - self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { - let this = &mut ItemLowerer { lctx: this }; - match item.kind { - ItemKind::Mod(..) => { - let def_id = this.lctx.lower_node_id(item.id).expect_owner(); - let old_current_module = mem::replace(&mut this.lctx.current_module, def_id); - visit::walk_item(this, item); - this.lctx.current_module = old_current_module; - } - ItemKind::Impl(box ImplKind { ref of_trait, .. }) => { - this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); + let mut item_hir_id = None; + self.lctx.with_hir_id_owner(item.id, |lctx| { + lctx.without_in_scope_lifetime_defs(|lctx| { + if let Some(hir_item) = lctx.lower_item(item) { + let id = lctx.insert_item(hir_item); + item_hir_id = Some(id); } - _ => visit::walk_item(this, item), - } + }) }); - self.lctx.is_at_top_level = was_at_top_level; + + if let Some(hir_id) = item_hir_id { + self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { + let this = &mut ItemLowerer { lctx: this }; + match item.kind { + ItemKind::Mod(..) => { + let def_id = this.lctx.lower_node_id(item.id).expect_owner(); + let old_current_module = + mem::replace(&mut this.lctx.current_module, def_id); + visit::walk_item(this, item); + this.lctx.current_module = old_current_module; + } + ItemKind::Impl(box ImplKind { ref of_trait, .. }) => { + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); + } + _ => visit::walk_item(this, item), + } + }); + } } fn visit_fn(&mut self, fk: FnKind<'a>, sp: Span, _: NodeId) { @@ -113,7 +113,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn with_parent_item_lifetime_defs( &mut self, parent_hir_id: hir::ItemId, - f: impl FnOnce(&mut Self) -> T, + f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T, ) -> T { let old_len = self.in_scope_lifetimes.len(); @@ -137,7 +137,10 @@ impl<'hir> LoweringContext<'_, 'hir> { // Clears (and restores) the `in_scope_lifetimes` field. Used when // visiting nested items, which never inherit in-scope lifetimes // from their surrounding environment. - fn without_in_scope_lifetime_defs(&mut self, f: impl FnOnce(&mut Self) -> T) -> T { + fn without_in_scope_lifetime_defs( + &mut self, + f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T, + ) -> T { let old_in_scope_lifetimes = mem::replace(&mut self.in_scope_lifetimes, vec![]); // this vector is only used when walking over impl headers, @@ -154,23 +157,10 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn lower_mod(&mut self, items: &[P], inner: Span) -> hir::Mod<'hir> { - let mut items: Vec<_> = items - .iter() - .filter_map(|x| { - if self.check_force_top_level(&x) { None } else { Some(self.lower_item_id(&x)) } - }) - .flatten() - .collect(); - - if self.current_hir_id_owner.0 == CRATE_DEF_ID { - let top_level_items = self.top_level_items.clone(); - for item in top_level_items { - let id = self.lower_item_id(&item)[0]; - items.push(id); - } + hir::Mod { + inner, + item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_id(x))), } - - hir::Mod { inner, item_ids: self.arena.alloc_from_iter(items.into_iter()) } } pub(super) fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { @@ -218,15 +208,13 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub fn lower_item(&mut self, i: &Item) -> hir::Item<'hir> { - let was_at_top_level = mem::replace(&mut self.is_at_top_level, false); + pub fn lower_item(&mut self, i: &Item) -> Option> { let mut ident = i.ident; let mut vis = self.lower_visibility(&i.vis, None); let hir_id = self.lower_node_id(i.id); let attrs = self.lower_attrs(hir_id, &i.attrs); let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind); - self.is_at_top_level = was_at_top_level; - hir::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span } + Some(hir::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span }) } fn lower_item_kind( @@ -297,8 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::Mod(_, ref mod_kind) => match mod_kind { ModKind::Loaded(items, _, inner_span) => { - let module = self.lower_mod(items, *inner_span); - hir::ItemKind::Mod(module) + hir::ItemKind::Mod(self.lower_mod(items, *inner_span)) } ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), }, @@ -550,10 +537,13 @@ impl<'hir> LoweringContext<'_, 'hir> { this.attrs.insert(new_id, attrs); } - this.insert_item( - hir::Item { def_id: new_id.expect_owner(), ident, kind, vis, span }, - false, - ); + this.insert_item(hir::Item { + def_id: new_id.expect_owner(), + ident, + kind, + vis, + span, + }); }); } @@ -621,16 +611,13 @@ impl<'hir> LoweringContext<'_, 'hir> { this.attrs.insert(new_hir_id, attrs); } - this.insert_item( - hir::Item { - def_id: new_hir_id.expect_owner(), - ident, - kind, - vis, - span: use_tree.span, - }, - false, - ); + this.insert_item(hir::Item { + def_id: new_hir_id.expect_owner(), + ident, + kind, + vis, + span: use_tree.span, + }); }); } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5a42b5bb2097a..3fe698c3946ec 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -36,7 +36,6 @@ #![recursion_limit = "256"] use rustc_ast::node_id::NodeMap; -use rustc_ast::ptr::P; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; @@ -121,11 +120,8 @@ struct LoweringContext<'a, 'hir: 'a> { /// outside of an `async fn`. current_item: Option, - top_level_items: Vec, - catch_scopes: Vec, loop_scopes: Vec, - is_at_top_level: bool, is_in_loop_condition: bool, is_in_trait_impl: bool, is_in_dyn_type: bool, @@ -335,7 +331,6 @@ pub fn lower_crate<'a, 'hir>( attrs: BTreeMap::default(), catch_scopes: Vec::new(), loop_scopes: Vec::new(), - is_at_top_level: true, is_in_loop_condition: false, is_in_trait_impl: false, is_in_dyn_type: false, @@ -348,7 +343,6 @@ pub fn lower_crate<'a, 'hir>( generator_kind: None, task_context: None, current_item: None, - top_level_items: Vec::new(), lifetimes_to_define: Vec::new(), is_collecting_in_band_lifetimes: false, in_scope_lifetimes: Vec::new(), @@ -473,22 +467,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .count(); self.lctx.type_def_lifetime_params.insert(def_id.to_def_id(), count); } - ItemKind::MacroDef(..) => { - if self.lctx.check_force_top_level(item) { - self.lctx.top_level_items.push(item.clone()); - } - } ItemKind::Use(ref use_tree) => { self.allocate_use_tree_hir_id_counters(use_tree); } _ => {} } - let was_at_top_level = mem::replace(&mut self.lctx.is_at_top_level, false); - visit::walk_item(self, item); - - self.lctx.is_at_top_level = was_at_top_level; } fn visit_assoc_item(&mut self, item: &'tcx AssocItem, ctxt: AssocCtxt) { @@ -525,10 +510,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c); visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c); - let mut items: Vec<_> = self.top_level_items.drain(..).map(|item| P(item)).collect(); - items.extend(c.items.clone()); - - let module = self.arena.alloc(self.lower_mod(items.as_slice(), c.span)); + let module = self.arena.alloc(self.lower_mod(&c.items, c.span)); self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs); self.owners.ensure_contains_elem(CRATE_DEF_ID, || None); self.owners[CRATE_DEF_ID] = Some(hir::OwnerNode::Crate(module)); @@ -579,13 +561,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(krate) } - fn insert_item(&mut self, item: hir::Item<'hir>, force_top_level: bool) -> hir::ItemId { + fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId { let id = item.item_id(); let item = self.arena.alloc(item); - let module = if force_top_level { CRATE_DEF_ID } else { self.current_module }; self.owners.ensure_contains_elem(id.def_id, || None); self.owners[id.def_id] = Some(hir::OwnerNode::Item(item)); - self.modules.entry(module).or_default().items.insert(id); + self.modules.entry(self.current_module).or_default().items.insert(id); id } @@ -616,19 +597,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id } - /// This checks if an item is a `#[macro_use]` macro, and thus always - /// defined at the top level. As a special case, if the macro is already - /// at the top level, it remains at its current level. - fn check_force_top_level(&self, item: &Item) -> bool { - if self.is_at_top_level { - false - } else if let ItemKind::MacroDef(MacroDef { macro_rules, .. }) = item.kind { - macro_rules && self.sess.contains_name(&item.attrs, sym::macro_export) - } else { - false - } - } - fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId { // Set up the counter if needed. self.item_local_id_counters.entry(owner).or_insert(0); @@ -1625,7 +1593,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Insert the item into the global item list. This usually happens // automatically for all AST items. But this opaque type item // does not actually exist in the AST. - self.insert_item(opaque_ty_item, false); + self.insert_item(opaque_ty_item); } fn lifetimes_from_impl_trait_bounds( @@ -2414,22 +2382,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { [stmts @ .., Stmt { kind: StmtKind::Expr(e), .. }] => (stmts, Some(&*e)), stmts => (stmts, None), }; - let stmts: Vec<_> = stmts - .iter() - .filter_map(|stmt| { - if let StmtKind::Item(ref item) = stmt.kind { - if self.check_force_top_level(item) { - None - } else { - Some(self.lower_stmt(stmt)) - } - } else { - Some(self.lower_stmt(stmt)) - } - }) - .flatten() - .collect(); - let stmts = self.arena.alloc_from_iter(stmts.into_iter()); + let stmts = self.arena.alloc_from_iter(stmts.iter().flat_map(|stmt| self.lower_stmt(stmt))); let expr = expr.map(|e| self.lower_expr(e)); let rules = self.lower_block_check_mode(&b.rules); let hir_id = self.lower_node_id(b.id); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 075555dc708c1..6f4f1bdaea1b7 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -4,7 +4,7 @@ use rustc_ast::walk_list; use rustc_ast::*; use rustc_ast_lowering::ResolverAstLowering; use rustc_expand::expand::AstFragment; -use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::definitions::*; use rustc_span::hygiene::LocalExpnId; use rustc_span::symbol::{kw, sym}; @@ -29,18 +29,9 @@ struct DefCollector<'a, 'b> { } impl<'a, 'b> DefCollector<'a, 'b> { - fn create_def( - &mut self, - node_id: NodeId, - data: DefPathData, - span: Span, - force_top_level: bool, - ) -> LocalDefId { - let parent_def = if force_top_level { CRATE_DEF_ID } else { self.parent_def }; - debug!( - "create_def(node_id={:?}, data={:?}, parent_def={:?}, force_top_level={:?}", - node_id, data, parent_def, force_top_level - ); + fn create_def(&mut self, node_id: NodeId, data: DefPathData, span: Span) -> LocalDefId { + let parent_def = self.parent_def; + debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); self.resolver.create_def(parent_def, node_id, data, self.expansion.to_expn_id(), span) } @@ -74,7 +65,7 @@ impl<'a, 'b> DefCollector<'a, 'b> { self.visit_macro_invoc(field.id); } else { let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); - let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span, false); + let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span); self.with_parent(def, |this| visit::walk_field_def(this, field)); } } @@ -91,8 +82,6 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { fn visit_item(&mut self, i: &'a Item) { debug!("visit_item: {:?}", i); - let mut force_top_level = false; - // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better let def_data = match &i.kind { @@ -113,14 +102,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => { DefPathData::ValueNs(i.ident.name) } - ItemKind::MacroDef(ref macro_def) => { - if macro_def.macro_rules - && self.resolver.session.contains_name(&i.attrs, sym::macro_export) - { - force_top_level = true; - } - DefPathData::MacroNs(i.ident.name) - } + ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name), ItemKind::MacCall(..) => { visit::walk_item(self, i); return self.visit_macro_invoc(i.id); @@ -130,7 +112,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { return visit::walk_item(self, i); } }; - let def = self.create_def(i.id, def_data, i.span, force_top_level); + let def = self.create_def(i.id, def_data, i.span); self.with_parent(def, |this| { this.with_impl_trait(ImplTraitContext::Existential, |this| { @@ -138,7 +120,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { // If this is a unit or tuple-like struct, register the constructor. if let Some(ctor_hir_id) = struct_def.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, i.span, false); + this.create_def(ctor_hir_id, DefPathData::Ctor, i.span); } } _ => {} @@ -152,7 +134,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { if let FnKind::Fn(_, _, sig, _, body) = fn_kind { if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness { let return_impl_trait_id = - self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span, false); + self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. Besides that, @@ -164,8 +146,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { self.with_parent(return_impl_trait_id, |this| { this.visit_fn_ret_ty(&sig.decl.output) }); - let closure_def = - self.create_def(closure_id, DefPathData::ClosureExpr, span, false); + let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span); self.with_parent(closure_def, |this| walk_list!(this, visit_block, body)); return; } @@ -175,11 +156,11 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { } fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) { - self.create_def(id, DefPathData::Misc, use_tree.span, false); + self.create_def(id, DefPathData::Misc, use_tree.span); match use_tree.kind { UseTreeKind::Simple(_, id1, id2) => { - self.create_def(id1, DefPathData::Misc, use_tree.prefix.span, false); - self.create_def(id2, DefPathData::Misc, use_tree.prefix.span, false); + self.create_def(id1, DefPathData::Misc, use_tree.prefix.span); + self.create_def(id2, DefPathData::Misc, use_tree.prefix.span); } UseTreeKind::Glob => (), UseTreeKind::Nested(..) => {} @@ -196,7 +177,6 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name), foreign_item.span, - false, ); self.with_parent(def, |this| { @@ -208,10 +188,10 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { if v.is_placeholder { return self.visit_macro_invoc(v.id); } - let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span, false); + let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span); self.with_parent(def, |this| { if let Some(ctor_hir_id) = v.data.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, v.span, false); + this.create_def(ctor_hir_id, DefPathData::Ctor, v.span); } visit::walk_variant(this, v) }); @@ -237,7 +217,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { GenericParamKind::Type { .. } => DefPathData::TypeNs(name), GenericParamKind::Const { .. } => DefPathData::ValueNs(name), }; - self.create_def(param.id, def_path_data, param.ident.span, false); + self.create_def(param.id, def_path_data, param.ident.span); // impl-Trait can happen inside generic parameters, like // ``` @@ -257,7 +237,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { AssocItemKind::MacCall(..) => return self.visit_macro_invoc(i.id), }; - let def = self.create_def(i.id, def_data, i.span, false); + let def = self.create_def(i.id, def_data, i.span); self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); } @@ -269,7 +249,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { } fn visit_anon_const(&mut self, constant: &'a AnonConst) { - let def = self.create_def(constant.id, DefPathData::AnonConst, constant.value.span, false); + let def = self.create_def(constant.id, DefPathData::AnonConst, constant.value.span); self.with_parent(def, |this| visit::walk_anon_const(this, constant)); } @@ -279,17 +259,16 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ExprKind::Closure(_, asyncness, ..) => { // Async closures desugar to closures inside of closures, so // we must create two defs. - let closure_def = - self.create_def(expr.id, DefPathData::ClosureExpr, expr.span, false); + let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span); match asyncness { Async::Yes { closure_id, .. } => { - self.create_def(closure_id, DefPathData::ClosureExpr, expr.span, false) + self.create_def(closure_id, DefPathData::ClosureExpr, expr.span) } Async::No => closure_def, } } ExprKind::Async(_, async_id, _) => { - self.create_def(async_id, DefPathData::ClosureExpr, expr.span, false) + self.create_def(async_id, DefPathData::ClosureExpr, expr.span) } _ => self.parent_def, }; @@ -310,7 +289,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { ty.span, ), ImplTraitContext::Existential => { - self.create_def(node_id, DefPathData::ImplTrait, ty.span, false) + self.create_def(node_id, DefPathData::ImplTrait, ty.span) } }; self.with_parent(parent_def, |this| visit::walk_ty(this, ty)) From 9347710537112f6e2baae83fb23a62388655d655 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Sat, 14 Aug 2021 16:55:44 -0700 Subject: [PATCH 09/18] Adjust rustdoc implementation --- src/librustdoc/doctest.rs | 24 ++++++++--------- src/librustdoc/visit_ast.rs | 51 ++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index d5268abeec795..9b7f28e682ef7 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1171,10 +1171,17 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx> } fn visit_item(&mut self, item: &'hir hir::Item<'_>) { - let name = if let hir::ItemKind::Impl(impl_) = &item.kind { - rustc_hir_pretty::id_to_string(&self.map, impl_.self_ty.hir_id) - } else { - item.ident.to_string() + let name = match &item.kind { + hir::ItemKind::Macro { is_exported: false, .. } => { + // FIXME(#88038): Non exported macros have historically not been tested, + // but we really ought to start testing them. + intravisit::walk_item(self, item); + return; + } + hir::ItemKind::Impl(impl_) => { + rustc_hir_pretty::id_to_string(&self.map, impl_.self_ty.hir_id) + } + _ => item.ident.to_string(), }; self.visit_testable(name, item.hir_id(), item.span, |this| { @@ -1216,15 +1223,6 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx> intravisit::walk_field_def(this, f); }); } - - fn visit_macro_def(&mut self, macro_def: &'hir hir::MacroDef<'_>) { - self.visit_testable( - macro_def.ident.to_string(), - macro_def.hir_id(), - macro_def.span, - |_| (), - ); - } } #[cfg(test)] diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index db8386862819b..e3feea5b2561b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -7,9 +7,9 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::Node; use rustc_middle::middle::privacy::AccessLevel; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{TyCtxt, Visibility}; use rustc_span; -use rustc_span::def_id::LOCAL_CRATE; +use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Symbol}; @@ -73,13 +73,31 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> { let span = krate.module().inner; - let top_level_module = self.visit_mod_contents( + let mut top_level_module = self.visit_mod_contents( &Spanned { span, node: hir::VisibilityKind::Public }, hir::CRATE_HIR_ID, &krate.module(), self.cx.tcx.crate_name(LOCAL_CRATE), ); + // `#[macro_export] macro_rules!` items are reexported at the top level of the + // crate, regardless of where they're defined. We want to document the + // top level rexport of the macro, not its original definition, since + // the rexport defines the path that a user will actually see. Accordingly, + // we add the rexport as an item here, and then skip over the original + // definition in `visit_item()` below. + for export in self.cx.tcx.module_exports(CRATE_DEF_ID).unwrap_or(&[]) { + if let Res::Def(DefKind::Macro(_), def_id) = export.res { + if let Some(local_def_id) = def_id.as_local() { + if self.cx.tcx.has_attr(def_id, sym::macro_export) { + let hir_id = self.cx.tcx.hir().local_def_id_to_hir_id(local_def_id); + let item = self.cx.tcx.hir().expect_item(hir_id); + top_level_module.items.push((item, None)); + } + } + } + } + self.cx.cache.exact_paths = self.exact_paths; top_level_module } @@ -210,11 +228,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { debug!("visiting item {:?}", item); let name = renamed.unwrap_or(item.ident.name); - let is_pub = if let hir::ItemKind::Macro { is_exported: true, .. } = item.kind { - true - } else { - item.vis.node.is_pub() - }; + let is_pub = self.cx.tcx.visibility(item.def_id) == Visibility::Public; if is_pub { self.store_path(item.def_id.to_def_id()); @@ -269,8 +283,27 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::ItemKind::Mod(ref m) => { om.mods.push(self.visit_mod_contents(&item.vis, item.hir_id(), m, name)); } + 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: + // + // 1. This macro was defined by `macro`, and thus isn't covered by the case + // above. + // 2. This macro isn't marked with `#[macro_export]`, and thus isn't covered + // by the case above. + // 3. We're inlining, since a reexport where inlining has been requested + // should be inlined even if it is also documented at the top level. + + let def_id = item.def_id.to_def_id(); + let is_macro_2_0 = !macro_def.ast.macro_rules; + let nonexported = !self.cx.tcx.has_attr(def_id, sym::macro_export); + + if is_macro_2_0 || nonexported || self.inlining { + om.items.push((item, renamed)); + } + } hir::ItemKind::Fn(..) - | hir::ItemKind::Macro { .. } | hir::ItemKind::ExternCrate(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) From 020a39156f945d42be9af2dd4a84581859750f9f Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Sun, 15 Aug 2021 01:38:44 -0700 Subject: [PATCH 10/18] Stop tracking whether macros are exported in HIR --- compiler/rustc_ast_lowering/src/item.rs | 22 ++++------- compiler/rustc_hir/src/hir.rs | 3 +- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir/src/stable_hash_impls.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 +--- compiler/rustc_passes/src/check_attr.rs | 7 +++- compiler/rustc_passes/src/stability.rs | 1 - compiler/rustc_privacy/src/lib.rs | 39 ++++++++++++-------- 10 files changed, 42 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 02a62ebdb2d55..d6087acc2fb08 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -443,23 +443,15 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), ), ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { - let is_exported = !macro_rules - || attrs.map_or(false, |a| self.sess.contains_name(a, sym::macro_export)); - let body = P(self.lower_mac_args(body)); - hir::ItemKind::Macro { - // `is_exported` is duplicated, to make matching more convenient. - is_exported, - macro_def: hir::MacroDef { - is_exported, - ident: *ident, - vis: *vis, - def_id: hir_id.expect_owner(), - span, - ast: MacroDef { body, macro_rules }, - }, - } + hir::ItemKind::Macro(hir::MacroDef { + ident: *ident, + vis: *vis, + def_id: hir_id.expect_owner(), + span, + ast: MacroDef { body, macro_rules }, + }) } ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 53c98a0db7f39..f9c067150d492 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -772,7 +772,6 @@ impl Crate<'_> { /// Not parsed directly, but created on macro import or `macro_rules!` expansion. #[derive(Debug)] pub struct MacroDef<'hir> { - pub is_exported: bool, pub ident: Ident, pub vis: Visibility<'hir>, pub def_id: LocalDefId, @@ -2781,7 +2780,7 @@ pub enum ItemKind<'hir> { /// An external module, e.g. `extern { .. }`. ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] }, /// A MBE macro (`macro_rules!` or `macro`). - Macro { is_exported: bool, macro_def: MacroDef<'hir> }, + Macro(MacroDef<'hir>), /// Module-level inline assembly (from `global_asm!`). GlobalAsm(&'hir InlineAsm<'hir>), /// A type alias, e.g., `type Foo = Bar`. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 4816e45e5bed5..22b9bef382766 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -593,7 +593,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { visitor.visit_id(item.hir_id()); walk_list!(visitor, visit_foreign_item_ref, items); } - ItemKind::Macro { ref macro_def, .. } => { + ItemKind::Macro(ref macro_def) => { visitor.visit_id(item.hir_id()); visitor.visit_macro_def(macro_def) } diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 891df8f144522..560607528330b 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -193,7 +193,7 @@ impl HashStable for Item<'_> { impl HashStable for MacroDef<'_> { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - let MacroDef { is_exported: _, ident, def_id: _, ref ast, ref vis, span } = *self; + let MacroDef { ident, def_id: _, ref ast, ref vis, span } = *self; hcx.hash_hir_item_like(|hcx| { ident.name.hash_stable(hcx, hasher); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 606f2efa66045..6788cbcb2bb8a 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -660,7 +660,7 @@ impl<'a> State<'a> { } self.bclose(item.span); } - hir::ItemKind::Macro { ref macro_def, .. } => { + hir::ItemKind::Macro(ref macro_def) => { let (kw, has_bang) = if macro_def.ast.macro_rules { ("macro_rules", true) } else { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 8fd468875787b..afa032ab27d5e 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -617,7 +617,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { return; } - hir::ItemKind::Macro { is_exported: true, .. } + hir::ItemKind::Macro { .. } | hir::ItemKind::TyAlias(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 830fa6a430cde..16c4969b3d2f7 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1374,12 +1374,8 @@ impl EncodeContext<'a, 'tcx> { return self.encode_info_for_mod(item.def_id, m); } hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod, - hir::ItemKind::Macro { is_exported, ref macro_def } => { - if is_exported { - EntryKind::MacroDef(self.lazy(macro_def.ast.clone())) - } else { - return; - } + hir::ItemKind::Macro(ref macro_def) => { + EntryKind::MacroDef(self.lazy(macro_def.ast.clone())) } hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm, hir::ItemKind::TyAlias(..) => EntryKind::Type, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6883a6d7a778e..23cb2ce498a68 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1512,8 +1512,11 @@ impl 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 { is_exported: false, .. } = item.kind { - check_non_exported_macro_for_invalid_attrs(self.tcx, item); + if let ItemKind::Macro(ref macro_def) = item.kind { + let def_id = item.def_id.to_def_id(); + if macro_def.ast.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { + check_non_exported_macro_for_invalid_attrs(self.tcx, item); + } } let target = Target::from_item(item); diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 4b245ce5c1696..bf00516024916 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -622,7 +622,6 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { i.kind, hir::ItemKind::Impl(hir::Impl { of_trait: None, .. }) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::Macro { is_exported: false, .. } ) { self.check_missing_stability(i.def_id, i.span); } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3f40cab0f3e89..628764ae83eda 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -25,7 +25,7 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::hygiene::Transparency; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use rustc_trait_selection::traits::const_evaluatable::{self, AbstractConst}; @@ -507,11 +507,7 @@ impl EmbargoVisitor<'tcx> { } match def_kind { // No type privacy, so can be directly marked as reachable. - DefKind::Const - | DefKind::Macro(_) - | DefKind::Static - | DefKind::TraitAlias - | DefKind::TyAlias => { + DefKind::Const | DefKind::Static | DefKind::TraitAlias | DefKind::TyAlias => { if vis.is_accessible_from(module.to_def_id(), self.tcx) { self.update(def_id, level); } @@ -566,6 +562,7 @@ impl EmbargoVisitor<'tcx> { | DefKind::ExternCrate | DefKind::Use | DefKind::ForeignMod + | DefKind::Macro(_) | DefKind::AnonConst | DefKind::Field | DefKind::GlobalAsm @@ -642,11 +639,23 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } // Foreign modules inherit level from parents. hir::ItemKind::ForeignMod { .. } => self.prev_level, - // Non-exported macros can't be visible by definition; - hir::ItemKind::Macro { is_exported: false, .. } => None, + hir::ItemKind::Macro(ref macro_def) => { + let def_id = item.def_id.to_def_id(); + let is_macro_export = self.tcx.has_attr(def_id, sym::macro_export); + match (macro_def.ast.macro_rules, is_macro_export) { + (true, true) => Some(AccessLevel::Public), + (true, false) => None, + (false, _) => { + if item.vis.node.is_pub() { + self.prev_level + } else { + None + } + } + } + } // Other `pub` items inherit levels from parents. - hir::ItemKind::Macro { is_exported: true, .. } - | hir::ItemKind::Const(..) + hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::ExternCrate(..) | hir::ItemKind::GlobalAsm(..) @@ -714,17 +723,15 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } - hir::ItemKind::Macro { macro_def: ref md, .. } => { + hir::ItemKind::Macro(ref md) => { + // We have to make sure that the items that macros might reference + // are reachable, since they might be exported transitively. + // Non-opaque macros cannot make other items more accessible than they already are. let attrs = self.tcx.hir().attrs(md.hir_id()); if attr::find_transparency(&self.tcx.sess, &attrs, md.ast.macro_rules).0 != Transparency::Opaque { - // `#[macro_export]`-ed `macro_rules!` are `Public` since they - // ignore their containing path to always appear at the crate root. - if md.ast.macro_rules { - self.update(item.def_id, Some(AccessLevel::Public)); - } return; } From b0c6d6acae982495a2b7debf5592991029dea924 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Sun, 15 Aug 2021 01:52:35 -0700 Subject: [PATCH 11/18] Fix tools --- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/doctest.rs | 10 +++++++--- src/librustdoc/visit_ast.rs | 2 +- src/tools/clippy/clippy_lints/src/utils/inspector.rs | 10 ++-------- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8fb9065fafc66..e7ede6870cab3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1859,7 +1859,7 @@ impl Clean> for (&hir::Item<'_>, Option) { 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, .. } => MacroItem(Macro { + ItemKind::Macro(ref macro_def) => MacroItem(Macro { source: display_macro_source(cx, name, ¯o_def.ast, def_id, &item.vis), imported_from: None, }), diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 9b7f28e682ef7..9967f5d3e05fa 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1172,11 +1172,15 @@ 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 { is_exported: false, .. } => { + hir::ItemKind::Macro(ref macro_def) => { // FIXME(#88038): Non exported macros have historically not been tested, // but we really ought to start testing them. - intravisit::walk_item(self, item); - return; + let def_id = item.def_id.to_def_id(); + if macro_def.ast.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { + intravisit::walk_item(self, item); + return; + } + item.ident.to_string() } hir::ItemKind::Impl(impl_) => { rustc_hir_pretty::id_to_string(&self.map, impl_.self_ty.hir_id) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e3feea5b2561b..3671b1770d02d 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -283,7 +283,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::ItemKind::Mod(ref m) => { om.mods.push(self.visit_mod_contents(&item.vis, item.hir_id(), m, name)); } - 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: diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index c013bb9d27faf..ad4d4a64e936b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -408,16 +408,10 @@ fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) { }, hir::ItemKind::Mod(..) => println!("module"), hir::ItemKind::ForeignMod { abi, .. } => println!("foreign module with abi: {}", abi), - hir::ItemKind::Macro { ref macro_def, .. } => { + hir::ItemKind::Macro(ref macro_def) => { if macro_def.ast.macro_rules { - if macro_def.is_exported { - println!("exported macro introduced by `macro_rules!`"); - } else { - println!("nonexported macro introduced by `macro_rules!`"); - } + println!("macro introduced by `macro_rules!`"); } else { - // There's no point in distinguishing exported and nonexported `macro` - // macros. That's defined their visibility, which was printed above. println!("macro introduced by `macro`"); } } From 542746e038941c3ced082beb4dbd0d296036956b Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Sun, 15 Aug 2021 15:43:17 -0700 Subject: [PATCH 12/18] Update test --- src/test/rustdoc-ui/deny-missing-docs-macro.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc-ui/deny-missing-docs-macro.stderr b/src/test/rustdoc-ui/deny-missing-docs-macro.stderr index a564006e74f48..0867b08183e2d 100644 --- a/src/test/rustdoc-ui/deny-missing-docs-macro.stderr +++ b/src/test/rustdoc-ui/deny-missing-docs-macro.stderr @@ -1,4 +1,4 @@ -error: missing documentation for macro +error: missing documentation for a macro --> $DIR/deny-missing-docs-macro.rs:6:1 | LL | macro_rules! foo { From b8061b8605284dcb2941b57d185c718a27896b95 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Tue, 17 Aug 2021 21:06:16 -0700 Subject: [PATCH 13/18] Perform minor cleanup --- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir/src/target.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 4 ++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 4 ++-- compiler/rustc_mir/src/monomorphize/collector.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 2 +- compiler/rustc_passes/src/stability.rs | 9 ++++----- compiler/rustc_privacy/src/lib.rs | 4 ++-- compiler/rustc_resolve/src/late/lifetimes.rs | 2 +- compiler/rustc_save_analysis/src/sig.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 2 +- compiler/rustc_typeck/src/collect/type_of.rs | 2 +- 13 files changed, 19 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f9c067150d492..a7097c3e5ea80 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2844,7 +2844,7 @@ impl ItemKind<'_> { ItemKind::Fn(..) => "function", ItemKind::Mod(..) => "module", ItemKind::ForeignMod { .. } => "extern block", - ItemKind::Macro { .. } => "macro", + ItemKind::Macro(..) => "macro", ItemKind::GlobalAsm(..) => "global asm item", ItemKind::TyAlias(..) => "type alias", ItemKind::OpaqueTy(..) => "opaque type", diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index ad7bc030cb251..dabdccbe77ef2 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -113,7 +113,7 @@ impl Target { ItemKind::Fn(..) => Target::Fn, ItemKind::Mod(..) => Target::Mod, ItemKind::ForeignMod { .. } => Target::ForeignMod, - ItemKind::Macro { .. } => Target::MacroDef, + ItemKind::Macro(..) => Target::MacroDef, ItemKind::GlobalAsm(..) => Target::GlobalAsm, ItemKind::TyAlias(..) => Target::TyAlias, ItemKind::OpaqueTy(..) => Target::OpaqueTy, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index afa032ab27d5e..4a7acf657511a 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -617,10 +617,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { return; } - hir::ItemKind::Macro { .. } - | hir::ItemKind::TyAlias(..) + hir::ItemKind::TyAlias(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) + | hir::ItemKind::Macro(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 16c4969b3d2f7..9db9b34c60aab 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1952,7 +1952,7 @@ impl EncodeContext<'a, 'tcx> { | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::Macro { .. } + | hir::ItemKind::Macro(..) | hir::ItemKind::GlobalAsm(..) | hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 360b3094df221..8da8024c7bd54 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -228,7 +228,7 @@ impl<'hir> Map<'hir> { ItemKind::ExternCrate(_) => DefKind::ExternCrate, ItemKind::Use(..) => DefKind::Use, ItemKind::ForeignMod { .. } => DefKind::ForeignMod, - ItemKind::Macro { .. } => DefKind::Macro(MacroKind::Bang), + ItemKind::Macro(..) => DefKind::Macro(MacroKind::Bang), ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, ItemKind::Impl { .. } => DefKind::Impl, }, @@ -1042,7 +1042,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String { ItemKind::Fn(..) => "fn", ItemKind::Mod(..) => "mod", ItemKind::ForeignMod { .. } => "foreign mod", - ItemKind::Macro { .. } => "macro", + ItemKind::Macro(..) => "macro", ItemKind::GlobalAsm(..) => "global asm", ItemKind::TyAlias(..) => "ty", ItemKind::OpaqueTy(..) => "opaque type", diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index faac2a59a01ba..c6fd9eaf1a836 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -1150,7 +1150,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::Macro { .. } + | hir::ItemKind::Macro(..) | hir::ItemKind::TyAlias(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 29978a49ab874..d406042c44eff 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -264,7 +264,7 @@ impl<'tcx> ReachableContext<'tcx> { | hir::ItemKind::TyAlias(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::Macro { .. } + | hir::ItemKind::Macro(..) | hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index bf00516024916..8b3268257b165 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -613,11 +613,10 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { } fn visit_item(&mut self, i: &'tcx Item<'tcx>) { - // Inherent impls, foreign modules, and non exported macros serve only as - // containers for other items, they don't have their own stability. They still can - // be annotated as unstable and propagate this unstability to children, but this - // annotation is completely optional. They inherit stability from their parents - // when unannotated. + // Inherent impls and foreign modules serve only as containers for other items, + // they don't have their own stability. They still can be annotated as unstable + // and propagate this unstability to children, but this annotation is completely + // optional. They inherit stability from their parents when unannotated. if !matches!( i.kind, hir::ItemKind::Impl(hir::Impl { of_trait: None, .. }) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 628764ae83eda..3553baee8423b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -778,7 +778,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { // Mark all items in interfaces of reachable items as reachable. match item.kind { // The interface is empty. - hir::ItemKind::Macro { .. } | hir::ItemKind::ExternCrate(..) => {} + hir::ItemKind::Macro(..) | hir::ItemKind::ExternCrate(..) => {} // All nested items are checked by `visit_item`. hir::ItemKind::Mod(..) => {} @@ -1988,7 +1988,7 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> { // Checked in resolve. hir::ItemKind::Use(..) => {} // No subitems. - hir::ItemKind::GlobalAsm(..) | hir::ItemKind::Macro { .. } => {} + hir::ItemKind::Macro(..) | hir::ItemKind::GlobalAsm(..) => {} // Subitems of these items have inherited publicity. hir::ItemKind::Const(..) | hir::ItemKind::Static(..) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index be3e7ea7d6fec..191f648a55de2 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -742,7 +742,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Use(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::Macro { .. } + | hir::ItemKind::Macro(..) | hir::ItemKind::GlobalAsm(..) => { // These sorts of items have no lifetime parameters at all. intravisit::walk_item(self, item); diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs index bfcf1fde6b862..4ac6e8e6dc471 100644 --- a/compiler/rustc_save_analysis/src/sig.rs +++ b/compiler/rustc_save_analysis/src/sig.rs @@ -430,7 +430,7 @@ impl<'hir> Sig for hir::Item<'hir> { Ok(Signature { text, defs, refs: vec![] }) } - hir::ItemKind::Macro { .. } => { + hir::ItemKind::Macro(..) => { let mut text = "macro".to_owned(); let name = self.ident.to_string(); text.push_str(&name); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 11a251bbc70ed..d445bed4ca1b8 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -750,7 +750,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) | hir::ItemKind::Mod(_) - | hir::ItemKind::Macro { .. } + | hir::ItemKind::Macro(..) | hir::ItemKind::GlobalAsm(_) => {} hir::ItemKind::ForeignMod { items, .. } => { for item in items { diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 861f56cbcf7ca..8cd0b8ccc9c7c 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -404,7 +404,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { | ItemKind::TraitAlias(..) | ItemKind::Mod(..) | ItemKind::ForeignMod { .. } - | ItemKind::Macro { .. } + | ItemKind::Macro(..) | ItemKind::GlobalAsm(..) | ItemKind::ExternCrate(..) | ItemKind::Use(..) => { From 43802ec598f60cd1e6d67bfc4f27d733af84d80d Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Tue, 17 Aug 2021 22:36:07 -0700 Subject: [PATCH 14/18] Perform minor cleanup (tools edition) --- src/tools/clippy/clippy_lints/src/missing_doc.rs | 2 +- src/tools/clippy/clippy_lints/src/missing_inline.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 9e8e84657c973..da86d28ee0b2d 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -123,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Mod(..) - | hir::ItemKind::Macro { .. } + | hir::ItemKind::Macro(..) | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 3f26ec2e73237..37ec743da314b 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -119,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Mod(..) - | hir::ItemKind::Macro { .. } + | hir::ItemKind::Macro(..) | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::TraitAlias(..) From fef71afd60264766f4a9eca187220623daa737d4 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Wed, 18 Aug 2021 00:58:23 -0700 Subject: [PATCH 15/18] Eliminate `hir::MacroDef` --- compiler/rustc_ast_lowering/src/item.rs | 8 +------- compiler/rustc_hir/src/arena.rs | 1 - compiler/rustc_hir/src/hir.rs | 21 +------------------- compiler/rustc_hir/src/intravisit.rs | 11 +--------- compiler/rustc_hir/src/stable_hash_impls.rs | 17 ++-------------- compiler/rustc_hir_pretty/src/lib.rs | 8 ++++---- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_passes/src/hir_stats.rs | 5 ----- compiler/rustc_passes/src/stability.rs | 13 ------------ compiler/rustc_privacy/src/lib.rs | 13 ++++++------ 11 files changed, 17 insertions(+), 84 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d6087acc2fb08..cc87078d54b3f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -445,13 +445,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { let body = P(self.lower_mac_args(body)); - hir::ItemKind::Macro(hir::MacroDef { - ident: *ident, - vis: *vis, - def_id: hir_id.expect_owner(), - span, - ast: MacroDef { body, macro_rules }, - }) + hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }) } ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index c4cff79f6c525..0801a1bde2264 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -35,7 +35,6 @@ macro_rules! arena_types { [few] inline_asm: rustc_hir::InlineAsm<$tcx>, [few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, [] local: rustc_hir::Local<$tcx>, - [few] macro_def: rustc_hir::MacroDef<$tcx>, [few] mod_: rustc_hir::Mod<$tcx>, [] param: rustc_hir::Param<$tcx>, [] pat: rustc_hir::Pat<$tcx>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a7097c3e5ea80..aaf49e5539f68 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -767,25 +767,6 @@ impl Crate<'_> { } } -/// A macro definition, in this crate or imported from another. -/// -/// Not parsed directly, but created on macro import or `macro_rules!` expansion. -#[derive(Debug)] -pub struct MacroDef<'hir> { - pub ident: Ident, - pub vis: Visibility<'hir>, - pub def_id: LocalDefId, - pub span: Span, - pub ast: ast::MacroDef, -} - -impl MacroDef<'_> { - #[inline] - pub fn hir_id(&self) -> HirId { - HirId::make_owner(self.def_id) - } -} - /// A block of statements `{ .. }`, which may have a label (in this case the /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of /// the `rules` being anything but `DefaultBlock`. @@ -2780,7 +2761,7 @@ pub enum ItemKind<'hir> { /// An external module, e.g. `extern { .. }`. ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] }, /// A MBE macro (`macro_rules!` or `macro`). - Macro(MacroDef<'hir>), + Macro(ast::MacroDef), /// Module-level inline assembly (from `global_asm!`). GlobalAsm(&'hir InlineAsm<'hir>), /// A type alias, e.g., `type Foo = Bar`. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 22b9bef382766..e73a02675a2c8 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -466,9 +466,6 @@ pub trait Visitor<'v>: Sized { walk_assoc_type_binding(self, type_binding) } fn visit_attribute(&mut self, _id: HirId, _attr: &'v Attribute) {} - fn visit_macro_def(&mut self, macro_def: &'v MacroDef<'v>) { - walk_macro_def(self, macro_def) - } fn visit_vis(&mut self, vis: &'v Visibility<'v>) { walk_vis(self, vis) } @@ -491,11 +488,6 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) { } } -pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef<'v>) { - visitor.visit_id(macro_def.hir_id()); - visitor.visit_ident(macro_def.ident); -} - pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) { visitor.visit_id(mod_hir_id); for &item_id in module.item_ids { @@ -593,9 +585,8 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { visitor.visit_id(item.hir_id()); walk_list!(visitor, visit_foreign_item_ref, items); } - ItemKind::Macro(ref macro_def) => { + ItemKind::Macro(_) => { visitor.visit_id(item.hir_id()); - visitor.visit_macro_def(macro_def) } ItemKind::GlobalAsm(asm) => { visitor.visit_id(item.hir_id()); diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 560607528330b..422a1064874c5 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -1,8 +1,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use crate::hir::{ - BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, MacroDef, Mod, - TraitItem, TraitItemId, Ty, VisibilityKind, + BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem, + TraitItemId, Ty, VisibilityKind, }; use crate::hir_id::{HirId, ItemLocalId}; use rustc_span::def_id::DefPathHash; @@ -190,16 +190,3 @@ impl HashStable for Item<'_> { }); } } - -impl HashStable for MacroDef<'_> { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - let MacroDef { ident, def_id: _, ref ast, ref vis, span } = *self; - - hcx.hash_hir_item_like(|hcx| { - ident.name.hash_stable(hcx, hasher); - ast.hash_stable(hcx, hasher); - vis.hash_stable(hcx, hasher); - span.hash_stable(hcx, hasher); - }); - } -} diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 6788cbcb2bb8a..019bf87292078 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -661,7 +661,7 @@ impl<'a> State<'a> { self.bclose(item.span); } hir::ItemKind::Macro(ref macro_def) => { - let (kw, has_bang) = if macro_def.ast.macro_rules { + let (kw, has_bang) = if macro_def.macro_rules { ("macro_rules", true) } else { self.print_visibility(&item.vis); @@ -672,13 +672,13 @@ impl<'a> State<'a> { Some(MacHeader::Keyword(kw)), has_bang, Some(item.ident), - macro_def.ast.body.delim(), - ¯o_def.ast.body.inner_tokens(), + macro_def.body.delim(), + ¯o_def.body.inner_tokens(), true, item.span, ); - if macro_def.ast.body.need_semicolon() { + if macro_def.body.need_semicolon() { self.word(";"); } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 9db9b34c60aab..fa7dc68f577cd 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1375,7 +1375,7 @@ impl EncodeContext<'a, 'tcx> { } hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod, hir::ItemKind::Macro(ref macro_def) => { - EntryKind::MacroDef(self.lazy(macro_def.ast.clone())) + EntryKind::MacroDef(self.lazy(macro_def.clone())) } hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm, hir::ItemKind::TyAlias(..) => EntryKind::Type, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 23cb2ce498a68..b9e3066b31266 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1514,7 +1514,7 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { // In the long run, the checks should be harmonized. if let ItemKind::Macro(ref macro_def) = item.kind { let def_id = item.def_id.to_def_id(); - if macro_def.ast.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { + if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { check_non_exported_macro_for_invalid_attrs(self.tcx, item); } } diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 2bed8cadeb95d..b8ce973185c8d 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -244,11 +244,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { fn visit_attribute(&mut self, _: hir::HirId, attr: &'v ast::Attribute) { self.record("Attribute", Id::Attr(attr.id), attr); } - - fn visit_macro_def(&mut self, macro_def: &'v hir::MacroDef<'v>) { - self.record("MacroDef", Id::Node(macro_def.hir_id()), macro_def); - hir_visit::walk_macro_def(self, macro_def) - } } impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 8b3268257b165..9749518c2b425 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -539,19 +539,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { ); } - fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) { - self.annotate( - md.def_id, - md.span, - None, - AnnotationKind::Required, - InheritDeprecation::Yes, - InheritConstStability::No, - InheritStability::No, - |_| {}, - ); - } - fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) { let kind = match &p.kind { // Allow stability attributes on default generic arguments. diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3553baee8423b..ced0d22cbe473 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -642,7 +642,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { hir::ItemKind::Macro(ref macro_def) => { let def_id = item.def_id.to_def_id(); let is_macro_export = self.tcx.has_attr(def_id, sym::macro_export); - match (macro_def.ast.macro_rules, is_macro_export) { + match (macro_def.macro_rules, is_macro_export) { (true, true) => Some(AccessLevel::Public), (true, false) => None, (false, _) => { @@ -728,23 +728,22 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { // are reachable, since they might be exported transitively. // Non-opaque macros cannot make other items more accessible than they already are. - let attrs = self.tcx.hir().attrs(md.hir_id()); - if attr::find_transparency(&self.tcx.sess, &attrs, md.ast.macro_rules).0 + let attrs = self.tcx.hir().attrs(item.hir_id()); + if attr::find_transparency(&self.tcx.sess, &attrs, md.macro_rules).0 != Transparency::Opaque { return; } + let item_def_id = item.def_id.to_def_id(); let macro_module_def_id = - ty::DefIdTree::parent(self.tcx, md.def_id.to_def_id()).unwrap().expect_local(); + ty::DefIdTree::parent(self.tcx, item_def_id).unwrap().expect_local(); if self.tcx.hir().opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) { // The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252). return; } - let level = if md.vis.node.is_pub() { self.get(macro_module_def_id) } else { None }; - let new_level = self.update(md.def_id, level); - if new_level.is_none() { + if self.get(item.def_id).is_none() { return; } From c662241e60442defa508fbc05f1607c05e9e5ceb Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Wed, 18 Aug 2021 01:05:00 -0700 Subject: [PATCH 16/18] Eliminate `hir::MacroDef` (tools edition) --- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/doctest.rs | 2 +- src/librustdoc/visit_ast.rs | 2 +- src/tools/clippy/clippy_lints/src/utils/inspector.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e7ede6870cab3..39cffb4cee352 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1860,7 +1860,7 @@ impl Clean> for (&hir::Item<'_>, Option) { clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) } ItemKind::Macro(ref macro_def) => MacroItem(Macro { - source: display_macro_source(cx, name, ¯o_def.ast, def_id, &item.vis), + source: display_macro_source(cx, name, ¯o_def, def_id, &item.vis), imported_from: None, }), ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 9967f5d3e05fa..426f9718bc1a0 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1176,7 +1176,7 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx> // 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(); - if macro_def.ast.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { + if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { intravisit::walk_item(self, item); return; } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 3671b1770d02d..2c260c9a695ed 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -296,7 +296,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // should be inlined even if it is also documented at the top level. let def_id = item.def_id.to_def_id(); - let is_macro_2_0 = !macro_def.ast.macro_rules; + let is_macro_2_0 = !macro_def.macro_rules; let nonexported = !self.cx.tcx.has_attr(def_id, sym::macro_export); if is_macro_2_0 || nonexported || self.inlining { diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index ad4d4a64e936b..f9a284e89573b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -409,7 +409,7 @@ fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) { hir::ItemKind::Mod(..) => println!("module"), hir::ItemKind::ForeignMod { abi, .. } => println!("foreign module with abi: {}", abi), hir::ItemKind::Macro(ref macro_def) => { - if macro_def.ast.macro_rules { + if macro_def.macro_rules { println!("macro introduced by `macro_rules!`"); } else { println!("macro introduced by `macro`"); From 9dce366ee25b279a7f4c81f5194d259f6b53d555 Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Wed, 18 Aug 2021 01:12:18 -0700 Subject: [PATCH 17/18] Keep using syntactic visibility in rustdoc for now --- src/librustdoc/visit_ast.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 2c260c9a695ed..43cf94387add5 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::Node; use rustc_middle::middle::privacy::AccessLevel; -use rustc_middle::ty::{TyCtxt, Visibility}; +use rustc_middle::ty::TyCtxt; use rustc_span; use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_span::source_map::Spanned; @@ -228,7 +228,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { debug!("visiting item {:?}", item); let name = renamed.unwrap_or(item.ident.name); - let is_pub = self.cx.tcx.visibility(item.def_id) == Visibility::Public; + let def_id = item.def_id.to_def_id(); + let is_pub = item.vis.node.is_pub() || self.cx.tcx.has_attr(def_id, sym::macro_export); if is_pub { self.store_path(item.def_id.to_def_id()); From fc67af121b3b74780e65623f1f86d22c34ace736 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 18 Aug 2021 20:54:55 +0200 Subject: [PATCH 18/18] Do not reexport macros that are already at the crate root. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 +--- compiler/rustc_resolve/src/imports.rs | 22 ++++++++++++++++---- compiler/rustc_resolve/src/lib.rs | 4 ---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index e49a55be75bfe..f4b25dfc4a0b0 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1102,9 +1102,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let def_id = self.local_def_id(child_index); let res = Res::Def(kind, def_id); - if !kind.is_macro() { - callback(Export { res, ident, vis, span }); - } + callback(Export { res, ident, vis, span }); // For non-re-export structs and variants add their constructors to children. // Re-export lists automatically contain constructors when necessary. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index dfb6d89a0d126..7be264a9f2d89 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -16,7 +16,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::ptr_key::PtrKey; use rustc_errors::{pluralize, struct_span_err, Applicability}; use rustc_hir::def::{self, PartialRes}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_middle::hir::exports::Export; use rustc_middle::span_bug; use rustc_middle::ty; @@ -1392,9 +1392,23 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // 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() { - let res = binding.res().map_id(|id| this.local_def_id(id)); - if res != def::Res::Err { + let res = binding.res(); + if res == Res::Err { + // Do not insert failed resolutions. + return; + } else if is_good_import { + let res = res.map_id(|id| this.local_def_id(id)); + reexports.push(Export { ident, res, span: binding.span, vis: binding.vis }); + } else if let NameBindingKind::Res(Res::Def(def_kind, macro_def_id), true) = + binding.kind + { + let macro_is_at_root = macro_def_id + .as_local() + .and_then(|macro_def_id| this.definitions.def_key(macro_def_id).parent) + == Some(CRATE_DEF_INDEX); + // Insert a re-export at crate root for exported macro_rules defined elsewhere. + if module.parent.is_none() && !macro_is_at_root { + let res = def::Res::Def(def_kind, macro_def_id); reexports.push(Export { ident, res, span: binding.span, vis: binding.vis }); } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e308ea1a1be5b..7cbea6e88ccad 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -815,10 +815,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 { self.res().macro_kind() }