Skip to content

Commit 522b1d0

Browse files
authored
Rollup merge of rust-lang#69677 - petrochenkov:spancode, r=eddyb
rustc_metadata: Give decoder access to whole crate store Pre-requisite for rust-lang#68941. r? @eddyb
2 parents dd6a074 + 41374d7 commit 522b1d0

File tree

3 files changed

+126
-107
lines changed

3 files changed

+126
-107
lines changed

src/librustc_metadata/creader.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ impl<'a> LoadError<'a> {
7676
}
7777
}
7878

79+
/// A reference to `CrateMetadata` that can also give access to whole crate store when necessary.
80+
#[derive(Clone, Copy)]
81+
crate struct CrateMetadataRef<'a> {
82+
pub cdata: &'a CrateMetadata,
83+
pub cstore: &'a CStore,
84+
}
85+
86+
impl std::ops::Deref for CrateMetadataRef<'_> {
87+
type Target = CrateMetadata;
88+
89+
fn deref(&self) -> &Self::Target {
90+
self.cdata
91+
}
92+
}
93+
7994
fn dump_crates(cstore: &CStore) {
8095
info!("resolved crates:");
8196
cstore.iter_crate_data(|cnum, data| {
@@ -100,10 +115,11 @@ impl CStore {
100115
CrateNum::new(self.metas.len() - 1)
101116
}
102117

103-
crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata {
104-
self.metas[cnum]
118+
crate fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> {
119+
let cdata = self.metas[cnum]
105120
.as_ref()
106-
.unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
121+
.unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum));
122+
CrateMetadataRef { cdata, cstore: self }
107123
}
108124

109125
fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
@@ -217,7 +233,7 @@ impl<'a> CrateLoader<'a> {
217233
// We're also sure to compare *paths*, not actual byte slices. The
218234
// `source` stores paths which are normalized which may be different
219235
// from the strings on the command line.
220-
let source = self.cstore.get_crate_data(cnum).source();
236+
let source = self.cstore.get_crate_data(cnum).cdata.source();
221237
if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) {
222238
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
223239
if let Some(mut files) = entry.files() {

src/librustc_metadata/rmeta/decoder.rs

+105-102
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Decoding metadata from a single crate's metadata
22

3+
use crate::creader::CrateMetadataRef;
34
use crate::rmeta::table::{FixedSizeEncoding, Table};
45
use crate::rmeta::*;
56

@@ -125,7 +126,7 @@ struct ImportedSourceFile {
125126

126127
pub(super) struct DecodeContext<'a, 'tcx> {
127128
opaque: opaque::Decoder<'a>,
128-
cdata: Option<&'a CrateMetadata>,
129+
cdata: Option<CrateMetadataRef<'a>>,
129130
sess: Option<&'tcx Session>,
130131
tcx: Option<TyCtxt<'tcx>>,
131132

@@ -141,7 +142,7 @@ pub(super) struct DecodeContext<'a, 'tcx> {
141142
/// Abstract over the various ways one can create metadata decoders.
142143
pub(super) trait Metadata<'a, 'tcx>: Copy {
143144
fn raw_bytes(self) -> &'a [u8];
144-
fn cdata(self) -> Option<&'a CrateMetadata> {
145+
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
145146
None
146147
}
147148
fn sess(self) -> Option<&'tcx Session> {
@@ -162,7 +163,7 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
162163
lazy_state: LazyState::NoNode,
163164
alloc_decoding_session: self
164165
.cdata()
165-
.map(|cdata| cdata.alloc_decoding_state.new_decoding_session()),
166+
.map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()),
166167
}
167168
}
168169
}
@@ -185,33 +186,33 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) {
185186
}
186187
}
187188

188-
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadata {
189+
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadataRef<'a> {
189190
fn raw_bytes(self) -> &'a [u8] {
190191
self.blob.raw_bytes()
191192
}
192-
fn cdata(self) -> Option<&'a CrateMetadata> {
193-
Some(self)
193+
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
194+
Some(*self)
194195
}
195196
}
196197

197-
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, &'tcx Session) {
198+
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, &'tcx Session) {
198199
fn raw_bytes(self) -> &'a [u8] {
199200
self.0.raw_bytes()
200201
}
201-
fn cdata(self) -> Option<&'a CrateMetadata> {
202-
Some(self.0)
202+
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
203+
Some(*self.0)
203204
}
204205
fn sess(self) -> Option<&'tcx Session> {
205206
Some(&self.1)
206207
}
207208
}
208209

209-
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) {
210+
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, TyCtxt<'tcx>) {
210211
fn raw_bytes(self) -> &'a [u8] {
211212
self.0.raw_bytes()
212213
}
213-
fn cdata(self) -> Option<&'a CrateMetadata> {
214-
Some(self.0)
214+
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
215+
Some(*self.0)
215216
}
216217
fn tcx(self) -> Option<TyCtxt<'tcx>> {
217218
Some(self.1)
@@ -242,7 +243,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
242243
self.tcx.expect("missing TyCtxt in DecodeContext")
243244
}
244245

