Choose encoding format in caller code.
This commit is contained in:
parent
078dd37f88
commit
2fe37c5bd1
4 changed files with 55 additions and 85 deletions
|
@ -377,7 +377,11 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
|
||||||
let local_cdata = decoder.cdata();
|
let local_cdata = decoder.cdata();
|
||||||
let sess = decoder.sess.unwrap();
|
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
|
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
|
||||||
// are stored in the owning crate, to avoid duplication.
|
// are stored in the owning crate, to avoid duplication.
|
||||||
debug_assert_ne!(cnum, LOCAL_CRATE);
|
debug_assert_ne!(cnum, LOCAL_CRATE);
|
||||||
|
@ -399,7 +403,8 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.decode((&crate_data, sess));
|
.decode((&crate_data, sess));
|
||||||
(expn_data, expn_hash)
|
(expn_data, expn_hash)
|
||||||
})
|
});
|
||||||
|
Ok(expn_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext {
|
||||||
|
|
||||||
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
|
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
|
||||||
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
|
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 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
|
||||||
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
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 expn_data = decoder.expn_data;
|
||||||
|
let tcx = decoder.tcx;
|
||||||
rustc_span::hygiene::decode_expn_id_incrcomp(
|
rustc_span::hygiene::decode_expn_id_incrcomp(
|
||||||
decoder,
|
krate,
|
||||||
|
index,
|
||||||
decoder.hygiene_context,
|
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.
|
// 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.
|
// We look up the position of the associated `ExpnData` and decode it.
|
||||||
let pos = expn_data
|
let pos = expn_data
|
||||||
.get(&index)
|
.get(&index)
|
||||||
.unwrap_or_else(|| panic!("Bad index {:?} (map {:?})", index, expn_data));
|
.unwrap_or_else(|| panic!("Bad index {:?} (map {:?})", index, expn_data));
|
||||||
|
|
||||||
this.with_position(pos.to_usize(), |decoder| {
|
decoder
|
||||||
let data: (ExpnData, ExpnHash) = decode_tagged(decoder, TAG_EXPN_DATA)?;
|
.with_position(pos.to_usize(), |decoder| 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))
|
|
||||||
},
|
},
|
||||||
|
|expn_id| tcx.untracked_resolutions.cstore.decode_expn_data(tcx.sess, expn_id),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -988,7 +989,9 @@ where
|
||||||
E: 'a + OpaqueEncoder,
|
E: 'a + OpaqueEncoder,
|
||||||
{
|
{
|
||||||
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
|
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.
|
/// first and then resolved later), so we use an `Option` here.
|
||||||
local_expn_data: IndexVec<LocalExpnId, Option<ExpnData>>,
|
local_expn_data: IndexVec<LocalExpnId, Option<ExpnData>>,
|
||||||
local_expn_hashes: IndexVec<LocalExpnId, ExpnHash>,
|
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_data: FxHashMap<ExpnId, ExpnData>,
|
||||||
foreign_expn_hashes: FxHashMap<ExpnId, ExpnHash>,
|
foreign_expn_hashes: FxHashMap<ExpnId, ExpnHash>,
|
||||||
expn_hash_to_expn_id: UnhashMap<ExpnHash, ExpnId>,
|
expn_hash_to_expn_id: UnhashMap<ExpnHash, ExpnId>,
|
||||||
|
@ -1130,6 +1132,13 @@ pub struct HygieneEncodeContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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>(
|
pub fn encode<T, R>(
|
||||||
&self,
|
&self,
|
||||||
encoder: &mut T,
|
encoder: &mut T,
|
||||||
|
@ -1186,15 +1195,13 @@ pub struct HygieneDecodeContext {
|
||||||
remapped_expns: Lock<Vec<Option<LocalExpnId>>>,
|
remapped_expns: Lock<Vec<Option<LocalExpnId>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode_expn_id_incrcomp<D: Decoder>(
|
pub fn decode_expn_id_incrcomp<E>(
|
||||||
d: &mut D,
|
krate: CrateNum,
|
||||||
|
index: u32,
|
||||||
context: &HygieneDecodeContext,
|
context: &HygieneDecodeContext,
|
||||||
decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>,
|
decode_data: impl FnOnce(u32) -> Result<(ExpnData, ExpnHash), E>,
|
||||||
decode_foreign: impl FnOnce(&mut D, ExpnId) -> Result<(ExpnData, ExpnHash), D::Error>,
|
decode_foreign: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
|
||||||
) -> Result<ExpnId, D::Error> {
|
) -> Result<ExpnId, E> {
|
||||||
let krate = CrateNum::decode(d)?;
|
|
||||||
let index = u32::decode(d)?;
|
|
||||||
|
|
||||||
// Do this after decoding, so that we decode a `CrateNum`
|
// Do this after decoding, so that we decode a `CrateNum`
|
||||||
// if necessary
|
// if necessary
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
|
@ -1203,23 +1210,7 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if krate != LOCAL_CRATE {
|
if krate != LOCAL_CRATE {
|
||||||
let expn_id = ExpnId { krate, local_id: ExpnIndex::from_u32(index) };
|
let expn_id = decode_expn_id(krate, index, decode_foreign);
|
||||||
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
|
|
||||||
});
|
|
||||||
return Ok(expn_id);
|
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
|
// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
|
||||||
// other ExpnIds
|
// 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);
|
debug_assert_eq!(krate, expn_data.krate);
|
||||||
|
|
||||||
let expn_id = HygieneData::with(|hygiene_data| {
|
let expn_id = HygieneData::with(|hygiene_data| {
|
||||||
|
@ -1269,18 +1260,14 @@ pub fn decode_expn_id_incrcomp<D: Decoder>(
|
||||||
Ok(expn_id)
|
Ok(expn_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode_expn_id<D: Decoder>(
|
pub fn decode_expn_id(
|
||||||
d: &mut D,
|
krate: CrateNum,
|
||||||
decode_data: impl FnOnce(CrateNum, ExpnIndex) -> (ExpnData, ExpnHash),
|
index: u32,
|
||||||
) -> Result<ExpnId, D::Error> {
|
decode_data: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
|
||||||
let krate = CrateNum::decode(d)?;
|
) -> ExpnId {
|
||||||
let index = u32::decode(d)?;
|
|
||||||
|
|
||||||
// Do this after decoding, so that we decode a `CrateNum`
|
|
||||||
// if necessary
|
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
debug!("decode_expn_id: deserialized root");
|
debug!("decode_expn_id: deserialized root");
|
||||||
return Ok(ExpnId::root());
|
return ExpnId::root();
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = ExpnIndex::from_u32(index);
|
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.
|
// Fast path if the expansion has already been decoded.
|
||||||
if HygieneData::with(|hygiene_data| hygiene_data.foreign_expn_data.contains_key(&expn_id)) {
|
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
|
// Don't decode the data inside `HygieneData::with`, since we need to recursively decode
|
||||||
// other ExpnIds
|
// 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!(krate, expn_data.krate);
|
||||||
debug_assert_eq!(Some(index.as_u32()), expn_data.orig_id);
|
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());
|
debug_assert!(_old_id.is_none());
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(expn_id)
|
expn_id
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
|
// Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
|
||||||
|
@ -1448,39 +1435,6 @@ pub fn raw_encode_syntax_context<E: Encoder>(
|
||||||
ctxt.0.encode(e)
|
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 {
|
impl<E: Encoder> Encodable<E> for SyntaxContext {
|
||||||
default fn encode(&self, _: &mut E) -> Result<(), E::Error> {
|
default fn encode(&self, _: &mut E) -> Result<(), E::Error> {
|
||||||
panic!("cannot encode `SyntaxContext` with `{}`", std::any::type_name::<E>());
|
panic!("cannot encode `SyntaxContext` with `{}`", std::any::type_name::<E>());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue