1
Fork 0

Auto merge of #80919 - cjgillot:defkey-span, r=oli-obk

Generate metadata by iterating on DefId instead of traversing the HIR tree 1/N

Sample from #80347.
This commit is contained in:
bors 2021-01-24 06:51:17 +00:00
commit 85e355ea9b
12 changed files with 304 additions and 264 deletions

View file

@ -419,6 +419,10 @@ impl Definitions {
pub fn add_parent_module_of_macro_def(&mut self, expn_id: ExpnId, module: DefId) { pub fn add_parent_module_of_macro_def(&mut self, expn_id: ExpnId, module: DefId) {
self.parent_modules_of_macro_defs.insert(expn_id, module); self.parent_modules_of_macro_defs.insert(expn_id, module);
} }
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
self.def_id_to_hir_id.iter_enumerated().map(|(k, _)| k)
}
} }
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]

View file

@ -618,43 +618,6 @@ impl MetadataBlob {
} }
} }
impl EntryKind {
fn def_kind(&self) -> DefKind {
match *self {
EntryKind::AnonConst(..) => DefKind::AnonConst,
EntryKind::Const(..) => DefKind::Const,
EntryKind::AssocConst(..) => DefKind::AssocConst,
EntryKind::ImmStatic
| EntryKind::MutStatic
| EntryKind::ForeignImmStatic
| EntryKind::ForeignMutStatic => DefKind::Static,
EntryKind::Struct(_, _) => DefKind::Struct,
EntryKind::Union(_, _) => DefKind::Union,
EntryKind::Fn(_) | EntryKind::ForeignFn(_) => DefKind::Fn,
EntryKind::AssocFn(_) => DefKind::AssocFn,
EntryKind::Type => DefKind::TyAlias,
EntryKind::TypeParam => DefKind::TyParam,
EntryKind::ConstParam => DefKind::ConstParam,
EntryKind::OpaqueTy => DefKind::OpaqueTy,
EntryKind::AssocType(_) => DefKind::AssocTy,
EntryKind::Mod(_) => DefKind::Mod,
EntryKind::Variant(_) => DefKind::Variant,
EntryKind::Trait(_) => DefKind::Trait,
EntryKind::TraitAlias => DefKind::TraitAlias,
EntryKind::Enum(..) => DefKind::Enum,
EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
EntryKind::ProcMacro(kind) => DefKind::Macro(kind),
EntryKind::ForeignType => DefKind::ForeignTy,
EntryKind::Impl(_) => DefKind::Impl,
EntryKind::Closure => DefKind::Closure,
EntryKind::ForeignMod => DefKind::ForeignMod,
EntryKind::GlobalAsm => DefKind::GlobalAsm,
EntryKind::Field => DefKind::Field,
EntryKind::Generator(_) => DefKind::Generator,
}
}
}
impl CrateRoot<'_> { impl CrateRoot<'_> {
crate fn is_proc_macro_crate(&self) -> bool { crate fn is_proc_macro_crate(&self) -> bool {
self.proc_macro_data.is_some() self.proc_macro_data.is_some()
@ -685,21 +648,6 @@ impl CrateRoot<'_> {
} }
impl<'a, 'tcx> CrateMetadataRef<'a> { impl<'a, 'tcx> CrateMetadataRef<'a> {
fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind> {
self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
}
fn kind(&self, item_id: DefIndex) -> EntryKind {
self.maybe_kind(item_id).unwrap_or_else(|| {
bug!(
"CrateMetadata::kind({:?}): id not found, in crate {:?} with number {}",
item_id,
self.root.name,
self.cnum,
)
})
}
fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro { fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro {
// DefIndex's in root.proc_macro_data have a one-to-one correspondence // DefIndex's in root.proc_macro_data have a one-to-one correspondence
// with items in 'raw_proc_macros'. // with items in 'raw_proc_macros'.
@ -736,8 +684,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.try_item_ident(item_index, sess).unwrap() self.try_item_ident(item_index, sess).unwrap()
} }
fn def_kind(&self, index: DefIndex) -> DefKind { fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind> {
self.kind(index).def_kind() self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
}
fn kind(&self, item_id: DefIndex) -> EntryKind {
self.maybe_kind(item_id).unwrap_or_else(|| {
bug!(
"CrateMetadata::kind({:?}): id not found, in crate {:?} with number {}",
item_id,
self.root.name,
self.cnum,
)
})
}
fn def_kind(&self, item_id: DefIndex) -> DefKind {
self.root.tables.def_kind.get(self, item_id).map(|k| k.decode(self)).unwrap_or_else(|| {
bug!(
"CrateMetadata::def_kind({:?}): id not found, in crate {:?} with number {}",
item_id,
self.root.name,
self.cnum,
)
})
} }
fn get_span(&self, index: DefIndex, sess: &Session) -> Span { fn get_span(&self, index: DefIndex, sess: &Session) -> Span {

View file

@ -130,7 +130,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
is_foreign_item => { cdata.is_foreign_item(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) }
static_mutability => { cdata.static_mutability(def_id.index) } static_mutability => { cdata.static_mutability(def_id.index) }
generator_kind => { cdata.generator_kind(def_id.index) } generator_kind => { cdata.generator_kind(def_id.index) }
def_kind => { cdata.def_kind(def_id.index) } opt_def_kind => { Some(cdata.def_kind(def_id.index)) }
def_span => { cdata.get_span(def_id.index, &tcx.sess) } def_span => { cdata.get_span(def_id.index, &tcx.sess) }
def_ident_span => { def_ident_span => {
cdata.try_item_ident(def_id.index, &tcx.sess).ok().map(|ident| ident.span) cdata.try_item_ident(def_id.index, &tcx.sess).ok().map(|ident| ident.span)

View file

@ -1,13 +1,12 @@
use crate::rmeta::table::{FixedSizeEncoding, TableBuilder}; use crate::rmeta::table::{FixedSizeEncoding, TableBuilder};
use crate::rmeta::*; use crate::rmeta::*;
use rustc_ast as ast;
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintEncoder}; use rustc_data_structures::fingerprint::{Fingerprint, FingerprintEncoder};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{join, Lrc}; use rustc_data_structures::sync::{join, Lrc};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind; use rustc_hir::def::{CtorOf, DefKind};
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::DefPathData; use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
@ -437,7 +436,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(hir::CRATE_HIR_ID, &krate.item.module, &krate.item.attrs); self.encode_info_for_mod(hir::CRATE_HIR_ID, &krate.item.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`
@ -580,6 +579,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode the items. // Encode the items.
i = self.position(); i = self.position();
self.encode_def_ids();
self.encode_info_for_items(); self.encode_info_for_items();
let item_bytes = self.position() - i; let item_bytes = self.position() - i;
@ -715,7 +715,107 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
} }
fn should_encode_visibility(def_kind: DefKind) -> bool {
match def_kind {
DefKind::Mod
| DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Variant
| DefKind::Trait
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
| DefKind::Fn
| DefKind::Const
| DefKind::Static
| DefKind::Ctor(..)
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::Macro(..)
| DefKind::Use
| DefKind::ForeignMod
| DefKind::OpaqueTy
| DefKind::Impl
| DefKind::Field => true,
DefKind::TyParam
| DefKind::ConstParam
| DefKind::LifetimeParam
| DefKind::AnonConst
| DefKind::GlobalAsm
| DefKind::Closure
| DefKind::Generator
| DefKind::ExternCrate => false,
}
}
fn should_encode_stability(def_kind: DefKind) -> bool {
match def_kind {
DefKind::Mod
| DefKind::Ctor(..)
| DefKind::Variant
| DefKind::Field
| DefKind::Struct
| DefKind::AssocTy
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::TyParam
| DefKind::ConstParam
| DefKind::Static
| DefKind::Const
| DefKind::Fn
| DefKind::ForeignMod
| DefKind::TyAlias
| DefKind::OpaqueTy
| DefKind::Enum
| DefKind::Union
| DefKind::Impl
| DefKind::Trait
| DefKind::TraitAlias
| DefKind::Macro(..)
| DefKind::ForeignTy => true,
DefKind::Use
| DefKind::LifetimeParam
| DefKind::AnonConst
| DefKind::GlobalAsm
| DefKind::Closure
| DefKind::Generator
| DefKind::ExternCrate => false,
}
}
impl EncodeContext<'a, 'tcx> { impl EncodeContext<'a, 'tcx> {
fn encode_def_ids(&mut self) {
if self.is_proc_macro {
return;
}
let tcx = self.tcx;
let hir = tcx.hir();
for local_id in hir.iter_local_def_id() {
let def_id = local_id.to_def_id();
let def_kind = tcx.opt_def_kind(local_id);
let def_kind = if let Some(def_kind) = def_kind { def_kind } else { continue };
record!(self.tables.def_kind[def_id] <- match def_kind {
// Replace Ctor by the enclosing object to avoid leaking details in children crates.
DefKind::Ctor(CtorOf::Struct, _) => DefKind::Struct,
DefKind::Ctor(CtorOf::Variant, _) => DefKind::Variant,
def_kind => def_kind,
});
record!(self.tables.span[def_id] <- tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- tcx.get_attrs(def_id));
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
if should_encode_visibility(def_kind) {
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
}
if should_encode_stability(def_kind) {
self.encode_stability(def_id);
self.encode_const_stability(def_id);
self.encode_deprecation(def_id);
}
}
}
fn encode_variances_of(&mut self, def_id: DefId) { fn encode_variances_of(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_variances_of({:?})", def_id); debug!("EncodeContext::encode_variances_of({:?})", def_id);
record!(self.tables.variances[def_id] <- &self.tcx.variances_of(def_id)[..]); record!(self.tables.variances[def_id] <- &self.tcx.variances_of(def_id)[..]);
@ -740,17 +840,11 @@ impl EncodeContext<'a, 'tcx> {
}; };
record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data))); record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| { record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
assert!(f.did.is_local()); assert!(f.did.is_local());
f.did.index f.did.index
})); }));
self.encode_ident_span(def_id, variant.ident); self.encode_ident_span(def_id, variant.ident);
self.encode_stability(def_id);
self.encode_deprecation(def_id);
self.encode_item_type(def_id); self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn { if variant.ctor_kind == CtorKind::Fn {
// FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`. // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
@ -780,10 +874,6 @@ impl EncodeContext<'a, 'tcx> {
}; };
record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data))); record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
self.encode_stability(def_id);
self.encode_deprecation(def_id);
self.encode_item_type(def_id); self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn { if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@ -799,7 +889,7 @@ impl EncodeContext<'a, 'tcx> {
self.encode_mir_for_ctfe(def_id.expect_local()); self.encode_mir_for_ctfe(def_id.expect_local());
} }
fn encode_info_for_mod(&mut self, id: hir::HirId, md: &hir::Mod<'_>, attrs: &[ast::Attribute]) { fn encode_info_for_mod(&mut self, id: hir::HirId, md: &hir::Mod<'_>) {
let tcx = self.tcx; let tcx = self.tcx;
let local_def_id = tcx.hir().local_def_id(id); let local_def_id = tcx.hir().local_def_id(id);
let def_id = local_def_id.to_def_id(); let def_id = local_def_id.to_def_id();
@ -832,9 +922,6 @@ impl EncodeContext<'a, 'tcx> {
}; };
record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data))); record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data)));
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- attrs);
if self.is_proc_macro { if self.is_proc_macro {
record!(self.tables.children[def_id] <- &[]); record!(self.tables.children[def_id] <- &[]);
} else { } else {
@ -842,8 +929,6 @@ impl EncodeContext<'a, 'tcx> {
tcx.hir().local_def_id(item_id.id).local_def_index tcx.hir().local_def_id(item_id.id).local_def_index
})); }));
} }
self.encode_stability(def_id);
self.encode_deprecation(def_id);
} }
fn encode_field( fn encode_field(
@ -852,24 +937,14 @@ impl EncodeContext<'a, 'tcx> {
variant_index: VariantIdx, variant_index: VariantIdx,
field_index: usize, field_index: usize,
) { ) {
let tcx = self.tcx;
let variant = &adt_def.variants[variant_index]; let variant = &adt_def.variants[variant_index];
let field = &variant.fields[field_index]; let field = &variant.fields[field_index];
let def_id = field.did; let def_id = field.did;
debug!("EncodeContext::encode_field({:?})", def_id); debug!("EncodeContext::encode_field({:?})", def_id);
let variant_id = tcx.hir().local_def_id_to_hir_id(variant.def_id.expect_local());
let variant_data = tcx.hir().expect_variant_data(variant_id);
record!(self.tables.kind[def_id] <- EntryKind::Field); record!(self.tables.kind[def_id] <- EntryKind::Field);
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- variant_data.fields()[field_index].attrs);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
self.encode_ident_span(def_id, field.ident); self.encode_ident_span(def_id, field.ident);
self.encode_stability(def_id);
self.encode_deprecation(def_id);
self.encode_item_type(def_id); self.encode_item_type(def_id);
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_explicit_predicates(def_id); self.encode_explicit_predicates(def_id);
@ -889,11 +964,6 @@ impl EncodeContext<'a, 'tcx> {
}; };
record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr)); record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr));
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
self.encode_stability(def_id);
self.encode_deprecation(def_id);
self.encode_item_type(def_id); self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn { if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@ -955,29 +1025,25 @@ impl EncodeContext<'a, 'tcx> {
hir::Defaultness::Final => span_bug!(ast_item.span, "traits cannot have final items"), hir::Defaultness::Final => span_bug!(ast_item.span, "traits cannot have final items"),
}; };
record!(self.tables.kind[def_id] <- match trait_item.kind { match trait_item.kind {
ty::AssocKind::Const => { ty::AssocKind::Const => {
let rendered = rustc_hir_pretty::to_string( let rendered = rustc_hir_pretty::to_string(
&(&self.tcx.hir() as &dyn intravisit::Map<'_>), &(&self.tcx.hir() as &dyn intravisit::Map<'_>),
|s| s.print_trait_item(ast_item) |s| s.print_trait_item(ast_item),
); );
let rendered_const = self.lazy(RenderedConst(rendered)); let rendered_const = self.lazy(RenderedConst(rendered));
EntryKind::AssocConst( record!(self.tables.kind[def_id] <- EntryKind::AssocConst(
container, container,
Default::default(), Default::default(),
rendered_const, rendered_const,
) ));
} }
ty::AssocKind::Fn => { ty::AssocKind::Fn => {
let fn_data = if let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind { let fn_data = if let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind {
let param_names = match *m { let param_names = match *m {
hir::TraitFn::Required(ref names) => { hir::TraitFn::Required(ref names) => self.encode_fn_param_names(names),
self.encode_fn_param_names(names) hir::TraitFn::Provided(body) => self.encode_fn_param_names_for_body(body),
}
hir::TraitFn::Provided(body) => {
self.encode_fn_param_names_for_body(body)
}
}; };
FnData { FnData {
asyncness: m_sig.header.asyncness, asyncness: m_sig.header.asyncness,
@ -987,24 +1053,18 @@ impl EncodeContext<'a, 'tcx> {
} else { } else {
bug!() bug!()
}; };
EntryKind::AssocFn(self.lazy(AssocFnData { record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
fn_data, fn_data,
container, container,
has_self: trait_item.fn_has_self_parameter, has_self: trait_item.fn_has_self_parameter,
})) })));
} }
ty::AssocKind::Type => { ty::AssocKind::Type => {
self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_bounds(def_id);
EntryKind::AssocType(container) record!(self.tables.kind[def_id] <- EntryKind::AssocType(container));
} }
}); }
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
record!(self.tables.span[def_id] <- ast_item.span);
record!(self.tables.attributes[def_id] <- ast_item.attrs);
self.encode_ident_span(def_id, ast_item.ident); self.encode_ident_span(def_id, ast_item.ident);
self.encode_stability(def_id);
self.encode_const_stability(def_id);
self.encode_deprecation(def_id);
match trait_item.kind { match trait_item.kind {
ty::AssocKind::Const | ty::AssocKind::Fn => { ty::AssocKind::Const | ty::AssocKind::Fn => {
self.encode_item_type(def_id); self.encode_item_type(def_id);
@ -1068,15 +1128,16 @@ impl EncodeContext<'a, 'tcx> {
} }
}; };
record!(self.tables.kind[def_id] <- match impl_item.kind { match impl_item.kind {
ty::AssocKind::Const => { ty::AssocKind::Const => {
if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind { if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id); let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
EntryKind::AssocConst( record!(self.tables.kind[def_id] <- EntryKind::AssocConst(
container, container,
qualifs, qualifs,
self.encode_rendered_const_for_body(body_id)) self.encode_rendered_const_for_body(body_id))
);
} else { } else {
bug!() bug!()
} }
@ -1091,21 +1152,17 @@ impl EncodeContext<'a, 'tcx> {
} else { } else {
bug!() bug!()
}; };
EntryKind::AssocFn(self.lazy(AssocFnData { record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
fn_data, fn_data,
container, container,
has_self: impl_item.fn_has_self_parameter, has_self: impl_item.fn_has_self_parameter,
})) })));
} }
ty::AssocKind::Type => EntryKind::AssocType(container) ty::AssocKind::Type => {
}); record!(self.tables.kind[def_id] <- EntryKind::AssocType(container));
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id)); }
record!(self.tables.span[def_id] <- ast_item.span); }
record!(self.tables.attributes[def_id] <- ast_item.attrs);
self.encode_ident_span(def_id, impl_item.ident); self.encode_ident_span(def_id, impl_item.ident);
self.encode_stability(def_id);
self.encode_const_stability(def_id);
self.encode_deprecation(def_id);
self.encode_item_type(def_id); self.encode_item_type(def_id);
if impl_item.kind == ty::AssocKind::Fn { if impl_item.kind == ty::AssocKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@ -1235,15 +1292,12 @@ impl EncodeContext<'a, 'tcx> {
self.encode_ident_span(def_id, item.ident); self.encode_ident_span(def_id, item.ident);
record!(self.tables.kind[def_id] <- match item.kind { let entry_kind = match item.kind {
hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic, hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic,
hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic, hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic,
hir::ItemKind::Const(_, body_id) => { hir::ItemKind::Const(_, body_id) => {
let qualifs = self.tcx.at(item.span).mir_const_qualif(def_id); let qualifs = self.tcx.at(item.span).mir_const_qualif(def_id);
EntryKind::Const( EntryKind::Const(qualifs, self.encode_rendered_const_for_body(body_id))
qualifs,
self.encode_rendered_const_for_body(body_id)
)
} }
hir::ItemKind::Fn(ref sig, .., body) => { hir::ItemKind::Fn(ref sig, .., body) => {
let data = FnData { let data = FnData {
@ -1255,7 +1309,7 @@ impl EncodeContext<'a, 'tcx> {
EntryKind::Fn(self.lazy(data)) EntryKind::Fn(self.lazy(data))
} }
hir::ItemKind::Mod(ref m) => { hir::ItemKind::Mod(ref m) => {
return self.encode_info_for_mod(item.hir_id, m, &item.attrs); return self.encode_info_for_mod(item.hir_id, m);
} }
hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod, hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod,
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm, hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
@ -1272,61 +1326,61 @@ impl EncodeContext<'a, 'tcx> {
// Encode def_ids for each field and method // Encode def_ids for each field and method
// for methods, write all the stuff get_trait_method // for methods, write all the stuff get_trait_method
// needs to know // needs to know
let ctor = struct_def.ctor_hir_id().map(|ctor_hir_id| { let ctor = struct_def
self.tcx.hir().local_def_id(ctor_hir_id).local_def_index .ctor_hir_id()
}); .map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index);
EntryKind::Struct(self.lazy(VariantData { EntryKind::Struct(
ctor_kind: variant.ctor_kind, self.lazy(VariantData {
discr: variant.discr, ctor_kind: variant.ctor_kind,
ctor, discr: variant.discr,
is_non_exhaustive: variant.is_field_list_non_exhaustive(), ctor,
}), adt_def.repr) is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}),
adt_def.repr,
)
} }
hir::ItemKind::Union(..) => { hir::ItemKind::Union(..) => {
let adt_def = self.tcx.adt_def(def_id); let adt_def = self.tcx.adt_def(def_id);
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
EntryKind::Union(self.lazy(VariantData { EntryKind::Union(
ctor_kind: variant.ctor_kind, self.lazy(VariantData {
discr: variant.discr, ctor_kind: variant.ctor_kind,
ctor: None, discr: variant.discr,
is_non_exhaustive: variant.is_field_list_non_exhaustive(), ctor: None,
}), adt_def.repr) is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}),
adt_def.repr,
)
} }
hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => { hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
let trait_ref = self.tcx.impl_trait_ref(def_id); let trait_ref = self.tcx.impl_trait_ref(def_id);
let polarity = self.tcx.impl_polarity(def_id); let polarity = self.tcx.impl_polarity(def_id);
let parent = if let Some(trait_ref) = trait_ref { let parent = if let Some(trait_ref) = trait_ref {
let trait_def = self.tcx.trait_def(trait_ref.def_id); let trait_def = self.tcx.trait_def(trait_ref.def_id);
trait_def.ancestors(self.tcx, def_id).ok() trait_def.ancestors(self.tcx, def_id).ok().and_then(|mut an| {
.and_then(|mut an| an.nth(1).and_then(|node| { an.nth(1).and_then(|node| match node {
match node { specialization_graph::Node::Impl(parent) => Some(parent),
specialization_graph::Node::Impl(parent) => Some(parent), _ => None,
_ => None, })
} })
}))
} else { } else {
None None
}; };
// if this is an impl of `CoerceUnsized`, create its // if this is an impl of `CoerceUnsized`, create its
// "unsized info", else just store None // "unsized info", else just store None
let coerce_unsized_info = let coerce_unsized_info = trait_ref.and_then(|t| {
trait_ref.and_then(|t| { if Some(t.def_id) == self.tcx.lang_items().coerce_unsized_trait() {
if Some(t.def_id) == self.tcx.lang_items().coerce_unsized_trait() { Some(self.tcx.at(item.span).coerce_unsized_info(def_id))
Some(self.tcx.at(item.span).coerce_unsized_info(def_id)) } else {
} else { None
None }
} });
});
let data = ImplData { let data =
polarity, ImplData { polarity, defaultness, parent_impl: parent, coerce_unsized_info };
defaultness,
parent_impl: parent,
coerce_unsized_info,
};
EntryKind::Impl(self.lazy(data)) EntryKind::Impl(self.lazy(data))
} }
@ -1343,13 +1397,11 @@ impl EncodeContext<'a, 'tcx> {
EntryKind::Trait(self.lazy(data)) EntryKind::Trait(self.lazy(data))
} }
hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias, hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias,
hir::ItemKind::ExternCrate(_) | hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item), bug!("cannot encode info for item {:?}", item)
}); }
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id)); };
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id)); record!(self.tables.kind[def_id] <- entry_kind);
record!(self.tables.attributes[def_id] <- item.attrs);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
// FIXME(eddyb) there should be a nicer way to do this. // FIXME(eddyb) there should be a nicer way to do this.
match item.kind { match item.kind {
hir::ItemKind::ForeignMod { items, .. } => record!(self.tables.children[def_id] <- hir::ItemKind::ForeignMod { items, .. } => record!(self.tables.children[def_id] <-
@ -1383,9 +1435,6 @@ impl EncodeContext<'a, 'tcx> {
} }
_ => {} _ => {}
} }
self.encode_stability(def_id);
self.encode_const_stability(def_id);
self.encode_deprecation(def_id);
match item.kind { match item.kind {
hir::ItemKind::Static(..) hir::ItemKind::Static(..)
| hir::ItemKind::Const(..) | hir::ItemKind::Const(..)
@ -1466,17 +1515,11 @@ impl EncodeContext<'a, 'tcx> {
fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) { fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) {
let def_id = self.tcx.hir().local_def_id(macro_def.hir_id).to_def_id(); let def_id = self.tcx.hir().local_def_id(macro_def.hir_id).to_def_id();
record!(self.tables.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone()))); record!(self.tables.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone())));
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
record!(self.tables.span[def_id] <- macro_def.span);
record!(self.tables.attributes[def_id] <- macro_def.attrs);
self.encode_ident_span(def_id, macro_def.ident); self.encode_ident_span(def_id, macro_def.ident);
self.encode_stability(def_id);
self.encode_deprecation(def_id);
} }
fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) { fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
record!(self.tables.kind[def_id] <- kind); record!(self.tables.kind[def_id] <- kind);
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
if encode_type { if encode_type {
self.encode_item_type(def_id); self.encode_item_type(def_id);
} }
@ -1490,18 +1533,18 @@ impl EncodeContext<'a, 'tcx> {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let ty = self.tcx.typeck(def_id).node_type(hir_id); let ty = self.tcx.typeck(def_id).node_type(hir_id);
record!(self.tables.kind[def_id.to_def_id()] <- match ty.kind() { match ty.kind() {
ty::Generator(..) => { ty::Generator(..) => {
let data = self.tcx.generator_kind(def_id).unwrap(); let data = self.tcx.generator_kind(def_id).unwrap();
EntryKind::Generator(data) record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Generator(data));
} }
ty::Closure(..) => EntryKind::Closure, ty::Closure(..) => {
record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Closure);
}
_ => bug!("closure that is neither generator nor closure"), _ => bug!("closure that is neither generator nor closure"),
}); }
record!(self.tables.span[def_id.to_def_id()] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id.to_def_id()] <- &self.tcx.get_attrs(def_id.to_def_id())[..]);
self.encode_item_type(def_id.to_def_id()); self.encode_item_type(def_id.to_def_id());
if let ty::Closure(def_id, substs) = *ty.kind() { if let ty::Closure(def_id, substs) = *ty.kind() {
record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig()); record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
@ -1525,7 +1568,6 @@ impl EncodeContext<'a, 'tcx> {
let qualifs = self.tcx.mir_const_qualif(def_id); let qualifs = self.tcx.mir_const_qualif(def_id);
record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst(qualifs, const_data)); record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst(qualifs, const_data));
record!(self.tables.span[def_id.to_def_id()] <- self.tcx.def_span(def_id));
self.encode_item_type(def_id.to_def_id()); self.encode_item_type(def_id.to_def_id());
self.encode_generics(def_id.to_def_id()); self.encode_generics(def_id.to_def_id());
self.encode_explicit_predicates(def_id.to_def_id()); self.encode_explicit_predicates(def_id.to_def_id());
@ -1575,6 +1617,15 @@ impl EncodeContext<'a, 'tcx> {
let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).copied(); let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).copied();
let macros = self.lazy(hir.krate().proc_macros.iter().map(|p| p.owner.local_def_index)); let macros = self.lazy(hir.krate().proc_macros.iter().map(|p| p.owner.local_def_index));
record!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod);
record!(self.tables.span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
record!(self.tables.attributes[LOCAL_CRATE.as_def_id()] <- tcx.get_attrs(LOCAL_CRATE.as_def_id()));
record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- tcx.visibility(LOCAL_CRATE.as_def_id()));
if let Some(stability) = stability {
record!(self.tables.stability[LOCAL_CRATE.as_def_id()] <- stability);
}
self.encode_deprecation(LOCAL_CRATE.as_def_id());
// Normally, this information is encoded when we walk the items // Normally, this information is encoded when we walk the items
// defined in this crate. However, we skip doing that for proc-macro crates, // defined in this crate. However, we skip doing that for proc-macro crates,
// so we manually encode just the information that we need // so we manually encode just the information that we need
@ -1606,6 +1657,7 @@ impl EncodeContext<'a, 'tcx> {
def_key.disambiguated_data.data = DefPathData::MacroNs(name); def_key.disambiguated_data.data = DefPathData::MacroNs(name);
let def_id = DefId::local(id); let def_id = DefId::local(id);
record!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind));
record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind)); record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
record!(self.tables.attributes[def_id] <- attrs); record!(self.tables.attributes[def_id] <- attrs);
record!(self.tables.def_keys[def_id] <- def_key); record!(self.tables.def_keys[def_id] <- def_key);
@ -1773,7 +1825,7 @@ impl EncodeContext<'a, 'tcx> {
debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id); debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id);
record!(self.tables.kind[def_id] <- match nitem.kind { match nitem.kind {
hir::ForeignItemKind::Fn(_, ref names, _) => { hir::ForeignItemKind::Fn(_, ref names, _) => {
let data = FnData { let data = FnData {
asyncness: hir::IsAsync::NotAsync, asyncness: hir::IsAsync::NotAsync,
@ -1784,19 +1836,19 @@ impl EncodeContext<'a, 'tcx> {
}, },
param_names: self.encode_fn_param_names(names), param_names: self.encode_fn_param_names(names),
}; };
EntryKind::ForeignFn(self.lazy(data)) record!(self.tables.kind[def_id] <- EntryKind::ForeignFn(self.lazy(data)));
} }
hir::ForeignItemKind::Static(_, hir::Mutability::Mut) => EntryKind::ForeignMutStatic, hir::ForeignItemKind::Static(_, hir::Mutability::Mut) => {
hir::ForeignItemKind::Static(_, hir::Mutability::Not) => EntryKind::ForeignImmStatic, record!(self.tables.kind[def_id] <- EntryKind::ForeignMutStatic);
hir::ForeignItemKind::Type => EntryKind::ForeignType, }
}); hir::ForeignItemKind::Static(_, hir::Mutability::Not) => {
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id)); record!(self.tables.kind[def_id] <- EntryKind::ForeignImmStatic);
record!(self.tables.span[def_id] <- nitem.span); }
record!(self.tables.attributes[def_id] <- nitem.attrs); hir::ForeignItemKind::Type => {
record!(self.tables.kind[def_id] <- EntryKind::ForeignType);
}
}
self.encode_ident_span(def_id, nitem.ident); self.encode_ident_span(def_id, nitem.ident);
self.encode_stability(def_id);
self.encode_const_stability(def_id);
self.encode_deprecation(def_id);
self.encode_item_type(def_id); self.encode_item_type(def_id);
self.encode_inherent_implementations(def_id); self.encode_inherent_implementations(def_id);
if let hir::ForeignItemKind::Fn(..) = nitem.kind { if let hir::ForeignItemKind::Fn(..) = nitem.kind {
@ -1862,15 +1914,12 @@ impl EncodeContext<'a, 'tcx> {
let def_id = self.tcx.hir().local_def_id(param.hir_id); let def_id = self.tcx.hir().local_def_id(param.hir_id);
match param.kind { match param.kind {
GenericParamKind::Lifetime { .. } => continue, GenericParamKind::Lifetime { .. } => continue,
GenericParamKind::Type { ref default, .. } => { GenericParamKind::Type { default, .. } => {
self.encode_info_for_generic_param( self.encode_info_for_generic_param(
def_id.to_def_id(), def_id.to_def_id(),
EntryKind::TypeParam, EntryKind::TypeParam,
default.is_some(), default.is_some(),
); );
if default.is_some() {
self.encode_stability(def_id.to_def_id());
}
} }
GenericParamKind::Const { .. } => { GenericParamKind::Const { .. } => {
self.encode_info_for_generic_param( self.encode_info_for_generic_param(

View file

@ -6,7 +6,7 @@ use rustc_attr as attr;
use rustc_data_structures::svh::Svh; use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::MetadataRef; use rustc_data_structures::sync::MetadataRef;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind; use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{DefId, DefIndex, DefPathHash}; use rustc_hir::def_id::{DefId, DefIndex, DefPathHash};
use rustc_hir::definitions::DefKey; use rustc_hir::definitions::DefKey;
use rustc_hir::lang_items; use rustc_hir::lang_items;
@ -279,6 +279,7 @@ macro_rules! define_tables {
} }
define_tables! { define_tables! {
def_kind: Table<DefIndex, Lazy<DefKind>>,
kind: Table<DefIndex, Lazy<EntryKind>>, kind: Table<DefIndex, Lazy<EntryKind>>,
visibility: Table<DefIndex, Lazy<ty::Visibility>>, visibility: Table<DefIndex, Lazy<ty::Visibility>>,
span: Table<DefIndex, Lazy<Span>>, span: Table<DefIndex, Lazy<Span>>,

View file

@ -1,7 +1,6 @@
use self::collector::NodeCollector; use self::collector::NodeCollector;
use crate::hir::{Owner, OwnerNodes}; use crate::hir::{Owner, OwnerNodes};
use crate::ty::query::Providers;
use crate::ty::TyCtxt; use crate::ty::TyCtxt;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::svh::Svh; use rustc_data_structures::svh::Svh;
@ -183,14 +182,18 @@ impl<'hir> Map<'hir> {
self.tcx.definitions.opt_local_def_id_to_hir_id(def_id) self.tcx.definitions.opt_local_def_id_to_hir_id(def_id)
} }
pub fn def_kind(&self, local_def_id: LocalDefId) -> DefKind { pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
self.tcx.definitions.iter_local_def_id()
}
pub fn opt_def_kind(&self, local_def_id: LocalDefId) -> Option<DefKind> {
// FIXME(eddyb) support `find` on the crate root. // FIXME(eddyb) support `find` on the crate root.
if local_def_id.to_def_id().index == CRATE_DEF_INDEX { if local_def_id.to_def_id().index == CRATE_DEF_INDEX {
return DefKind::Mod; return Some(DefKind::Mod);
} }
let hir_id = self.local_def_id_to_hir_id(local_def_id); let hir_id = self.local_def_id_to_hir_id(local_def_id);
match self.get(hir_id) { let def_kind = match self.find(hir_id)? {
Node::Item(item) => match item.kind { Node::Item(item) => match item.kind {
ItemKind::Static(..) => DefKind::Static, ItemKind::Static(..) => DefKind::Static,
ItemKind::Const(..) => DefKind::Const, ItemKind::Const(..) => DefKind::Const,
@ -249,6 +252,7 @@ impl<'hir> Map<'hir> {
GenericParamKind::Type { .. } => DefKind::TyParam, GenericParamKind::Type { .. } => DefKind::TyParam,
GenericParamKind::Const { .. } => DefKind::ConstParam, GenericParamKind::Const { .. } => DefKind::ConstParam,
}, },
Node::Crate(_) => DefKind::Mod,
Node::Stmt(_) Node::Stmt(_)
| Node::PathSegment(_) | Node::PathSegment(_)
| Node::Ty(_) | Node::Ty(_)
@ -260,9 +264,14 @@ impl<'hir> Map<'hir> {
| Node::Arm(_) | Node::Arm(_)
| Node::Lifetime(_) | Node::Lifetime(_)
| Node::Visibility(_) | Node::Visibility(_)
| Node::Block(_) | Node::Block(_) => return None,
| Node::Crate(_) => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)), };
} Some(def_kind)
}
pub fn def_kind(&self, local_def_id: LocalDefId) -> DefKind {
self.opt_def_kind(local_def_id)
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", local_def_id))
} }
fn find_entry(&self, id: HirId) -> Option<Entry<'hir>> { fn find_entry(&self, id: HirId) -> Option<Entry<'hir>> {
@ -514,9 +523,7 @@ impl<'hir> Map<'hir> {
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
pub fn find(&self, hir_id: HirId) -> Option<Node<'hir>> { pub fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
self.find_entry(hir_id).and_then(|entry| { self.find_entry(hir_id).map(|entry| entry.node)
if let Node::Crate(..) = entry.node { None } else { Some(entry.node) }
})
} }
/// Similar to `get_parent`; returns the parent HIR Id, or just `hir_id` if there /// Similar to `get_parent`; returns the parent HIR Id, or just `hir_id` if there
@ -848,50 +855,55 @@ impl<'hir> Map<'hir> {
/// Gets the span of the definition of the specified HIR node. /// Gets the span of the definition of the specified HIR node.
/// This is used by `tcx.get_span` /// This is used by `tcx.get_span`
pub fn span(&self, hir_id: HirId) -> Span { pub fn span(&self, hir_id: HirId) -> Span {
match self.find_entry(hir_id).map(|entry| entry.node) { self.opt_span(hir_id)
Some(Node::Param(param)) => param.span, .unwrap_or_else(|| bug!("hir::map::Map::span: id not in map: {:?}", hir_id))
Some(Node::Item(item)) => match &item.kind { }
pub fn opt_span(&self, hir_id: HirId) -> Option<Span> {
let span = match self.find_entry(hir_id)?.node {
Node::Param(param) => param.span,
Node::Item(item) => match &item.kind {
ItemKind::Fn(sig, _, _) => sig.span, ItemKind::Fn(sig, _, _) => sig.span,
_ => item.span, _ => item.span,
}, },
Some(Node::ForeignItem(foreign_item)) => foreign_item.span, Node::ForeignItem(foreign_item) => foreign_item.span,
Some(Node::TraitItem(trait_item)) => match &trait_item.kind { Node::TraitItem(trait_item) => match &trait_item.kind {
TraitItemKind::Fn(sig, _) => sig.span, TraitItemKind::Fn(sig, _) => sig.span,
_ => trait_item.span, _ => trait_item.span,
}, },
Some(Node::ImplItem(impl_item)) => match &impl_item.kind { Node::ImplItem(impl_item) => match &impl_item.kind {
ImplItemKind::Fn(sig, _) => sig.span, ImplItemKind::Fn(sig, _) => sig.span,
_ => impl_item.span, _ => impl_item.span,
}, },
Some(Node::Variant(variant)) => variant.span, Node::Variant(variant) => variant.span,
Some(Node::Field(field)) => field.span, Node::Field(field) => field.span,
Some(Node::AnonConst(constant)) => self.body(constant.body).value.span, Node::AnonConst(constant) => self.body(constant.body).value.span,
Some(Node::Expr(expr)) => expr.span, Node::Expr(expr) => expr.span,
Some(Node::Stmt(stmt)) => stmt.span, Node::Stmt(stmt) => stmt.span,
Some(Node::PathSegment(seg)) => seg.ident.span, Node::PathSegment(seg) => seg.ident.span,
Some(Node::Ty(ty)) => ty.span, Node::Ty(ty) => ty.span,
Some(Node::TraitRef(tr)) => tr.path.span, Node::TraitRef(tr) => tr.path.span,
Some(Node::Binding(pat)) => pat.span, Node::Binding(pat) => pat.span,
Some(Node::Pat(pat)) => pat.span, Node::Pat(pat) => pat.span,
Some(Node::Arm(arm)) => arm.span, Node::Arm(arm) => arm.span,
Some(Node::Block(block)) => block.span, Node::Block(block) => block.span,
Some(Node::Ctor(..)) => match self.find(self.get_parent_node(hir_id)) { Node::Ctor(..) => match self.find(self.get_parent_node(hir_id))? {
Some(Node::Item(item)) => item.span, Node::Item(item) => item.span,
Some(Node::Variant(variant)) => variant.span, Node::Variant(variant) => variant.span,
_ => unreachable!(), _ => unreachable!(),
}, },
Some(Node::Lifetime(lifetime)) => lifetime.span, Node::Lifetime(lifetime) => lifetime.span,
Some(Node::GenericParam(param)) => param.span, Node::GenericParam(param) => param.span,
Some(Node::Visibility(&Spanned { Node::Visibility(&Spanned {
node: VisibilityKind::Restricted { ref path, .. }, node: VisibilityKind::Restricted { ref path, .. },
.. ..
})) => path.span, }) => path.span,
Some(Node::Visibility(v)) => bug!("unexpected Visibility {:?}", v), Node::Visibility(v) => bug!("unexpected Visibility {:?}", v),
Some(Node::Local(local)) => local.span, Node::Local(local) => local.span,
Some(Node::MacroDef(macro_def)) => macro_def.span, Node::MacroDef(macro_def) => macro_def.span,
Some(Node::Crate(item)) => item.span, Node::Crate(item) => item.span,
None => bug!("hir::map::Map::span: id not in map: {:?}", hir_id), };
} Some(span)
} }
/// Like `hir.span()`, but includes the body of function items /// Like `hir.span()`, but includes the body of function items
@ -907,7 +919,7 @@ impl<'hir> Map<'hir> {
} }
pub fn span_if_local(&self, id: DefId) -> Option<Span> { pub fn span_if_local(&self, id: DefId) -> Option<Span> {
id.as_local().map(|id| self.span(self.local_def_id_to_hir_id(id))) id.as_local().and_then(|id| self.opt_span(self.local_def_id_to_hir_id(id)))
} }
pub fn res_span(&self, res: Res) -> Option<Span> { pub fn res_span(&self, res: Res) -> Option<Span> {
@ -1101,7 +1113,3 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String {
None => format!("unknown node{}", id_str), None => format!("unknown node{}", id_str),
} }
} }
pub fn provide(providers: &mut Providers) {
providers.def_kind = |tcx, def_id| tcx.hir().def_kind(def_id.expect_local());
}

View file

@ -15,6 +15,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE}; use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE};
use rustc_hir::*; use rustc_hir::*;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_span::DUMMY_SP;
pub struct Owner<'tcx> { pub struct Owner<'tcx> {
parent: HirId, parent: HirId,
@ -77,6 +78,7 @@ pub fn provide(providers: &mut Providers) {
}; };
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature; providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature;
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref(); providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref();
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
providers.fn_arg_names = |tcx, id| { providers.fn_arg_names = |tcx, id| {
let hir = tcx.hir(); let hir = tcx.hir();
let hir_id = hir.local_def_id_to_hir_id(id.expect_local()); let hir_id = hir.local_def_id_to_hir_id(id.expect_local());
@ -92,5 +94,5 @@ pub fn provide(providers: &mut Providers) {
span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", id); span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", id);
} }
}; };
map::provide(providers); providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local());
} }

