diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 19340dd51de14..e82449f69fd8e 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -644,6 +644,7 @@ impl EntryKind { 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, @@ -685,20 +686,11 @@ impl CrateRoot<'_> { } 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 { self.root.tables.kind.get(self, item_id).map(|k| k.decode(self)) } fn kind(&self, item_id: DefIndex) -> EntryKind { - assert!(!self.is_proc_macro(item_id)); self.maybe_kind(item_id).unwrap_or_else(|| { bug!( "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 { - if !self.is_proc_macro(item_index) { - let name = self - .def_key(item_index) - .disambiguated_data - .data - .get_opt_name() - .expect("no name in item_ident"); - let span = self - .root - .tables - .ident_span - .get(self, item_index) - .map(|data| data.decode((self, sess))) - .unwrap_or_else(|| panic!("Missing ident span for {:?} ({:?})", name, item_index)); - Ident::new(name, span) - } else { - Ident::new( - Symbol::intern(self.raw_proc_macro(item_index).name()), - self.get_span(item_index, sess), - ) - } + let name = self + .def_key(item_index) + .disambiguated_data + .data + .get_opt_name() + .expect("no name in item_ident"); + let span = self + .root + .tables + .ident_span + .get(self, item_index) + .map(|data| data.decode((self, sess))) + .unwrap_or_else(|| panic!("Missing ident span for {:?} ({:?})", name, item_index)); + Ident::new(name, span) } fn def_kind(&self, index: DefIndex) -> DefKind { - if !self.is_proc_macro(index) { - self.kind(index).def_kind() - } else { - DefKind::Macro(macro_kind(self.raw_proc_macro(index))) - } + self.kind(index).def_kind() } 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 { - match self.is_proc_macro(id) { - true => self.root.proc_macro_data.as_ref().unwrap().stability, - false => self.root.tables.stability.get(self, id).map(|stab| stab.decode(self)), - } + self.root.tables.stability.get(self, id).map(|stab| stab.decode(self)) } fn get_const_stability(&self, id: DefIndex) -> Option { @@ -967,19 +945,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_deprecation(&self, id: DefIndex) -> Option { - self.root - .tables - .deprecation - .get(self, id) - .filter(|_| !self.is_proc_macro(id)) - .map(|depr| depr.decode(self)) + self.root.tables.deprecation.get(self, id).map(|depr| depr.decode(self)) } fn get_visibility(&self, id: DefIndex) -> ty::Visibility { - match self.is_proc_macro(id) { - true => ty::Visibility::Public, - false => self.root.tables.visibility.get(self, id).unwrap().decode(self), - } + self.root.tables.visibility.get(self, id).unwrap().decode(self) } 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 { - !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 { @@ -1207,7 +1177,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .mir .get(self, id) - .filter(|_| !self.is_proc_macro(id)) .unwrap_or_else(|| { bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id)) }) @@ -1223,7 +1192,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .mir_abstract_consts .get(self, id) - .filter(|_| !self.is_proc_macro(id)) .map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx))))) } @@ -1232,7 +1200,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .unused_generic_params .get(self, id) - .filter(|_| !self.is_proc_macro(id)) .map(|params| params.decode(self)) .unwrap_or_default() } @@ -1242,7 +1209,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .promoted_mir .get(self, id) - .filter(|_| !self.is_proc_macro(id)) .unwrap_or_else(|| { bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id)) }) @@ -1546,14 +1512,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { #[inline] fn def_key(&self, index: DefIndex) -> DefKey { - *self.def_key_cache.lock().entry(index).or_insert_with(|| { - let mut key = self.root.tables.def_keys.get(self, index).unwrap().decode(self); - if self.is_proc_macro(index) { - let name = self.raw_proc_macro(index).name(); - key.disambiguated_data.data = DefPathData::MacroNs(Symbol::intern(name)); - } - key - }) + *self + .def_key_cache + .lock() + .entry(index) + .or_insert_with(|| self.root.tables.def_keys.get(self, index).unwrap().decode(self)) } // Returns the path leading to the thing with this `id`. diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 52ffd9a7975a3..46dd0df65e06f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -9,6 +9,7 @@ use rustc_data_structures::sync::{join, Lrc}; use rustc_hir as hir; use rustc_hir::def::CtorKind; 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::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor}; 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_serialize::{opaque, Encodable, Encoder}; 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::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext}; use rustc_target::abi::VariantIdx; @@ -1539,12 +1540,41 @@ impl EncodeContext<'a, 'tcx> { // so we manually encode just the information that we need for proc_macro in &hir.krate().proc_macros { 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]`, // so downstream crates need access to them. - let attrs = self.lazy(hir.attrs(*proc_macro)); - self.tables.span.set(id, span); - self.tables.attributes.set(id, attrs); + let attrs = hir.attrs(*proc_macro); + let macro_kind = if tcx.sess.contains_name(attrs, sym::proc_macro) { + 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 }) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 2bd2019d3cdb5..5360617890964 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -20,6 +20,7 @@ use rustc_serialize::opaque::Encoder; use rustc_session::config::SymbolManglingVersion; use rustc_session::CrateDisambiguator; use rustc_span::edition::Edition; +use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{self, ExpnData, ExpnId, Span}; use rustc_target::spec::{PanicStrategy, TargetTriple}; @@ -336,6 +337,7 @@ enum EntryKind { ForeignFn(Lazy), Mod(Lazy), MacroDef(Lazy), + ProcMacro(MacroKind), Closure, Generator(hir::GeneratorKind), Trait(Lazy),