Skip to content

Commit 2fe37c5

Browse files
committed
Choose encoding format in caller code.
1 parent 078dd37 commit 2fe37c5

File tree

4 files changed

+55
-85
lines changed

4 files changed

+55
-85
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,11 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
377377
let local_cdata = decoder.cdata();
378378
let sess = decoder.sess.unwrap();
379379

380-
rustc_span::hygiene::decode_expn_id(decoder, |cnum, index| {
380+
let cnum = CrateNum::decode(decoder)?;
381+
let index = u32::decode(decoder)?;
382+
383+
let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| {
384+
let ExpnId { krate: cnum, local_id: index } = expn_id;
381385
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
382386
// are stored in the owning crate, to avoid duplication.
383387
debug_assert_ne!(cnum, LOCAL_CRATE);
@@ -399,7 +403,8 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
399403
.unwrap()
400404
.decode((&crate_data, sess));
401405
(expn_data, expn_hash)
402-
})
406+
});
407+
Ok(expn_id)
403408
}
404409
}
405410

compiler/rustc_metadata/src/rmeta/encoder.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext {
182182

183183
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
184184
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
185-
rustc_span::hygiene::raw_encode_expn_id(*self, &s.hygiene_ctxt, s)
185+
if self.krate == LOCAL_CRATE {
186+
// We will only write details for local expansions. Non-local expansions will fetch
187+
// data from the corresponding crate's metadata.
188+
// FIXME(#43047) FIXME(#74731) We may eventually want to avoid relying on external
189+
// metadata from proc-macro crates.
190+
s.hygiene_ctxt.schedule_expn_data_for_encoding(*self);
191+
}
192+
self.krate.encode(s)?;
193+
self.local_id.encode(s)
186194
}
187195
}
188196

compiler/rustc_middle/src/ty/query/on_disk_cache.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -794,25 +794,26 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
794794

795795
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
796796
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
797+
let krate = CrateNum::decode(decoder)?;
798+
let index = u32::decode(decoder)?;
799+
797800
let expn_data = decoder.expn_data;
801+
let tcx = decoder.tcx;
798802
rustc_span::hygiene::decode_expn_id_incrcomp(
799-
decoder,
803+
krate,
804+
index,
800805
decoder.hygiene_context,
801-
|this, index| {
806+
|index| -> Result<(ExpnData, ExpnHash), _> {
802807
// This closure is invoked if we haven't already decoded the data for the `ExpnId` we are deserializing.
803808
// We look up the position of the associated `ExpnData` and decode it.
804809
let pos = expn_data
805810
.get(&index)
806811
.unwrap_or_else(|| panic!("Bad index {:?} (map {:?})", index, expn_data));
807812

808-
this.with_position(pos.to_usize(), |decoder| {
809-
let data: (ExpnData, ExpnHash) = decode_tagged(decoder, TAG_EXPN_DATA)?;
810-
Ok(data)
811-
})
812-
},
813-
|this, expn_id| {
814-
Ok(this.tcx.untracked_resolutions.cstore.decode_expn_data(this.tcx.sess, expn_id))
813+
decoder
814+
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA))
815815
},
816+
|expn_id| tcx.untracked_resolutions.cstore.decode_expn_data(tcx.sess, expn_id),
816817
)
817818
}
818819
}
@@ -988,7 +989,9 @@ where
988989
E: 'a + OpaqueEncoder,
989990
{
990991
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
991-
rustc_span::hygiene::raw_encode_expn_id_incrcomp(*self, s.hygiene_context, s)
992+
s.hygiene_context.schedule_expn_data_for_encoding(*self);
993+
self.krate.encode(s)?;
994+
self.local_id.as_u32().encode(s)
992995
}
993996
}
994997

compiler/rustc_span/src/hygiene.rs