245-
fn cdata(&self) -> &'a CrateMetadata {
246+
fn cdata(&self) -> CrateMetadataRef<'a> {
246247
self.cdata.expect("missing CrateMetadata in DecodeContext")
247248
}
248249

@@ -558,50 +559,7 @@ impl CrateRoot<'_> {
558559
}
559560
}
560561

561-
impl<'a, 'tcx> CrateMetadata {
562-
crate fn new(
563-
sess: &Session,
564-
blob: MetadataBlob,
565-
root: CrateRoot<'static>,
566-
raw_proc_macros: Option<&'static [ProcMacro]>,
567-
cnum: CrateNum,
568-
cnum_map: CrateNumMap,
569-
dep_kind: DepKind,
570-
source: CrateSource,
571-
private_dep: bool,
572-
host_hash: Option<Svh>,
573-
) -> CrateMetadata {
574-
let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || {
575-
root.def_path_table.decode((&blob, sess))
576-
});
577-
let trait_impls = root
578-
.impls
579-
.decode((&blob, sess))
580-
.map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
581-
.collect();
582-
let alloc_decoding_state =
583-
AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
584-
let dependencies = Lock::new(cnum_map.iter().cloned().collect());
585-
CrateMetadata {
586-
blob,
587-
root,
588-
def_path_table,
589-
trait_impls,
590-
raw_proc_macros,
591-
source_map_import_info: Once::new(),
592-
alloc_decoding_state,
593-
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
594-
cnum,
595-
cnum_map,
596-
dependencies,
597-
dep_kind: Lock::new(dep_kind),
598-
source,
599-
private_dep,
600-
host_hash,
601-
extern_crate: Lock::new(None),
602-
}
603-
}
604-
562+
impl<'a, 'tcx> CrateMetadataRef<'a> {
605563
fn is_proc_macro(&self, id: DefIndex) -> bool {
606564
self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some()
607565
}
@@ -622,10 +580,6 @@ impl<'a, 'tcx> CrateMetadata {
622580
})
623581
}
624582

