From fee421685d9b29a7a865a13dc1c5a76816bcf417 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 25 Jul 2021 12:03:24 +0200 Subject: [PATCH] Introduce OwnerNode::Crate. --- compiler/rustc_ast_lowering/src/lib.rs | 6 +- compiler/rustc_hir/src/arena.rs | 1 + compiler/rustc_hir/src/hir.rs | 67 ++++++++++++------- compiler/rustc_hir/src/intravisit.rs | 3 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- .../rustc_middle/src/hir/map/collector.rs | 20 +----- compiler/rustc_passes/src/entry.rs | 2 +- compiler/rustc_passes/src/stability.rs | 4 +- .../rustc_save_analysis/src/dump_visitor.rs | 9 +-- src/librustdoc/clean/types.rs | 4 +- src/librustdoc/doctest.rs | 2 +- src/librustdoc/visit_ast.rs | 4 +- .../auxiliary/lint-for-crate-rpass.rs | 2 +- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 2 +- .../clippy/clippy_lints/src/missing_doc.rs | 2 +- 17 files changed, 69 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 540abe6e48e..57bf7be4056 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -512,8 +512,11 @@ 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.lower_mod(&c.items, 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)); + let body_ids = body_ids(&self.bodies); let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); @@ -548,7 +551,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let krate = hir::Crate { - item: module, non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs), owners: self.owners, bodies: self.bodies, diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 4e8cf009495..c4cff79f6c5 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -36,6 +36,7 @@ macro_rules! arena_types { [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>, [] path: rustc_hir::Path<$tcx>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f9b83f88ee4..23b28733e2a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,6 +1,6 @@ // ignore-tidy-filelength use crate::def::{CtorKind, DefKind, Res}; -use crate::def_id::DefId; +use crate::def_id::{DefId, CRATE_DEF_ID}; crate use crate::hir_id::{HirId, ItemLocalId}; use crate::{itemlikevisit, LangItem}; @@ -628,7 +628,6 @@ pub struct ModuleItems { /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #[derive(Debug)] pub struct Crate<'hir> { - pub item: Mod<'hir>, // Attributes from non-exported macros, kept only for collecting the library feature list. pub non_exported_macro_attrs: &'hir [Attribute], @@ -658,6 +657,10 @@ pub struct Crate<'hir> { } impl Crate<'hir> { + pub fn module(&self) -> &'hir Mod<'hir> { + if let Some(OwnerNode::Crate(m)) = self.owners[CRATE_DEF_ID] { m } else { panic!() } + } + pub fn item(&self, id: ItemId) -> &'hir Item<'hir> { self.owners[id.def_id].as_ref().unwrap().expect_item() } @@ -698,7 +701,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::MacroDef(_) | OwnerNode::Crate(_) => {} } } } @@ -713,7 +716,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(_)) | None => {} + Some(OwnerNode::MacroDef(_)) | Some(OwnerNode::Crate(_)) | None => {} }) } @@ -2943,16 +2946,29 @@ pub enum OwnerNode<'hir> { TraitItem(&'hir TraitItem<'hir>), ImplItem(&'hir ImplItem<'hir>), MacroDef(&'hir MacroDef<'hir>), + Crate(&'hir Mod<'hir>), } impl<'hir> OwnerNode<'hir> { - pub fn ident(&self) -> Ident { + pub fn ident(&self) -> Option { match self { OwnerNode::Item(Item { ident, .. }) | OwnerNode::ForeignItem(ForeignItem { ident, .. }) | OwnerNode::ImplItem(ImplItem { ident, .. }) | OwnerNode::TraitItem(TraitItem { ident, .. }) - | OwnerNode::MacroDef(MacroDef { ident, .. }) => *ident, + | OwnerNode::MacroDef(MacroDef { ident, .. }) => Some(*ident), + OwnerNode::Crate(..) => None, + } + } + + pub fn span(&self) -> Span { + match self { + OwnerNode::Item(Item { span, .. }) + | OwnerNode::ForeignItem(ForeignItem { span, .. }) + | OwnerNode::ImplItem(ImplItem { span, .. }) + | OwnerNode::TraitItem(TraitItem { span, .. }) + | OwnerNode::MacroDef(MacroDef { span, .. }) + | OwnerNode::Crate(Mod { inner: span, .. }) => *span, } } @@ -2997,56 +3013,42 @@ impl<'hir> OwnerNode<'hir> { | OwnerNode::ImplItem(ImplItem { def_id, .. }) | OwnerNode::ForeignItem(ForeignItem { def_id, .. }) | OwnerNode::MacroDef(MacroDef { def_id, .. }) => *def_id, + OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner, } } pub fn expect_item(self) -> &'hir Item<'hir> { match self { OwnerNode::Item(n) => n, - OwnerNode::ForeignItem(_) - | OwnerNode::ImplItem(_) - | OwnerNode::TraitItem(_) - | OwnerNode::MacroDef(_) => panic!(), + _ => panic!(), } } pub fn expect_foreign_item(self) -> &'hir ForeignItem<'hir> { match self { OwnerNode::ForeignItem(n) => n, - OwnerNode::Item(_) - | OwnerNode::ImplItem(_) - | OwnerNode::TraitItem(_) - | OwnerNode::MacroDef(_) => panic!(), + _ => panic!(), } } pub fn expect_impl_item(self) -> &'hir ImplItem<'hir> { match self { OwnerNode::ImplItem(n) => n, - OwnerNode::ForeignItem(_) - | OwnerNode::Item(_) - | OwnerNode::TraitItem(_) - | OwnerNode::MacroDef(_) => panic!(), + _ => panic!(), } } pub fn expect_trait_item(self) -> &'hir TraitItem<'hir> { match self { OwnerNode::TraitItem(n) => n, - OwnerNode::ForeignItem(_) - | OwnerNode::ImplItem(_) - | OwnerNode::Item(_) - | OwnerNode::MacroDef(_) => panic!(), + _ => panic!(), } } pub fn expect_macro_def(self) -> &'hir MacroDef<'hir> { match self { OwnerNode::MacroDef(n) => n, - OwnerNode::ForeignItem(_) - | OwnerNode::ImplItem(_) - | OwnerNode::TraitItem(_) - | OwnerNode::Item(_) => panic!(), + _ => panic!(), } } } @@ -3089,6 +3091,7 @@ impl<'hir> Into> for OwnerNode<'hir> { OwnerNode::ImplItem(n) => Node::ImplItem(n), OwnerNode::TraitItem(n) => Node::TraitItem(n), OwnerNode::MacroDef(n) => Node::MacroDef(n), + OwnerNode::Crate(n) => Node::Crate(n), } } } @@ -3221,6 +3224,18 @@ impl<'hir> Node<'hir> { _ => Constness::NotConst, } } + + pub fn as_owner(self) -> Option> { + match self { + Node::Item(i) => Some(OwnerNode::Item(i)), + 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, + } + } } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 83a4b2370d0..711b62c4a31 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -478,7 +478,8 @@ pub trait Visitor<'v>: Sized { /// Walks the contents of a crate. See also `Crate::visit_all_items`. pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) { - visitor.visit_mod(&krate.item, krate.item.inner, CRATE_HIR_ID); + 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 { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 5c1739b1ab9..4177c2f8d52 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -169,7 +169,7 @@ pub fn print_crate<'a>( // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. - s.print_mod(&krate.item, s.attrs(hir::CRATE_HIR_ID)); + s.print_mod(&krate.module(), s.attrs(hir::CRATE_HIR_ID)); s.print_remaining_comments(); s.s.eof() } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 7d87e708eae..b3c64b76820 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -568,7 +568,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) { - self.check_missing_docs_attrs(cx, hir::CRATE_HIR_ID, krate.item.inner, "the", "crate"); + self.check_missing_docs_attrs(cx, hir::CRATE_HIR_ID, krate.module().inner, "the", "crate"); for macro_def in krate.exported_macros() { // Non exported macros should be skipped, since `missing_docs` only diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e40c885fce9..45a4762c700 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -439,7 +439,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_items(&mut self) { let krate = self.tcx.hir().krate(); - self.encode_info_for_mod(CRATE_DEF_ID, &krate.item); + self.encode_info_for_mod(CRATE_DEF_ID, krate.module()); // Proc-macro crates only export proc-macro items, which are looked // up using `proc_macro_data` diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index be8863be627..09060169c5f 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -77,23 +77,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { definitions: &'a definitions::Definitions, mut hcx: StableHashingContext<'a>, ) -> NodeCollector<'a, 'hir> { - let hash = { - let Crate { - ref item, - // These fields are handled separately: - non_exported_macro_attrs: _, - owners: _, - trait_impls: _, - bodies: _, - body_ids: _, - modules: _, - proc_macros: _, - trait_map: _, - attrs: _, - } = *krate; - - hash_body(&mut hcx, item) - }; + let hash = hash_body(&mut hcx, krate.module()); let mut collector = NodeCollector { arena, @@ -108,7 +92,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { }; collector.insert_entry( hir::CRATE_HIR_ID, - Entry { parent: hir::CRATE_HIR_ID, node: Node::Crate(&krate.item) }, + Entry { parent: hir::CRATE_HIR_ID, node: Node::Crate(&krate.module()) }, hash, ); diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 550f4f148fd..876edbd1f6d 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -183,7 +183,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De } fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) { - let sp = tcx.hir().krate().item.inner; + let sp = tcx.hir().krate().module().inner; if *tcx.sess.parse_sess.reached_eof.borrow() { // There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about // the missing `fn main()` then as it might have been hidden inside an unclosed block. diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 42a4753c29c..3db0409d8f0 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -732,7 +732,7 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> { annotator.annotate( hir::CRATE_HIR_ID, - krate.item.inner, + krate.module().inner, None, AnnotationKind::Required, InheritDeprecation::Yes, @@ -929,7 +929,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { if tcx.stability().staged_api[&LOCAL_CRATE] { let krate = tcx.hir().krate(); let mut missing = MissingStabilityAnnotations { tcx, access_levels }; - missing.check_missing_stability(hir::CRATE_HIR_ID, krate.item.inner); + missing.check_missing_stability(hir::CRATE_HIR_ID, krate.module().inner); intravisit::walk_crate(&mut missing, krate); krate.visit_all_item_likes(&mut missing.as_deep_visitor()); } diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index 842f7f9deee..4f8dc7d16d4 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -146,7 +146,7 @@ impl<'tcx> DumpVisitor<'tcx> { }, crate_root: crate_root.unwrap_or_else(|| "".to_owned()), external_crates: self.save_ctxt.get_external_crates(), - span: self.span_from_span(krate.item.inner), + span: self.span_from_span(krate.module().inner), }; self.dumper.crate_prelude(data); @@ -1092,11 +1092,12 @@ impl<'tcx> DumpVisitor<'tcx> { format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id(id).to_def_id())); let sm = self.tcx.sess.source_map(); - let filename = sm.span_to_filename(krate.item.inner); + let krate_mod = krate.module(); + let filename = sm.span_to_filename(krate_mod.inner); let data_id = id_from_hir_id(id, &self.save_ctxt); let children = - krate.item.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect(); - let span = self.span_from_span(krate.item.inner); + krate_mod.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect(); + let span = self.span_from_span(krate_mod.inner); let attrs = self.tcx.hir().attrs(id); self.dumper.dump_def( diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2fd2d14bcab..101d3b400c3 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -227,7 +227,7 @@ impl ExternalCrate { if root.is_local() { tcx.hir() .krate() - .item + .module() .item_ids .iter() .filter_map(|&id| { @@ -293,7 +293,7 @@ impl ExternalCrate { if root.is_local() { tcx.hir() .krate() - .item + .module() .item_ids .iter() .filter_map(|&id| { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index b45e84aff8c..d5268abeec7 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -144,7 +144,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { hir_collector.visit_testable( "".to_string(), CRATE_HIR_ID, - krate.item.inner, + krate.module().inner, |this| { intravisit::walk_crate(this, krate); }, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 3621a6cb7d8..d74b3b46272 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -72,11 +72,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> { - let span = krate.item.inner; + let span = krate.module().inner; let mut top_level_module = self.visit_mod_contents( &Spanned { span, node: hir::VisibilityKind::Public }, hir::CRATE_HIR_ID, - &krate.item, + &krate.module(), self.cx.tcx.crate_name(LOCAL_CRATE), ); // Attach the crate's exported macros to the top-level module. diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index 51cea4f6ba9..1f494e44484 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -33,7 +33,7 @@ macro_rules! fake_lint_pass { if !cx.sess().contains_name(attrs, $attr) { cx.lint(CRATE_NOT_OKAY, |lint| { let msg = format!("crate is not marked with #![{}]", $attr); - lint.build(&msg).set_span(krate.item.inner).emit() + lint.build(&msg).set_span(krate.module().inner).emit() }); } )* diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index ef5353e6d8c..122a544e9d4 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -31,7 +31,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass { if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) { cx.lint(CRATE_NOT_OKAY, |lint| { lint.build("crate is not marked with #![crate_okay]") - .set_span(krate.item.inner) + .set_span(krate.module().inner) .emit() }); } diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index a46a7407df0..6ad702f8eaf 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) { let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); - self.check_missing_docs_attrs(cx, attrs, krate.item.inner, "the", "crate"); + self.check_missing_docs_attrs(cx, attrs, krate.module().inner, "the", "crate"); } fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {