Choose encoding format in caller code.
This commit is contained in:
parent
078dd37f88
commit
2fe37c5bd1
@ -377,7 +377,11 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<ExpnId, String> {
|
||||
let local_cdata = decoder.cdata();
|
||||
let sess = decoder.sess.unwrap();
|
||||
|
||||
rustc_span::hygiene::decode_expn_id(decoder, |cnum, index| {
|
||||
let cnum = CrateNum::decode(decoder)?;
|
||||
let index = u32::decode(decoder)?;
|
||||
|
||||
let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| {
|
||||
let ExpnId { krate: cnum, local_id: index } = expn_id;
|
||||
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
|
||||
// are stored in the owning crate, to avoid duplication.
|
||||
debug_assert_ne!(cnum, LOCAL_CRATE);
|
||||
@ -399,7 +403,8 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<ExpnId, String> {
|
||||
.unwrap()
|
||||
.decode((&crate_data, sess));
|
||||
(expn_data, expn_hash)
|
||||
})
|
||||
});
|
||||
Ok(expn_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,15 @@ fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
|
||||
|
||||
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
|
||||
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
|
||||
rustc_span::hygiene::raw_encode_expn_id(*self, &s.hygiene_ctxt, s)
|
||||
if self.krate == LOCAL_CRATE {
|
||||
// We will only write details for local expansions. Non-local expansions will fetch
|
||||
// data from the corresponding crate's metadata.
|
||||
// FIXME(#43047) FIXME(#74731) We may eventually want to avoid relying on external
|
||||
// metadata from proc-macro crates.
|
||||
s.hygiene_ctxt.schedule_expn_data_for_encoding(*self);
|
||||
}
|
||||
self.krate.encode(s)?;
|
||||
self.local_id.encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,25 +794,26 @@ fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
||||
|
||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
|
||||
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
||||
let krate = CrateNum::decode(decoder)?;
|
||||
let index = u32::decode(decoder)?;
|
||||
|
||||
let expn_data = decoder.expn_data;
|
||||
let tcx = decoder.tcx;
|
||||
rustc_span::hygiene::decode_expn_id_incrcomp(
|
||||
decoder,
|
||||
krate,
|
||||
index,
|
||||
decoder.hygiene_context,
|
||||
|this, index| {
|
||||
|index| -> Result<(ExpnData, ExpnHash), _> {
|
||||
// This closure is invoked if we haven't already decoded the data for the `ExpnId` we are deserializing.
|
||||
// We look up the position of the associated `ExpnData` and decode it.
|
||||
let pos = expn_data
|
||||
.get(&index)
|
||||
.unwrap_or_else(|| panic!("Bad index {:?} (map {:?})", index, expn_data));
|
||||
|
||||
this.with_position(pos.to_usize(), |decoder| {
|
||||
let data: (ExpnData, ExpnHash) = decode_tagged(decoder, TAG_EXPN_DATA)?;
|
||||
Ok(data)
|
||||
})
|
||||
},
|
||||
|this, expn_id| {
|
||||
Ok(this.tcx.untracked_resolutions.cstore.decode_expn_data(this.tcx.sess, expn_id))
|
||||
decoder
|
||||
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA))
|
||||
},
|
||||
|expn_id| tcx.untracked_resolutions.cstore.decode_expn_data(tcx.sess, expn_id),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -988,7 +989,9 @@ impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for ExpnId
|
||||
E: 'a + OpaqueEncoder,
|
||||
{
|
||||
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
|
||||
rustc_span::hygiene::raw_encode_expn_id_incrcomp(*self, s.hygiene_context, s)
|
||||
s.hygiene_context.schedule_expn_data_for_encoding(*self);
|
||||
self.krate.encode(s)?;
|
||||
self.local_id.as_u32().encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,6 +261,8 @@ pub struct HygieneData {
|
||||
/// first and then resolved later), so we use an `Option` here.
|
||||
local_expn_data: IndexVec<LocalExpnId, Option<ExpnData>>,
|
||||
local_expn_hashes: IndexVec<LocalExpnId, ExpnHash>,
|
||||
/// Data and hash information from external crates. We may eventually want to remove these
|
||||
/// maps, and fetch the information directly from the other crate's metadata like DefIds do.
|
||||
foreign_expn_data: FxHashMap<ExpnId, ExpnData>,
|
||||
foreign_expn_hashes: FxHashMap<ExpnId, ExpnHash>,
|
||||
expn_hash_to_expn_id: UnhashMap<ExpnHash, ExpnId>,
|
||||
@ -1130,6 +1132,13 @@ pub struct HygieneEncodeContext {
|
||||
}
|
||||
|
||||
impl HygieneEncodeContext {
|
||||
/// Record the fact that we need to serialize the corresponding `ExpnData`.
|
||||
pub fn schedule_expn_data_for_encoding(&self, expn: ExpnId) {
|
||||
if !self.serialized_expns.lock().contains(&expn) {
|
||||
self.latest_expns.lock().insert(expn);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode<T, R>(
|
||||
&self,
|
||||
encoder: &mut T,
|
||||
@ -1186,15 +1195,13 @@ pub struct HygieneDecodeContext {
|
||||
remapped_expns: Lock<Vec<Option<LocalExpnId>>>,
|
||||
}
|
||||
|
||||
pub fn decode_expn_id_incrcomp<D: Decoder>(
|
||||
d: &mut D,
|
||||
pub fn decode_expn_id_incrcomp<E>(
|
||||
krate: CrateNum,
|
||||
index: u32,
|
||||
context: &HygieneDecodeContext,
|
||||
decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>,
|
||||
decode_foreign: impl FnOnce(&mut D, ExpnId) -> Result<(ExpnData, ExpnHash), D::Error>,
|
||||
) -> Result<ExpnId, D::Error> {
|
||||
let krate = CrateNum::decode(d)?;
|
||||
let index = u32::decode(d)?;
|
||||
|
||||
decode_data: impl FnOnce(u32) -> Result<(ExpnData, ExpnHash), E>,
|
||||
decode_foreign: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
|
||||
) -> Result<ExpnId, E> {
|
||||
// Do this after decoding, so that we decode a `CrateNum`
|
||||
// if necessary
|
||||
if index == 0 {
|
||||
@ -1203,23 +1210,7 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
|
||||
}
|
||||
|
||||
if krate != LOCAL_CRATE {
|
||||
let expn_id = ExpnId { krate, local_id: ExpnIndex::from_u32(index) };
|
||||
if HygieneData::with(|hygiene_data| hygiene_data.foreign_expn_data.contains_key(&expn_id)) {
|
||||
return Ok(expn_id);
|
||||
}
|
||||
let (expn_data, hash) = decode_foreign(d, expn_id)?;
|
||||
debug_assert_eq!(krate, expn_data.krate);
|
||||
debug_assert_eq!(expn_data.orig_id, Some(index));
|
||||
let expn_id = HygieneData::with(|hygiene_data| {
|
||||
debug_assert_eq!(expn_data.orig_id, Some(index));
|
||||
let _old_data = hygiene_data.foreign_expn_data.insert(expn_id, expn_data);
|
||||
debug_assert!(_old_data.is_none());
|
||||
let _old_hash = hygiene_data.foreign_expn_hashes.insert(expn_id, hash);
|
||||
debug_assert!(_old_hash.is_none());
|
||||
let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
|
||||
debug_assert!(_old_id.is_none());
|
||||
expn_id
|
||||
});
|
||||
let expn_id = decode_expn_id(krate, index, decode_foreign);
|
||||
return Ok(expn_id);
|
||||
}
|
||||
|
||||
@ -1234,7 +1225,7 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
|
||||
|
||||
// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
|
||||
// other ExpnIds
|
||||
let (mut expn_data, hash) = decode_data(d, index)?;
|
||||
let (mut expn_data, hash) = decode_data(index)?;
|
||||
debug_assert_eq!(krate, expn_data.krate);
|
||||
|
||||
let expn_id = HygieneData::with(|hygiene_data| {
|
||||
@ -1269,18 +1260,14 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
|
||||
Ok(expn_id)
|
||||
}
|
||||
|
||||
pub fn decode_expn_id<D: Decoder>(
|
||||
d: &mut D,
|
||||
decode_data: impl FnOnce(CrateNum, ExpnIndex) -> (ExpnData, ExpnHash),
|
||||
) -> Result<ExpnId, D::Error> {
|
||||
let krate = CrateNum::decode(d)?;
|
||||
let index = u32::decode(d)?;
|
||||
|
||||
// Do this after decoding, so that we decode a `CrateNum`
|
||||
// if necessary
|
||||
pub fn decode_expn_id(
|
||||
krate: CrateNum,
|
||||
index: u32,
|
||||
decode_data: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
|
||||
) -> ExpnId {
|
||||
if index == 0 {
|
||||
debug!("decode_expn_id: deserialized root");
|
||||
return Ok(ExpnId::root());
|
||||
return ExpnId::root();
|
||||
}
|
||||
|
||||
let index = ExpnIndex::from_u32(index);
|
||||
@ -1291,12 +1278,12 @@ pub fn decode_expn_id<D: Decoder>(
|
||||
|
||||
// Fast path if the expansion has already been decoded.
|
||||
if HygieneData::with(|hygiene_data| hygiene_data.foreign_expn_data.contains_key(&expn_id)) {
|
||||
return Ok(expn_id);
|
||||
return expn_id;
|
||||
}
|
||||
|
||||
// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
|
||||
// other ExpnIds
|
||||
let (expn_data, hash) = decode_data(krate, index);
|
||||
let (expn_data, hash) = decode_data(expn_id);
|
||||
debug_assert_eq!(krate, expn_data.krate);
|
||||
debug_assert_eq!(Some(index.as_u32()), expn_data.orig_id);
|
||||
|
||||
@ -1309,7 +1296,7 @@ pub fn decode_expn_id<D: Decoder>(
|
||||
debug_assert!(_old_id.is_none());
|
||||
});
|
||||
|
||||
Ok(expn_id)
|
||||
expn_id
|
||||
}
|
||||
|
||||
// Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
|
||||
@ -1448,39 +1435,6 @@ pub fn raw_encode_syntax_context<E: Encoder>(
|
||||
ctxt.0.encode(e)
|
||||
}
|
||||
|
||||
pub fn raw_encode_expn_id_incrcomp<E: Encoder>(
|
||||
expn: ExpnId,
|
||||
context: &HygieneEncodeContext,
|
||||
e: &mut E,
|
||||
) -> Result<(), E::Error> {
|
||||
// Record the fact that we need to serialize the corresponding `ExpnData`
|
||||
if !context.serialized_expns.lock().contains(&expn) {
|
||||
context.latest_expns.lock().insert(expn);
|
||||
}
|
||||
expn.krate.encode(e)?;
|
||||
expn.local_id.as_u32().encode(e)
|
||||
}
|
||||
|
||||
pub fn raw_encode_expn_id<E: Encoder>(
|
||||
expn: ExpnId,
|
||||
context: &HygieneEncodeContext,
|
||||
e: &mut E,
|
||||
) -> Result<(), E::Error> {
|
||||
// We only need to serialize the ExpnData
|
||||
// if it comes from this crate.
|
||||
// We currently don't serialize any hygiene information data for
|
||||
// proc-macro crates: see the `SpecializedEncoder<Span>` impl
|
||||
// for crate metadata.
|
||||
// Record the fact that we need to serialize the corresponding `ExpnData`
|
||||
if expn.krate == LOCAL_CRATE {
|
||||
if !context.serialized_expns.lock().contains(&expn) {
|
||||
context.latest_expns.lock().insert(expn);
|
||||
}
|
||||
}
|
||||
expn.krate.encode(e)?;
|
||||
expn.local_id.as_u32().encode(e)
|
||||
}
|
||||
|
||||
impl<E: Encoder> Encodable<E> for SyntaxContext {
|
||||
default fn encode(&self, _: &mut E) -> Result<(), E::Error> {
|
||||
panic!("cannot encode `SyntaxContext` with `{}`", std::any::type_name::<E>());
|
||||
|
Loading…
Reference in New Issue
Block a user