rustc_metadata: Give decoder access to whole crate store

This commit is contained in:
Vadim Petrochenkov 2020-03-03 01:06:07 +03:00
parent c79f5f0647
commit c1df945a61
3 changed files with 43 additions and 22 deletions

View File

@ -76,6 +76,21 @@ impl<'a> LoadError<'a> {
} }
} }
/// A reference to `CrateMetadata` that can also give access to whole crate store when necessary.
#[derive(Clone, Copy)]
crate struct CrateMetadataRef<'a> {
pub cdata: &'a CrateMetadata,
pub cstore: &'a CStore,
}
impl std::ops::Deref for CrateMetadataRef<'_> {
type Target = CrateMetadata;
fn deref(&self) -> &Self::Target {
self.cdata
}
}
fn dump_crates(cstore: &CStore) { fn dump_crates(cstore: &CStore) {
info!("resolved crates:"); info!("resolved crates:");
cstore.iter_crate_data(|cnum, data| { cstore.iter_crate_data(|cnum, data| {
@ -100,10 +115,11 @@ impl CStore {
CrateNum::new(self.metas.len() - 1) CrateNum::new(self.metas.len() - 1)
} }
crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata { crate fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> {
self.metas[cnum] let cdata = self.metas[cnum]
.as_ref() .as_ref()
.unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum));
CrateMetadataRef { cdata, cstore: self }
} }
fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) { fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
@ -217,7 +233,7 @@ impl<'a> CrateLoader<'a> {
// We're also sure to compare *paths*, not actual byte slices. The // We're also sure to compare *paths*, not actual byte slices. The
// `source` stores paths which are normalized which may be different // `source` stores paths which are normalized which may be different
// from the strings on the command line. // from the strings on the command line.
let source = self.cstore.get_crate_data(cnum).source(); let source = self.cstore.get_crate_data(cnum).cdata.source();
if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) { if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) {
// Only use `--extern crate_name=path` here, not `--extern crate_name`. // Only use `--extern crate_name=path` here, not `--extern crate_name`.
if let Some(mut files) = entry.files() { if let Some(mut files) = entry.files() {

View File

@ -1,5 +1,6 @@
// Decoding metadata from a single crate's metadata // Decoding metadata from a single crate's metadata
use crate::creader::CrateMetadataRef;
use crate::rmeta::table::{FixedSizeEncoding, Table}; use crate::rmeta::table::{FixedSizeEncoding, Table};
use crate::rmeta::*; use crate::rmeta::*;
@ -125,7 +126,7 @@ struct ImportedSourceFile {
pub(super) struct DecodeContext<'a, 'tcx> { pub(super) struct DecodeContext<'a, 'tcx> {
opaque: opaque::Decoder<'a>, opaque: opaque::Decoder<'a>,
cdata: Option<&'a CrateMetadata>, cdata: Option<CrateMetadataRef<'a>>,
sess: Option<&'tcx Session>, sess: Option<&'tcx Session>,
tcx: Option<TyCtxt<'tcx>>, tcx: Option<TyCtxt<'tcx>>,
@ -141,7 +142,7 @@ pub(super) struct DecodeContext<'a, 'tcx> {
/// Abstract over the various ways one can create metadata decoders. /// Abstract over the various ways one can create metadata decoders.
pub(super) trait Metadata<'a, 'tcx>: Copy { pub(super) trait Metadata<'a, 'tcx>: Copy {
fn raw_bytes(self) -> &'a [u8]; fn raw_bytes(self) -> &'a [u8];
fn cdata(self) -> Option<&'a CrateMetadata> { fn cdata(self) -> Option<CrateMetadataRef<'a>> {
None None
} }
fn sess(self) -> Option<&'tcx Session> { fn sess(self) -> Option<&'tcx Session> {
@ -162,7 +163,7 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
lazy_state: LazyState::NoNode, lazy_state: LazyState::NoNode,
alloc_decoding_session: self alloc_decoding_session: self
.cdata() .cdata()
.map(|cdata| cdata.alloc_decoding_state.new_decoding_session()), .map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()),
} }
} }
} }
@ -185,33 +186,33 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) {
} }
} }
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadata { impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadataRef<'a> {
fn raw_bytes(self) -> &'a [u8] { fn raw_bytes(self) -> &'a [u8] {
self.blob.raw_bytes() self.blob.raw_bytes()
} }
fn cdata(self) -> Option<&'a CrateMetadata> { fn cdata(self) -> Option<CrateMetadataRef<'a>> {
Some(self) Some(*self)
} }
} }
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, &'tcx Session) { impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, &'tcx Session) {
fn raw_bytes(self) -> &'a [u8] { fn raw_bytes(self) -> &'a [u8] {
self.0.raw_bytes() self.0.raw_bytes()
} }
fn cdata(self) -> Option<&'a CrateMetadata> { fn cdata(self) -> Option<CrateMetadataRef<'a>> {
Some(self.0) Some(*self.0)
} }
fn sess(self) -> Option<&'tcx Session> { fn sess(self) -> Option<&'tcx Session> {
Some(&self.1) Some(&self.1)
} }
} }
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) { impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, TyCtxt<'tcx>) {
fn raw_bytes(self) -> &'a [u8] { fn raw_bytes(self) -> &'a [u8] {
self.0.raw_bytes() self.0.raw_bytes()
} }
fn cdata(self) -> Option<&'a CrateMetadata> { fn cdata(self) -> Option<CrateMetadataRef<'a>> {
Some(self.0) Some(*self.0)
} }
fn tcx(self) -> Option<TyCtxt<'tcx>> { fn tcx(self) -> Option<TyCtxt<'tcx>> {
Some(self.1) Some(self.1)
@ -242,7 +243,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
self.tcx.expect("missing TyCtxt in DecodeContext") self.tcx.expect("missing TyCtxt in DecodeContext")
} }
fn cdata(&self) -> &'a CrateMetadata { fn cdata(&self) -> CrateMetadataRef<'a> {
self.cdata.expect("missing CrateMetadata in DecodeContext") self.cdata.expect("missing CrateMetadata in DecodeContext")
} }
@ -558,7 +559,7 @@ impl CrateRoot<'_> {
} }
} }
impl<'a, 'tcx> CrateMetadata { impl CrateMetadata {
crate fn new( crate fn new(
sess: &Session, sess: &Session,
blob: MetadataBlob, blob: MetadataBlob,
@ -601,7 +602,9 @@ impl<'a, 'tcx> CrateMetadata {
extern_crate: Lock::new(None), extern_crate: Lock::new(None),
} }
} }
}
impl<'a, 'tcx> CrateMetadataRef<'a> {
fn is_proc_macro(&self, id: DefIndex) -> bool { fn is_proc_macro(&self, id: DefIndex) -> bool {
self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some() self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some()
} }
@ -1440,10 +1443,10 @@ impl<'a, 'tcx> CrateMetadata {
/// Proc macro crates don't currently export spans, so this function does not have /// Proc macro crates don't currently export spans, so this function does not have
/// to work for them. /// to work for them.
fn imported_source_files( fn imported_source_files(
&'a self, &self,
local_source_map: &source_map::SourceMap, local_source_map: &source_map::SourceMap,
) -> &[ImportedSourceFile] { ) -> &'a [ImportedSourceFile] {
self.source_map_import_info.init_locking(|| { self.cdata.source_map_import_info.init_locking(|| {
let external_source_map = self.root.source_map.decode(self); let external_source_map = self.root.source_map.decode(self);
external_source_map external_source_map
@ -1540,7 +1543,9 @@ impl<'a, 'tcx> CrateMetadata {
dep_node_index dep_node_index
} }
}
impl CrateMetadata {
crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> { crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
self.dependencies.borrow() self.dependencies.borrow()
} }

View File

@ -517,7 +517,7 @@ impl CrateStore for CStore {
} }
fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable { fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable {
&self.get_crate_data(cnum).def_path_table &self.get_crate_data(cnum).cdata.def_path_table
} }
fn crates_untracked(&self) -> Vec<CrateNum> { fn crates_untracked(&self) -> Vec<CrateNum> {