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 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,

View File

@ -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>,

View File

@ -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<Ident> {
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<Node<'hir>> 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<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.

View File

@ -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 {

View File

@ -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()
}

View File

@ -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

View File

@ -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`

View File

@ -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,
);

View File

@ -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.

View File

@ -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());
}

View File

@ -146,7 +146,7 @@ impl<'tcx> DumpVisitor<'tcx> {
},
crate_root: crate_root.unwrap_or_else(|| "<no source>".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(

View File

@ -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| {

View File

@ -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);
},

View File

@ -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.

View File

@ -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()
});
}
)*

View File

@ -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()
});
}

View File

@ -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<'_>) {