View file

@ -878,7 +878,7 @@ rustc_queries! {
cache_on_disk_if { true } cache_on_disk_if { true }
} }
query def_kind(def_id: DefId) -> DefKind { query opt_def_kind(def_id: DefId) -> Option<DefKind> {
desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) }
} }

View file

@ -130,3 +130,19 @@ mod sealed {
} }
use sealed::IntoQueryParam; use sealed::IntoQueryParam;
impl TyCtxt<'tcx> {
pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
let def_id = def_id.into_query_param();
self.opt_def_kind(def_id)
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
}
}
impl TyCtxtAt<'tcx> {
pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
let def_id = def_id.into_query_param();
self.opt_def_kind(def_id)
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
}
}

View file

@ -307,6 +307,7 @@ impl<'tcx> ReachableContext<'tcx> {
| Node::Ctor(..) | Node::Ctor(..)
| Node::Field(_) | Node::Field(_)
| Node::Ty(_) | Node::Ty(_)
| Node::Crate(_)
| Node::MacroDef(_) => {} | Node::MacroDef(_) => {}
_ => { _ => {
bug!( bug!(

View file

@ -218,10 +218,6 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssociatedItems<'_> {
ty::AssociatedItems::new(items) ty::AssociatedItems::new(items)
} }
fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span {
tcx.hir().span_if_local(def_id).unwrap()
}
fn def_ident_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { fn def_ident_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
tcx.hir().get_if_local(def_id).and_then(|node| node.ident()).map(|ident| ident.span) tcx.hir().get_if_local(def_id).and_then(|node| node.ident()).map(|ident| ident.span)
} }
@ -495,7 +491,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
associated_item_def_ids, associated_item_def_ids,
associated_items, associated_items,
adt_sized_constraint, adt_sized_constraint,
def_span,
def_ident_span, def_ident_span,
param_env, param_env,
param_env_reveal_all_normalized, param_env_reveal_all_normalized,

View file

@ -109,14 +109,8 @@ LL | VEC.push(0);
note: mutable reference created due to call to this method note: mutable reference created due to call to this method
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
| |
LL | / pub fn push(&mut self, value: T) { LL | pub fn push(&mut self, value: T) {
LL | | // This will panic or abort if we would allocate > isize::MAX bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | | // or if the length increment would overflow for zero-sized types.
LL | | if self.len == self.buf.capacity() {
... |
LL | | }
LL | | }
| |_____^
note: `const` item defined here note: `const` item defined here
--> $DIR/lint-const-item-mutation.rs:31:1 --> $DIR/lint-const-item-mutation.rs:31:1
| |