1
Fork 0

Auto merge of #79353 - cjgillot:procmacro, r=petrochenkov

Setup proc-macro metadata at encoding instead of decoding

This should improve the common non-proc-macro case for metadata decoding.
This commit is contained in:
bors 2020-11-28 03:20:09 +00:00
commit f8e5209a21
3 changed files with 62 additions and 67 deletions

View file

@ -644,6 +644,7 @@ impl EntryKind {
EntryKind::TraitAlias => DefKind::TraitAlias, EntryKind::TraitAlias => DefKind::TraitAlias,
EntryKind::Enum(..) => DefKind::Enum, EntryKind::Enum(..) => DefKind::Enum,
EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang), EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
EntryKind::ProcMacro(kind) => DefKind::Macro(kind),
EntryKind::ForeignType => DefKind::ForeignTy, EntryKind::ForeignType => DefKind::ForeignTy,
EntryKind::Impl(_) => DefKind::Impl, EntryKind::Impl(_) => DefKind::Impl,
EntryKind::Closure => DefKind::Closure, EntryKind::Closure => DefKind::Closure,
@ -685,20 +686,11 @@ impl CrateRoot<'_> {
} }
impl<'a, 'tcx> CrateMetadataRef<'a> { impl<'a, 'tcx> CrateMetadataRef<'a> {
fn is_proc_macro(&self, id: DefIndex) -> bool {
self.root
.proc_macro_data
.as_ref()
.and_then(|data| data.macros.decode(self).find(|x| *x == id))
.is_some()
}
fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind> { fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind> {
self.root.tables.kind.get(self, item_id).map(|k| k.decode(self)) self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
} }
fn kind(&self, item_id: DefIndex) -> EntryKind { fn kind(&self, item_id: DefIndex) -> EntryKind {
assert!(!self.is_proc_macro(item_id));
self.maybe_kind(item_id).unwrap_or_else(|| { self.maybe_kind(item_id).unwrap_or_else(|| {
bug!( bug!(
"CrateMetadata::kind({:?}): id not found, in crate {:?} with number {}", "CrateMetadata::kind({:?}): id not found, in crate {:?} with number {}",
@ -725,35 +717,24 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
fn item_ident(&self, item_index: DefIndex, sess: &Session) -> Ident { fn item_ident(&self, item_index: DefIndex, sess: &Session) -> Ident {
if !self.is_proc_macro(item_index) { let name = self
let name = self .def_key(item_index)
.def_key(item_index) .disambiguated_data
.disambiguated_data .data
.data .get_opt_name()
.get_opt_name() .expect("no name in item_ident");
.expect("no name in item_ident"); let span = self
let span = self .root
.root .tables
.tables .ident_span
.ident_span .get(self, item_index)
.get(self, item_index) .map(|data| data.decode((self, sess)))
.map(|data| data.decode((self, sess))) .unwrap_or_else(|| panic!("Missing ident span for {:?} ({:?})", name, item_index));
.unwrap_or_else(|| panic!("Missing ident span for {:?} ({:?})", name, item_index)); Ident::new(name, span)
Ident::new(name, span)
} else {
Ident::new(
Symbol::intern(self.raw_proc_macro(item_index).name()),
self.get_span(item_index, sess),
)
}
} }
fn def_kind(&self, index: DefIndex) -> DefKind { fn def_kind(&self, index: DefIndex) -> DefKind {
if !self.is_proc_macro(index) { self.kind(index).def_kind()
self.kind(index).def_kind()
} else {
DefKind::Macro(macro_kind(self.raw_proc_macro(index)))
}
} }
fn get_span(&self, index: DefIndex, sess: &Session) -> Span { fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
@ -956,10 +937,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> { fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
match self.is_proc_macro(id) { self.root.tables.stability.get(self, id).map(|stab| stab.decode(self))
true => self.root.proc_macro_data.as_ref().unwrap().stability,
false => self.root.tables.stability.get(self, id).map(|stab| stab.decode(self)),
}
} }
fn get_const_stability(&self, id: DefIndex) -> Option<attr::ConstStability> { fn get_const_stability(&self, id: DefIndex) -> Option<attr::ConstStability> {
@ -967,19 +945,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> { fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
self.root self.root.tables.deprecation.get(self, id).map(|depr| depr.decode(self))
.tables
.deprecation
.get(self, id)
.filter(|_| !self.is_proc_macro(id))
.map(|depr| depr.decode(self))
} }
fn get_visibility(&self, id: DefIndex) -> ty::Visibility { fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
match self.is_proc_macro(id) { self.root.tables.visibility.get(self, id).unwrap().decode(self)
true => ty::Visibility::Public,
false => self.root.tables.visibility.get(self, id).unwrap().decode(self),
}
} }
fn get_impl_data(&self, id: DefIndex) -> ImplData { fn get_impl_data(&self, id: DefIndex) -> ImplData {
@ -1191,7 +1161,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
fn is_item_mir_available(&self, id: DefIndex) -> bool { fn is_item_mir_available(&self, id: DefIndex) -> bool {
!self.is_proc_macro(id) && self.root.tables.mir.get(self, id).is_some() self.root.tables.mir.get(self, id).is_some()
} }
fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId { fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId {
@ -1207,7 +1177,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables .tables
.mir .mir
.get(self, id) .get(self, id)
.filter(|_| !self.is_proc_macro(id))
.unwrap_or_else(|| { .unwrap_or_else(|| {
bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id)) bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id))
}) })
@ -1223,7 +1192,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables .tables
.mir_abstract_consts .mir_abstract_consts
.get(self, id) .get(self, id)
.filter(|_| !self.is_proc_macro(id))
.map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx))))) .map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx)))))
} }
@ -1232,7 +1200,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables .tables
.unused_generic_params .unused_generic_params
.get(self, id) .get(self, id)
.filter(|_| !self.is_proc_macro(id))
.map(|params| params.decode(self)) .map(|params| params.decode(self))
.unwrap_or_default() .unwrap_or_default()
} }
@ -1242,7 +1209,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.tables .tables
.promoted_mir .promoted_mir
.get(self, id) .get(self, id)
.filter(|_| !self.is_proc_macro(id))
.unwrap_or_else(|| { .unwrap_or_else(|| {
bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id)) bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id))
}) })
@ -1546,14 +1512,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
#[inline] #[inline]
fn def_key(&self, index: DefIndex) -> DefKey { fn def_key(&self, index: DefIndex) -> DefKey {
*self.def_key_cache.lock().entry(index).or_insert_with(|| { *self
let mut key = self.root.tables.def_keys.get(self, index).unwrap().decode(self); .def_key_cache
if self.is_proc_macro(index) { .lock()
let name = self.raw_proc_macro(index).name(); .entry(index)
key.disambiguated_data.data = DefPathData::MacroNs(Symbol::intern(name)); .or_insert_with(|| self.root.tables.def_keys.get(self, index).unwrap().decode(self))
}
key
})
} }
// Returns the path leading to the thing with this `id`. // Returns the path leading to the thing with this `id`.

