Introduce OwnerNode::Crate.

This commit is contained in:
Camille GILLOT 2021-07-25 12:03:24 +02:00
parent 36a28060f1
commit fee421685d
17 changed files with 69 additions and 65 deletions

View File

@ -512,8 +512,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c); visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c);
visit::walk_crate(&mut item::ItemLowerer { 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.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 body_ids = body_ids(&self.bodies);
let proc_macros = let proc_macros =
c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); 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 { let krate = hir::Crate {
item: module,
non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs), non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
owners: self.owners, owners: self.owners,
bodies: self.bodies, bodies: self.bodies,

View File

@ -36,6 +36,7 @@ macro_rules! arena_types {
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, [few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
[] local: rustc_hir::Local<$tcx>, [] local: rustc_hir::Local<$tcx>,
[few] macro_def: rustc_hir::MacroDef<$tcx>, [few] macro_def: rustc_hir::MacroDef<$tcx>,
[few] mod_: rustc_hir::Mod<$tcx>,
[] param: rustc_hir::Param<$tcx>, [] param: rustc_hir::Param<$tcx>,
[] pat: rustc_hir::Pat<$tcx>, [] pat: rustc_hir::Pat<$tcx>,
[] path: rustc_hir::Path<$tcx>, [] path: rustc_hir::Path<$tcx>,

View File

@ -1,6 +1,6 @@
// ignore-tidy-filelength // ignore-tidy-filelength
use crate::def::{CtorKind, DefKind, Res}; 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}; crate use crate::hir_id::{HirId, ItemLocalId};
use crate::{itemlikevisit, LangItem}; use crate::{itemlikevisit, LangItem};
@ -628,7 +628,6 @@ pub struct ModuleItems {
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
#[derive(Debug)] #[derive(Debug)]
pub struct Crate<'hir> { pub struct Crate<'hir> {
pub item: Mod<'hir>,
// Attributes from non-exported macros, kept only for collecting the library feature list. // Attributes from non-exported macros, kept only for collecting the library feature list.
pub non_exported_macro_attrs: &'hir [Attribute], pub non_exported_macro_attrs: &'hir [Attribute],
@ -658,6 +657,10 @@ pub struct Crate<'hir> {
} }
impl 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> { pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
self.owners[id.def_id].as_ref().unwrap().expect_item() 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::ForeignItem(item) => visitor.visit_foreign_item(item),
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item), OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
OwnerNode::TraitItem(item) => visitor.visit_trait_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::ForeignItem(item)) => visitor.visit_foreign_item(item),
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item), Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_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>), TraitItem(&'hir TraitItem<'hir>),
ImplItem(&'hir ImplItem<'hir>), ImplItem(&'hir ImplItem<'hir>),
MacroDef(&'hir MacroDef<'hir>), MacroDef(&'hir MacroDef<'hir>),
Crate(&'hir Mod<'hir>),
} }
impl<'hir> OwnerNode<'hir> { impl<'hir> OwnerNode<'hir> {
pub fn ident(&self) -> Ident { pub fn ident(&self) -> Option<Ident> {
match self { match self {
OwnerNode::Item(Item { ident, .. }) OwnerNode::Item(Item { ident, .. })
| OwnerNode::ForeignItem(ForeignItem { ident, .. }) | OwnerNode::ForeignItem(ForeignItem { ident, .. })
| OwnerNode::ImplItem(ImplItem { ident, .. }) | OwnerNode::ImplItem(ImplItem { ident, .. })
| OwnerNode::TraitItem(TraitItem { 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::ImplItem(ImplItem { def_id, .. })
| OwnerNode::ForeignItem(ForeignItem { def_id, .. }) | OwnerNode::ForeignItem(ForeignItem { def_id, .. })
| OwnerNode::MacroDef(MacroDef { def_id, .. }) => *def_id, | OwnerNode::MacroDef(MacroDef { def_id, .. }) => *def_id,
OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
} }
} }
pub fn expect_item(self) -> &'hir Item<'hir> { pub fn expect_item(self) -> &'hir Item<'hir> {
match self { match self {
OwnerNode::Item(n) => n, OwnerNode::Item(n) => n,
OwnerNode::ForeignItem(_) _ => panic!(),
| OwnerNode::ImplItem(_)
| OwnerNode::TraitItem(_)
| OwnerNode::MacroDef(_) => panic!(),
} }
} }
pub fn expect_foreign_item(self) -> &'hir ForeignItem<'hir> { pub fn expect_foreign_item(self) -> &'hir ForeignItem<'hir> {
match self { match self {
OwnerNode::ForeignItem(n) => n, OwnerNode::ForeignItem(n) => n,
OwnerNode::Item(_) _ => panic!(),
| OwnerNode::ImplItem(_)
| OwnerNode::TraitItem(_)
| OwnerNode::MacroDef(_) => panic!(),
} }
} }
pub fn expect_impl_item(self) -> &'hir ImplItem<'hir> { pub fn expect_impl_item(self) -> &'hir ImplItem<'hir> {
match self { match self {
OwnerNode::ImplItem(n) => n, OwnerNode::ImplItem(n) => n,
OwnerNode::ForeignItem(_) _ => panic!(),
| OwnerNode::Item(_)
| OwnerNode::TraitItem(_)
| OwnerNode::MacroDef(_) => panic!(),
} }
} }
pub fn expect_trait_item(self) -> &'hir TraitItem<'hir> { pub fn expect_trait_item(self) -> &'hir TraitItem<'hir> {
match self { match self {
OwnerNode::TraitItem(n) => n, OwnerNode::TraitItem(n) => n,
OwnerNode::ForeignItem(_) _ => panic!(),
| OwnerNode::ImplItem(_)
| OwnerNode::Item(_)
| OwnerNode::MacroDef(_) => panic!(),
} }
} }
pub fn expect_macro_def(self) -> &'hir MacroDef<'hir> { pub fn expect_macro_def(self) -> &'hir MacroDef<'hir> {
match self { match self {
OwnerNode::MacroDef(n) => n, OwnerNode::MacroDef(n) => n,
OwnerNode::ForeignItem(_) _ => panic!(),
| OwnerNode::ImplItem(_)
| OwnerNode::TraitItem(_)
| OwnerNode::Item(_) => panic!(),
} }
} }
} }
@ -3089,6 +3091,7 @@ impl<'hir> Into<Node<'hir>> for OwnerNode<'hir> {
OwnerNode::ImplItem(n) => Node::ImplItem(n), OwnerNode::ImplItem(n) => Node::ImplItem(n),
OwnerNode::TraitItem(n) => Node::TraitItem(n), OwnerNode::TraitItem(n) => Node::TraitItem(n),
OwnerNode::MacroDef(n) => Node::MacroDef(n), OwnerNode::MacroDef(n) => Node::MacroDef(n),
OwnerNode::Crate(n) => Node::Crate(n),
} }
} }
} }
@ -3221,6 +3224,18 @@ impl<'hir> Node<'hir> {
_ => Constness::NotConst, _ => Constness::NotConst,
} }
} }
pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
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. // Some nodes are used a lot. Make sure they don't unintentionally get bigger.

