Skip to content

Commit 47ea2ae

Browse files
committed
Separate encoding paths.
The two paths will be modified independently in the next few commits.
1 parent 0a6c636 commit 47ea2ae

File tree

4 files changed

+116
-97
lines changed

4 files changed

+116
-97
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use rustc_middle::ty::codec::TyDecoder;
3030
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
3131
use rustc_serialize::{opaque, Decodable, Decoder};
3232
use rustc_session::Session;
33-
use rustc_span::hygiene::ExpnDataDecodeMode;
3433
use rustc_span::source_map::{respan, Spanned};
3534
use rustc_span::symbol::{sym, Ident, Symbol};
3635
use rustc_span::{self, hygiene::MacroKind, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
@@ -381,33 +380,29 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
381380
}
382381
};
383382

384-
rustc_span::hygiene::decode_expn_id(
385-
decoder,
386-
ExpnDataDecodeMode::Metadata(get_ctxt),
387-
|_this, index| {
388-
let cnum = expn_cnum.get().unwrap();
389-
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
390-
// are stored in the owning crate, to avoid duplication.
391-
let crate_data = if cnum == LOCAL_CRATE {
392-
local_cdata
393-
} else {
394-
local_cdata.cstore.get_crate_data(cnum)
395-
};
396-
let expn_data = crate_data
397-
.root
398-
.expn_data
399-
.get(&crate_data, index)
400-
.unwrap()
401-
.decode((&crate_data, sess));
402-
let expn_hash = crate_data
403-
.root
404-
.expn_hashes
405-
.get(&crate_data, index)
406-
.unwrap()
407-
.decode((&crate_data, sess));
408-
Ok((expn_data, expn_hash))
409-
},
410-
)
383+
rustc_span::hygiene::decode_expn_id(decoder, get_ctxt, |_this, index| {
384+
let cnum = expn_cnum.get().unwrap();
385+
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
386+
// are stored in the owning crate, to avoid duplication.
387+
let crate_data = if cnum == LOCAL_CRATE {
388+
local_cdata
389+
} else {
390+
local_cdata.cstore.get_crate_data(cnum)
391+
};
392+
let expn_data = crate_data
393+
.root
394+
.expn_data
395+
.get(&crate_data, index)
396+
.unwrap()
397+
.decode((&crate_data, sess));
398+
let expn_hash = crate_data
399+
.root
400+
.expn_hashes
401+
.get(&crate_data, index)
402+
.unwrap()
403+
.decode((&crate_data, sess));
404+
Ok((expn_data, expn_hash))
405+
})
411406
}
412407
}
413408

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_session::config::CrateType;
3131
use rustc_span::symbol::{sym, Ident, Symbol};
3232
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext};
3333
use rustc_span::{
34-
hygiene::{ExpnDataEncodeMode, HygieneEncodeContext, MacroKind},
34+
hygiene::{HygieneEncodeContext, MacroKind},
3535
RealFileName,
3636
};
3737
use rustc_target::abi::VariantIdx;
@@ -176,12 +176,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext {
176176

177177
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
178178
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
179-
rustc_span::hygiene::raw_encode_expn_id(
180-
*self,
181-
&s.hygiene_ctxt,
182-
ExpnDataEncodeMode::Metadata,
183-
s,
184-
)
179+
rustc_span::hygiene::raw_encode_expn_id(*self, &s.hygiene_ctxt, s)
185180
}
186181
}
187182

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

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ use rustc_serialize::{
2020
};
2121
use rustc_session::Session;
2222
use rustc_span::hygiene::{
23-
ExpnDataDecodeMode, ExpnDataEncodeMode, ExpnId, HygieneDecodeContext, HygieneEncodeContext,
24-
SyntaxContext, SyntaxContextData,
23+
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
2524
};
2625
use rustc_span::source_map::{SourceMap, StableSourceFileId};
2726
use rustc_span::CachingSourceMapView;
@@ -793,9 +792,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
793792
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
794793
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
795794
let expn_data = decoder.expn_data;
796-
rustc_span::hygiene::decode_expn_id(
795+
rustc_span::hygiene::decode_expn_id_incrcomp(
797796
decoder,
798-
ExpnDataDecodeMode::incr_comp(decoder.hygiene_context),
797+
decoder.hygiene_context,
799798
|this, index| {
800799
// This closure is invoked if we haven't already decoded the data for the `ExpnId` we are deserializing.
801800
// We look up the position of the associated `ExpnData` and decode it.
@@ -983,12 +982,7 @@ where
983982
E: 'a + OpaqueEncoder,
984983
{
985984
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
986-
rustc_span::hygiene::raw_encode_expn_id(
987-
*self,
988-
s.hygiene_context,
989-
ExpnDataEncodeMode::IncrComp,
990-
s,
991-
)
985+
rustc_span::hygiene::raw_encode_expn_id_incrcomp(*self, s.hygiene_context, s)
992986
}
993987
}
994988

compiler/rustc_span/src/hygiene.rs

Lines changed: 87 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,22 +1076,74 @@ pub struct HygieneDecodeContext {
10761076
remapped_expns: Lock<Vec<Option<ExpnId>>>,
10771077
}
10781078

1079-
pub fn decode_expn_id<'a, D: Decoder, G>(
1079+
pub fn decode_expn_id_incrcomp<D: Decoder>(
10801080
d: &mut D,
1081-
mode: ExpnDataDecodeMode<'a, G>,
1081+
context: &HygieneDecodeContext,
10821082
decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>,
1083-
) -> Result<ExpnId, D::Error>
1084-
where
1085-
G: FnOnce(CrateNum) -> &'a HygieneDecodeContext,
1086-
{
1083+
) -> Result<ExpnId, D::Error> {
10871084
let index = u32::decode(d)?;
1088-
let context = match mode {
1089-
ExpnDataDecodeMode::IncrComp(context) => context,
1090-
ExpnDataDecodeMode::Metadata(get_context) => {
1091-
let krate = CrateNum::decode(d)?;
1092-
get_context(krate)
1085+
1086+
// Do this after decoding, so that we decode a `CrateNum`
1087+
// if necessary
1088+
if index == ExpnId::root().as_u32() {
1089+
debug!("decode_expn_id: deserialized root");
1090+
return Ok(ExpnId::root());
1091+
}
1092+
1093+
let outer_expns = &context.remapped_expns;
1094+
1095+
// Ensure that the lock() temporary is dropped early
1096+
{
1097+
if let Some(expn_id) = outer_expns.lock().get(index as usize).copied().flatten() {
1098+
return Ok(expn_id);
10931099
}
1094-
};
1100+
}
1101+
1102+
// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
1103+
// other ExpnIds
1104+
let (mut expn_data, hash) = decode_data(d, index)?;
1105+
1106+
let expn_id = HygieneData::with(|hygiene_data| {
1107+
if let Some(&expn_id) = hygiene_data.expn_hash_to_expn_id.get(&hash) {
1108+
return expn_id;
1109+
}
1110+
1111+
let expn_id = ExpnId(hygiene_data.expn_data.len() as u32);
1112+
1113+
// If we just deserialized an `ExpnData` owned by
1114+
// the local crate, its `orig_id` will be stale,
1115+
// so we need to update it to its own value.
1116+
// This only happens when we deserialize the incremental cache,
1117+
// since a crate will never decode its own metadata.
1118+
if expn_data.krate == LOCAL_CRATE {
1119+
expn_data.orig_id = Some(expn_id.0);
1120+
}
1121+
1122+
hygiene_data.expn_data.push(Some(expn_data));
1123+
hygiene_data.expn_hashes.push(hash);
1124+
let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
1125+
debug_assert!(_old_id.is_none());
1126+
1127+
let mut expns = outer_expns.lock();
1128+
let new_len = index as usize + 1;
1129+
if expns.len() < new_len {
1130+
expns.resize(new_len, None);
1131+
}
1132+
expns[index as usize] = Some(expn_id);
1133+
drop(expns);
1134+
expn_id
1135+
});
1136+
Ok(expn_id)
1137+
}
1138+
1139+
pub fn decode_expn_id<'a, D: Decoder>(
1140+
d: &mut D,
1141+
get_context: impl FnOnce(CrateNum) -> &'a HygieneDecodeContext,
1142+
decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>,
1143+
) -> Result<ExpnId, D::Error> {
1144+
let index = u32::decode(d)?;
1145+
let krate = CrateNum::decode(d)?;
1146+
let context = get_context(krate);
10951147

10961148
// Do this after decoding, so that we decode a `CrateNum`
10971149
// if necessary
@@ -1274,56 +1326,39 @@ pub fn raw_encode_syntax_context<E: Encoder>(
12741326
ctxt.0.encode(e)
12751327
}
12761328

1277-
pub fn raw_encode_expn_id<E: Encoder>(
1329+
pub fn raw_encode_expn_id_incrcomp<E: Encoder>(
12781330
expn: ExpnId,
12791331
context: &HygieneEncodeContext,
1280-
mode: ExpnDataEncodeMode,
12811332
e: &mut E,
12821333
) -> Result<(), E::Error> {
12831334
// Record the fact that we need to serialize the corresponding
12841335
// `ExpnData`
1285-
let needs_data = || {
1286-
if !context.serialized_expns.lock().contains(&expn) {
1287-
context.latest_expns.lock().insert(expn);
1288-
}
1289-
};
1290-
1291-
match mode {
1292-
ExpnDataEncodeMode::IncrComp => {
1293-
// Always serialize the `ExpnData` in incr comp mode
1294-
needs_data();
1295-
expn.0.encode(e)
1296-
}
1297-
ExpnDataEncodeMode::Metadata => {
1298-
let data = expn.expn_data();
1299-
// We only need to serialize the ExpnData
1300-
// if it comes from this crate.
1301-
// We currently don't serialize any hygiene information data for
1302-
// proc-macro crates: see the `SpecializedEncoder<Span>` impl
1303-
// for crate metadata.
1304-
if data.krate == LOCAL_CRATE {
1305-
needs_data();
1306-
}
1307-
data.orig_id.expect("Missing orig_id").encode(e)?;
1308-
data.krate.encode(e)
1309-
}
1336+
if !context.serialized_expns.lock().contains(&expn) {
1337+
context.latest_expns.lock().insert(expn);
13101338
}
1339+
expn.0.encode(e)
13111340
}
13121341

1313-
pub enum ExpnDataEncodeMode {
1314-
IncrComp,
1315-
Metadata,
1316-
}
1317-
1318-
pub enum ExpnDataDecodeMode<'a, F: FnOnce(CrateNum) -> &'a HygieneDecodeContext> {
1319-
IncrComp(&'a HygieneDecodeContext),
1320-
Metadata(F),
1321-
}
1322-
1323-
impl<'a> ExpnDataDecodeMode<'a, Box<dyn FnOnce(CrateNum) -> &'a HygieneDecodeContext>> {
1324-
pub fn incr_comp(ctxt: &'a HygieneDecodeContext) -> Self {
1325-
ExpnDataDecodeMode::IncrComp(ctxt)
1342+
pub fn raw_encode_expn_id<E: Encoder>(
1343+
expn: ExpnId,
1344+
context: &HygieneEncodeContext,
1345+
e: &mut E,
1346+
) -> Result<(), E::Error> {
1347+
let data = expn.expn_data();
1348+
// We only need to serialize the ExpnData
1349+
// if it comes from this crate.
1350+
// We currently don't serialize any hygiene information data for
1351+
// proc-macro crates: see the `SpecializedEncoder<Span>` impl
1352+
// for crate metadata.
1353+
if data.krate == LOCAL_CRATE {
1354+
// Record the fact that we need to serialize the corresponding
1355+
// `ExpnData`
1356+
if !context.serialized_expns.lock().contains(&expn) {
1357+
context.latest_expns.lock().insert(expn);
1358+
}
13261359
}
1360+
data.orig_id.expect("Missing orig_id").encode(e)?;
1361+
data.krate.encode(e)
13271362
}
13281363

13291364
impl<E: Encoder> Encodable<E> for SyntaxContext {

0 commit comments

Comments
 (0)