625-
fn local_def_id(&self, index: DefIndex) -> DefId {
626-
DefId { krate: self.cnum, index }
627-
}
628-
629583
fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro {
630584
// DefIndex's in root.proc_macro_data have a one-to-one correspondence
631585
// with items in 'raw_proc_macros'.
@@ -1191,18 +1145,6 @@ impl<'a, 'tcx> CrateMetadata {
11911145
.collect()
11921146
}
11931147

1194-
// Translate a DefId from the current compilation environment to a DefId
1195-
// for an external crate.
1196-
fn reverse_translate_def_id(&self, did: DefId) -> Option<DefId> {
1197-
for (local, &global) in self.cnum_map.iter_enumerated() {
1198-
if global == did.krate {
1199-
return Some(DefId { krate: local, index: did.index });
1200-
}
1201-
}
1202-
1203-
None
1204-
}
1205-
12061148
fn get_inherent_implementations_for_type(
12071149
&self,
12081150
tcx: TyCtxt<'tcx>,
@@ -1409,11 +1351,6 @@ impl<'a, 'tcx> CrateMetadata {
14091351
DefPath::make(self.cnum, id, |parent| self.def_key(parent))
14101352
}
14111353

1412-
#[inline]
1413-
fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
1414-
self.def_path_table.def_path_hash(index)
1415-
}
1416-
14171354
/// Imports the source_map from an external crate into the source_map of the crate
14181355
/// currently being compiled (the "local crate").
14191356
///
@@ -1440,10 +1377,10 @@ impl<'a, 'tcx> CrateMetadata {
14401377
/// Proc macro crates don't currently export spans, so this function does not have
14411378
/// to work for them.
14421379
fn imported_source_files(
1443-
&'a self,
1380+
&self,
14441381
local_source_map: &source_map::SourceMap,
1445-
) -> &[ImportedSourceFile] {
1446-
self.source_map_import_info.init_locking(|| {
1382+
) -> &'a [ImportedSourceFile] {
1383+
self.cdata.source_map_import_info.init_locking(|| {
14471384
let external_source_map = self.root.source_map.decode(self);
14481385

14491386
external_source_map
@@ -1516,29 +1453,50 @@ impl<'a, 'tcx> CrateMetadata {
15161453
.collect()
15171454
})
15181455
}
1456+
}
15191457

1520-
/// Get the `DepNodeIndex` corresponding this crate. The result of this
1521-
/// method is cached in the `dep_node_index` field.
1522-
fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
1523-
let mut dep_node_index = self.dep_node_index.load();
1524-
1525-
if unlikely!(dep_node_index == DepNodeIndex::INVALID) {
1526-
// We have not cached the DepNodeIndex for this upstream crate yet,
1527-
// so use the dep-graph to find it out and cache it.
1528-
// Note that multiple threads can enter this block concurrently.
1529-
// That is fine because the DepNodeIndex remains constant
1530-
// throughout the whole compilation session, and multiple stores
1531-
// would always write the same value.
1532-
1533-
let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX);
1534-
let dep_node = def_path_hash.to_dep_node(dep_graph::DepKind::CrateMetadata);
1535-
1536-
dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node);
1537-
assert!(dep_node_index != DepNodeIndex::INVALID);
1538-
self.dep_node_index.store(dep_node_index);
1458+
impl CrateMetadata {
1459+
crate fn new(
1460+
sess: &Session,
1461+
blob: MetadataBlob,
1462+
root: CrateRoot<'static>,
1463+
raw_proc_macros: Option<&'static [ProcMacro]>,
1464+
cnum: CrateNum,
1465+
cnum_map: CrateNumMap,
1466+
dep_kind: DepKind,
1467+
source: CrateSource,
1468+
private_dep: bool,
1469+
host_hash: Option<Svh>,
1470+
) -> CrateMetadata {
1471+
let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || {
1472+
root.def_path_table.decode((&blob, sess))
1473+
});
1474+
let trait_impls = root
1475+
.impls
1476+
.decode((&blob, sess))
1477+
.map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
1478+
.collect();
1479+
let alloc_decoding_state =
1480+
AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
1481+
let dependencies = Lock::new(cnum_map.iter().cloned().collect());
1482+
CrateMetadata {
1483+
blob,
1484+
root,
1485+
def_path_table,
1486+
trait_impls,
1487+
raw_proc_macros,
1488+
source_map_import_info: Once::new(),
1489+
alloc_decoding_state,
1490+
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
1491+
cnum,
1492+
cnum_map,
1493+
dependencies,
1494+
dep_kind: Lock::new(dep_kind),
1495+
source,
1496+
private_dep,
1497+
host_hash,
1498+
extern_crate: Lock::new(None),
15391499
}
1540-
1541-
dep_node_index
15421500
}
15431501

15441502
crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
@@ -1613,6 +1571,51 @@ impl<'a, 'tcx> CrateMetadata {
16131571
crate fn hash(&self) -> Svh {
16141572
self.root.hash
16151573
}
1574+
1575+
fn local_def_id(&self, index: DefIndex) -> DefId {
1576+
DefId { krate: self.cnum, index }
1577+
}
1578+
1579+
// Translate a DefId from the current compilation environment to a DefId
1580+
// for an external crate.
1581+
fn reverse_translate_def_id(&self, did: DefId) -> Option<DefId> {
1582+
for (local, &global) in self.cnum_map.iter_enumerated() {
1583+
if global == did.krate {
1584+
return Some(DefId { krate: local, index: did.index });
1585+
}
1586+
}
1587+
1588+
None
1589+
}
1590+
1591+
#[inline]
1592+
fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
1593+
self.def_path_table.def_path_hash(index)
1594+
}
1595+
1596+
/// Get the `DepNodeIndex` corresponding this crate. The result of this
1597+
/// method is cached in the `dep_node_index` field.
1598+
fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
1599+
let mut dep_node_index = self.dep_node_index.load();
1600+
1601+
if unlikely!(dep_node_index == DepNodeIndex::INVALID) {
1602+
// We have not cached the DepNodeIndex for this upstream crate yet,
1603+
// so use the dep-graph to find it out and cache it.
1604+
// Note that multiple threads can enter this block concurrently.
1605+
// That is fine because the DepNodeIndex remains constant
1606+
// throughout the whole compilation session, and multiple stores
1607+
// would always write the same value.
1608+
1609+
let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX);
1610+
let dep_node = def_path_hash.to_dep_node(dep_graph::DepKind::CrateMetadata);
1611+
1612+
dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node);
1613+
assert!(dep_node_index != DepNodeIndex::INVALID);
1614+
self.dep_node_index.store(dep_node_index);
1615+
}
1616+
1617+
dep_node_index
1618+
}
16161619
}
16171620

16181621
// Cannot be implemented on 'ProcMacro', as libproc_macro

src/librustc_metadata/rmeta/decoder/cstore_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ impl CrateStore for CStore {
517517
}
518518

519519
fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable {
520-
&self.get_crate_data(cnum).def_path_table
520+
&self.get_crate_data(cnum).cdata.def_path_table
521521
}
522522

523523
fn crates_untracked(&self) -> Vec<CrateNum> {

0 commit comments

Comments
 (0)