+26-72
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ pub struct HygieneData {
261261
/// first and then resolved later), so we use an `Option` here.
262262
local_expn_data: IndexVec<LocalExpnId, Option<ExpnData>>,
263263
local_expn_hashes: IndexVec<LocalExpnId, ExpnHash>,
264+
/// Data and hash information from external crates. We may eventually want to remove these
265+
/// maps, and fetch the information directly from the other crate's metadata like DefIds do.
264266
foreign_expn_data: FxHashMap<ExpnId, ExpnData>,
265267
foreign_expn_hashes: FxHashMap<ExpnId, ExpnHash>,
266268
expn_hash_to_expn_id: UnhashMap<ExpnHash, ExpnId>,
@@ -1130,6 +1132,13 @@ pub struct HygieneEncodeContext {
11301132
}
11311133

11321134
impl HygieneEncodeContext {
1135+
/// Record the fact that we need to serialize the corresponding `ExpnData`.
1136+
pub fn schedule_expn_data_for_encoding(&self, expn: ExpnId) {
1137+
if !self.serialized_expns.lock().contains(&expn) {
1138+
self.latest_expns.lock().insert(expn);
1139+
}
1140+
}
1141+
11331142
pub fn encode<T, R>(
11341143
&self,
11351144
encoder: &mut T,
@@ -1186,15 +1195,13 @@ pub struct HygieneDecodeContext {
11861195
remapped_expns: Lock<Vec<Option<LocalExpnId>>>,
11871196
}
11881197

1189-
pub fn decode_expn_id_incrcomp<D: Decoder>(
1190-
d: &mut D,
1198+
pub fn decode_expn_id_incrcomp<E>(
1199+
krate: CrateNum,
1200+
index: u32,
11911201
context: &HygieneDecodeContext,
1192-
decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>,
1193-
decode_foreign: impl FnOnce(&mut D, ExpnId) -> Result<(ExpnData, ExpnHash), D::Error>,
1194-
) -> Result<ExpnId, D::Error> {
1195-
let krate = CrateNum::decode(d)?;
1196-
let index = u32::decode(d)?;
1197-
1202+
decode_data: impl FnOnce(u32) -> Result<(ExpnData, ExpnHash), E>,
1203+
decode_foreign: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
1204+
) -> Result<ExpnId, E> {
11981205
// Do this after decoding, so that we decode a `CrateNum`
11991206
// if necessary
12001207
if index == 0 {
@@ -1203,23 +1210,7 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
12031210
}
12041211

12051212
if krate != LOCAL_CRATE {
1206-
let expn_id = ExpnId { krate, local_id: ExpnIndex::from_u32(index) };
1207-
if HygieneData::with(|hygiene_data| hygiene_data.foreign_expn_data.contains_key(&expn_id)) {
1208-
return Ok(expn_id);
1209-
}
1210-
let (expn_data, hash) = decode_foreign(d, expn_id)?;
1211-
debug_assert_eq!(krate, expn_data.krate);
1212-
debug_assert_eq!(expn_data.orig_id, Some(index));
1213-
let expn_id = HygieneData::with(|hygiene_data| {
1214-
debug_assert_eq!(expn_data.orig_id, Some(index));
1215-
let _old_data = hygiene_data.foreign_expn_data.insert(expn_id, expn_data);
1216-
debug_assert!(_old_data.is_none());
1217-
let _old_hash = hygiene_data.foreign_expn_hashes.insert(expn_id, hash);
1218-
debug_assert!(_old_hash.is_none());
1219-
let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
1220-
debug_assert!(_old_id.is_none());
1221-
expn_id
1222-
});
1213+
let expn_id = decode_expn_id(krate, index, decode_foreign);
12231214
return Ok(expn_id);
12241215
}
12251216

@@ -1234,7 +1225,7 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
12341225

12351226
// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
12361227
// other ExpnIds
1237-
let (mut expn_data, hash) = decode_data(d, index)?;
1228+
let (mut expn_data, hash) = decode_data(index)?;
12381229
debug_assert_eq!(krate, expn_data.krate);
12391230

12401231
let expn_id = HygieneData::with(|hygiene_data| {
@@ -1269,18 +1260,14 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
12691260
Ok(expn_id)
12701261
}
12711262

1272-
pub fn decode_expn_id<D: Decoder>(
1273-
d: &mut D,
1274-
decode_data: impl FnOnce(CrateNum, ExpnIndex) -> (ExpnData, ExpnHash),
1275-
) -> Result<ExpnId, D::Error> {
1276-
let krate = CrateNum::decode(d)?;
1277-
let index = u32::decode(d)?;
1278-
1279-
// Do this after decoding, so that we decode a `CrateNum`
1280-
// if necessary
1263+
pub fn decode_expn_id(
1264+
krate: CrateNum,
1265+
index: u32,
1266+
decode_data: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
1267+
) -> ExpnId {
12811268
if index == 0 {
12821269
debug!("decode_expn_id: deserialized root");
1283-
return Ok(ExpnId::root());
1270+
return ExpnId::root();
12841271
}
12851272

12861273
let index = ExpnIndex::from_u32(index);
@@ -1291,12 +1278,12 @@ pub fn decode_expn_id<D: Decoder>(
12911278

12921279
// Fast path if the expansion has already been decoded.
12931280
if HygieneData::with(|hygiene_data| hygiene_data.foreign_expn_data.contains_key(&expn_id)) {
1294-
return Ok(expn_id);
1281+
return expn_id;
12951282
}
12961283

12971284
// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
12981285
// other ExpnIds
1299-
let (expn_data, hash) = decode_data(krate, index);
1286+
let (expn_data, hash) = decode_data(expn_id);
13001287
debug_assert_eq!(krate, expn_data.krate);
13011288
debug_assert_eq!(Some(index.as_u32()), expn_data.orig_id);
13021289

@@ -1309,7 +1296,7 @@ pub fn decode_expn_id<D: Decoder>(
13091296
debug_assert!(_old_id.is_none());
13101297
});
13111298

1312-
Ok(expn_id)
1299+
expn_id
13131300
}
13141301

13151302
// Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
@@ -1448,39 +1435,6 @@ pub fn raw_encode_syntax_context<E: Encoder>(
14481435
ctxt.0.encode(e)
14491436
}
14501437

1451-
pub fn raw_encode_expn_id_incrcomp<E: Encoder>(
1452-
expn: ExpnId,
1453-
context: &HygieneEncodeContext,
1454-
e: &mut E,
1455-
) -> Result<(), E::Error> {
1456-
// Record the fact that we need to serialize the corresponding `ExpnData`
1457-
if !context.serialized_expns.lock().contains(&expn) {
1458-
context.latest_expns.lock().insert(expn);
1459-
}
1460-
expn.krate.encode(e)?;
1461-
expn.local_id.as_u32().encode(e)
1462-
}
1463-
1464-
pub fn raw_encode_expn_id<E: Encoder>(
1465-
expn: ExpnId,
1466-
context: &HygieneEncodeContext,
1467-
e: &mut E,
1468-
) -> Result<(), E::Error> {
1469-
// We only need to serialize the ExpnData
1470-
// if it comes from this crate.
1471-
// We currently don't serialize any hygiene information data for
1472-
// proc-macro crates: see the `SpecializedEncoder<Span>` impl
1473-
// for crate metadata.
1474-
// Record the fact that we need to serialize the corresponding `ExpnData`
1475-
if expn.krate == LOCAL_CRATE {
1476-
if !context.serialized_expns.lock().contains(&expn) {
1477-
context.latest_expns.lock().insert(expn);
1478-
}
1479-
}
1480-
expn.krate.encode(e)?;
1481-
expn.local_id.as_u32().encode(e)
1482-
}
1483-
14841438
impl<E: Encoder> Encodable<E> for SyntaxContext {
14851439
default fn encode(&self, _: &mut E) -> Result<(), E::Error> {
14861440
panic!("cannot encode `SyntaxContext` with `{}`", std::any::type_name::<E>());

0 commit comments

Comments
 (0)