View file

@ -9,6 +9,7 @@ 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::CtorKind;
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::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor}; use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
use rustc_hir::lang_items; use rustc_hir::lang_items;
@ -27,7 +28,7 @@ use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt}; use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
use rustc_serialize::{opaque, Encodable, Encoder}; use rustc_serialize::{opaque, Encodable, Encoder};
use rustc_session::config::CrateType; use rustc_session::config::CrateType;
use rustc_span::hygiene::{ExpnDataEncodeMode, HygieneEncodeContext}; use rustc_span::hygiene::{ExpnDataEncodeMode, HygieneEncodeContext, MacroKind};
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext}; use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext};
use rustc_target::abi::VariantIdx; use rustc_target::abi::VariantIdx;
@ -1539,12 +1540,41 @@ impl EncodeContext<'a, 'tcx> {
// so we manually encode just the information that we need // so we manually encode just the information that we need
for proc_macro in &hir.krate().proc_macros { for proc_macro in &hir.krate().proc_macros {
let id = proc_macro.owner.local_def_index; let id = proc_macro.owner.local_def_index;
let span = self.lazy(hir.span(*proc_macro)); let mut name = hir.name(*proc_macro);
let span = hir.span(*proc_macro);
// Proc-macros may have attributes like `#[allow_internal_unstable]`, // Proc-macros may have attributes like `#[allow_internal_unstable]`,
// so downstream crates need access to them. // so downstream crates need access to them.
let attrs = self.lazy(hir.attrs(*proc_macro)); let attrs = hir.attrs(*proc_macro);
self.tables.span.set(id, span); let macro_kind = if tcx.sess.contains_name(attrs, sym::proc_macro) {
self.tables.attributes.set(id, attrs); MacroKind::Bang
} else if tcx.sess.contains_name(attrs, sym::proc_macro_attribute) {
MacroKind::Attr
} else if let Some(attr) = tcx.sess.find_by_name(attrs, sym::proc_macro_derive) {
// This unwrap chain should have been checked by the proc-macro harness.
name = attr.meta_item_list().unwrap()[0]
.meta_item()
.unwrap()
.ident()
.unwrap()
.name;
MacroKind::Derive
} else {
bug!("Unknown proc-macro type for item {:?}", id);
};
let mut def_key = self.tcx.hir().def_key(proc_macro.owner);
def_key.disambiguated_data.data = DefPathData::MacroNs(name);
let def_id = DefId::local(id);
record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
record!(self.tables.attributes[def_id] <- attrs);
record!(self.tables.def_keys[def_id] <- def_key);
record!(self.tables.ident_span[def_id] <- span);
record!(self.tables.span[def_id] <- span);
record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
if let Some(stability) = stability {
record!(self.tables.stability[def_id] <- stability);
}
} }
Some(ProcMacroData { proc_macro_decls_static, stability, macros }) Some(ProcMacroData { proc_macro_decls_static, stability, macros })

View file

@ -20,6 +20,7 @@ use rustc_serialize::opaque::Encoder;
use rustc_session::config::SymbolManglingVersion; use rustc_session::config::SymbolManglingVersion;
use rustc_session::CrateDisambiguator; use rustc_session::CrateDisambiguator;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{Ident, Symbol}; use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{self, ExpnData, ExpnId, Span}; use rustc_span::{self, ExpnData, ExpnId, Span};
use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_target::spec::{PanicStrategy, TargetTriple};
@ -336,6 +337,7 @@ enum EntryKind {
ForeignFn(Lazy<FnData>), ForeignFn(Lazy<FnData>),
Mod(Lazy<ModData>), Mod(Lazy<ModData>),
MacroDef(Lazy<MacroDef>), MacroDef(Lazy<MacroDef>),
ProcMacro(MacroKind),
Closure, Closure,
Generator(hir::GeneratorKind), Generator(hir::GeneratorKind),
Trait(Lazy<TraitData>), Trait(Lazy<TraitData>),