View File

@ -478,7 +478,8 @@ pub trait Visitor<'v>: Sized {
/// Walks the contents of a crate. See also `Crate::visit_all_items`. /// 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>) { 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()); walk_list!(visitor, visit_macro_def, krate.exported_macros());
for (&id, attrs) in krate.attrs.iter() { for (&id, attrs) in krate.attrs.iter() {
for a in *attrs { for a in *attrs {

View File

@ -169,7 +169,7 @@ pub fn print_crate<'a>(
// When printing the AST, we sometimes need to inject `#[no_std]` here. // When printing the AST, we sometimes need to inject `#[no_std]` here.
// Since you can't compile the HIR, it's not necessary. // 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.print_remaining_comments();
s.s.eof() s.s.eof()
} }

View File

@ -568,7 +568,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
} }
fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) { 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() { for macro_def in krate.exported_macros() {
// Non exported macros should be skipped, since `missing_docs` only // Non exported macros should be skipped, since `missing_docs` only

View File

@ -439,7 +439,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_info_for_items(&mut self) { fn encode_info_for_items(&mut self) {
let krate = self.tcx.hir().krate(); 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 // Proc-macro crates only export proc-macro items, which are looked
// up using `proc_macro_data` // up using `proc_macro_data`

View File

@ -77,23 +77,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
definitions: &'a definitions::Definitions, definitions: &'a definitions::Definitions,
mut hcx: StableHashingContext<'a>, mut hcx: StableHashingContext<'a>,
) -> NodeCollector<'a, 'hir> { ) -> NodeCollector<'a, 'hir> {
let hash = { let hash = hash_body(&mut hcx, krate.module());
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 mut collector = NodeCollector { let mut collector = NodeCollector {
arena, arena,
@ -108,7 +92,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
}; };
collector.insert_entry( collector.insert_entry(
hir::CRATE_HIR_ID, 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, hash,
); );

View File

@ -183,7 +183,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
} }
fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) { 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() { if *tcx.sess.parse_sess.reached_eof.borrow() {
// There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about // 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. // the missing `fn main()` then as it might have been hidden inside an unclosed block.

View File

@ -732,7 +732,7 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
annotator.annotate( annotator.annotate(
hir::CRATE_HIR_ID, hir::CRATE_HIR_ID,
krate.item.inner, krate.module().inner,
None, None,
AnnotationKind::Required, AnnotationKind::Required,
InheritDeprecation::Yes, InheritDeprecation::Yes,
@ -929,7 +929,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
if tcx.stability().staged_api[&LOCAL_CRATE] { if tcx.stability().staged_api[&LOCAL_CRATE] {
let krate = tcx.hir().krate(); let krate = tcx.hir().krate();
let mut missing = MissingStabilityAnnotations { tcx, access_levels }; 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); intravisit::walk_crate(&mut missing, krate);
krate.visit_all_item_likes(&mut missing.as_deep_visitor()); krate.visit_all_item_likes(&mut missing.as_deep_visitor());
} }

View File

@ -146,7 +146,7 @@ impl<'tcx> DumpVisitor<'tcx> {
}, },
crate_root: crate_root.unwrap_or_else(|| "<no source>".to_owned()), crate_root: crate_root.unwrap_or_else(|| "<no source>".to_owned()),
external_crates: self.save_ctxt.get_external_crates(), 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); 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())); format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id(id).to_def_id()));
let sm = self.tcx.sess.source_map(); 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 data_id = id_from_hir_id(id, &self.save_ctxt);
let children = let children =
krate.item.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect(); 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.item.inner); let span = self.span_from_span(krate_mod.inner);
let attrs = self.tcx.hir().attrs(id); let attrs = self.tcx.hir().attrs(id);
self.dumper.dump_def( self.dumper.dump_def(

View File

@ -227,7 +227,7 @@ impl ExternalCrate {
if root.is_local() { if root.is_local() {
tcx.hir() tcx.hir()
.krate() .krate()
.item .module()
.item_ids .item_ids
.iter() .iter()
.filter_map(|&id| { .filter_map(|&id| {
@ -293,7 +293,7 @@ impl ExternalCrate {
if root.is_local() { if root.is_local() {
tcx.hir() tcx.hir()
.krate() .krate()
.item .module()
.item_ids .item_ids
.iter() .iter()
.filter_map(|&id| { .filter_map(|&id| {

View File

@ -144,7 +144,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
hir_collector.visit_testable( hir_collector.visit_testable(
"".to_string(), "".to_string(),
CRATE_HIR_ID, CRATE_HIR_ID,
krate.item.inner, krate.module().inner,
|this| { |this| {
intravisit::walk_crate(this, krate); intravisit::walk_crate(this, krate);
}, },

View File

@ -72,11 +72,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
} }
crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'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( let mut top_level_module = self.visit_mod_contents(
&Spanned { span, node: hir::VisibilityKind::Public }, &Spanned { span, node: hir::VisibilityKind::Public },
hir::CRATE_HIR_ID, hir::CRATE_HIR_ID,
&krate.item, &krate.module(),
self.cx.tcx.crate_name(LOCAL_CRATE), self.cx.tcx.crate_name(LOCAL_CRATE),
); );
// Attach the crate's exported macros to the top-level module. // Attach the crate's exported macros to the top-level module.

View File

@ -33,7 +33,7 @@ macro_rules! fake_lint_pass {
if !cx.sess().contains_name(attrs, $attr) { if !cx.sess().contains_name(attrs, $attr) {
cx.lint(CRATE_NOT_OKAY, |lint| { cx.lint(CRATE_NOT_OKAY, |lint| {
let msg = format!("crate is not marked with #![{}]", $attr); 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()
}); });
} }
)* )*

View File

@ -31,7 +31,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) { if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) {
cx.lint(CRATE_NOT_OKAY, |lint| { cx.lint(CRATE_NOT_OKAY, |lint| {
lint.build("crate is not marked with #![crate_okay]") lint.build("crate is not marked with #![crate_okay]")
.set_span(krate.item.inner) .set_span(krate.module().inner)
.emit() .emit()
}); });
} }

View File

@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) { fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); 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<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {