diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2021-06-24 21:02:09 +0200 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2021-07-15 19:31:46 +0200 |
| commit | 47ea2ae933f4fda8e069a77f36cb6d8b21d93997 (patch) | |
| tree | b0b08cdbf6af3833928679c29d501ab15b17d3dc /compiler/rustc_span/src | |
| parent | 0a6c636c40540707cdfd542866998862e8aa72e8 (diff) | |
| download | rust-47ea2ae933f4fda8e069a77f36cb6d8b21d93997.tar.gz rust-47ea2ae933f4fda8e069a77f36cb6d8b21d93997.zip | |
Separate encoding paths.
The two paths will be modified independently in the next few commits.
Diffstat (limited to 'compiler/rustc_span/src')
| -rw-r--r-- | compiler/rustc_span/src/hygiene.rs | 139 |
1 files changed, 87 insertions, 52 deletions
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index d292f652896..ddf9e7b4255 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1076,22 +1076,74 @@ pub struct HygieneDecodeContext { remapped_expns: Lock<Vec<Option<ExpnId>>>, } -pub fn decode_expn_id<'a, D: Decoder, G>( +pub fn decode_expn_id_incrcomp<D: Decoder>( d: &mut D, - mode: ExpnDataDecodeMode<'a, G>, + context: &HygieneDecodeContext, decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>, -) -> Result<ExpnId, D::Error> -where - G: FnOnce(CrateNum) -> &'a HygieneDecodeContext, -{ +) -> Result<ExpnId, D::Error> { let index = u32::decode(d)?; - let context = match mode { - ExpnDataDecodeMode::IncrComp(context) => context, - ExpnDataDecodeMode::Metadata(get_context) => { - let krate = CrateNum::decode(d)?; - get_context(krate) + + // Do this after decoding, so that we decode a `CrateNum` + // if necessary + if index == ExpnId::root().as_u32() { + debug!("decode_expn_id: deserialized root"); + return Ok(ExpnId::root()); + } + + let outer_expns = &context.remapped_expns; + + // Ensure that the lock() temporary is dropped early + { + if let Some(expn_id) = outer_expns.lock().get(index as usize).copied().flatten() { + return Ok(expn_id); } - }; + } + + // 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 expn_id = HygieneData::with(|hygiene_data| { + if let Some(&expn_id) = hygiene_data.expn_hash_to_expn_id.get(&hash) { + return expn_id; + } + + let expn_id = ExpnId(hygiene_data.expn_data.len() as u32); + + // If we just deserialized an `ExpnData` owned by + // the local crate, its `orig_id` will be stale, + // so we need to update it to its own value. + // This only happens when we deserialize the incremental cache, + // since a crate will never decode its own metadata. + if expn_data.krate == LOCAL_CRATE { + expn_data.orig_id = Some(expn_id.0); + } + + hygiene_data.expn_data.push(Some(expn_data)); + hygiene_data.expn_hashes.push(hash); + let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id); + debug_assert!(_old_id.is_none()); + + let mut expns = outer_expns.lock(); + let new_len = index as usize + 1; + if expns.len() < new_len { + expns.resize(new_len, None); + } + expns[index as usize] = Some(expn_id); + drop(expns); + expn_id + }); + Ok(expn_id) +} + +pub fn decode_expn_id<'a, D: Decoder>( + d: &mut D, + get_context: impl FnOnce(CrateNum) -> &'a HygieneDecodeContext, + decode_data: impl FnOnce(&mut D, u32) -> Result<(ExpnData, ExpnHash), D::Error>, +) -> Result<ExpnId, D::Error> { + let index = u32::decode(d)?; + let krate = CrateNum::decode(d)?; + let context = get_context(krate); // Do this after decoding, so that we decode a `CrateNum` // if necessary @@ -1274,56 +1326,39 @@ pub fn raw_encode_syntax_context<E: Encoder>( ctxt.0.encode(e) } -pub fn raw_encode_expn_id<E: Encoder>( +pub fn raw_encode_expn_id_incrcomp<E: Encoder>( expn: ExpnId, context: &HygieneEncodeContext, - mode: ExpnDataEncodeMode, e: &mut E, ) -> Result<(), E::Error> { // Record the fact that we need to serialize the corresponding // `ExpnData` - let needs_data = || { - if !context.serialized_expns.lock().contains(&expn) { - context.latest_expns.lock().insert(expn); - } - }; - - match mode { - ExpnDataEncodeMode::IncrComp => { - // Always serialize the `ExpnData` in incr comp mode - needs_data(); - expn.0.encode(e) - } - ExpnDataEncodeMode::Metadata => { - let data = expn.expn_data(); - // 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. - if data.krate == LOCAL_CRATE { - needs_data(); - } - data.orig_id.expect("Missing orig_id").encode(e)?; - data.krate.encode(e) - } + if !context.serialized_expns.lock().contains(&expn) { + context.latest_expns.lock().insert(expn); } + expn.0.encode(e) } -pub enum ExpnDataEncodeMode { - IncrComp, - Metadata, -} - -pub enum ExpnDataDecodeMode<'a, F: FnOnce(CrateNum) -> &'a HygieneDecodeContext> { - IncrComp(&'a HygieneDecodeContext), - Metadata(F), -} - -impl<'a> ExpnDataDecodeMode<'a, Box<dyn FnOnce(CrateNum) -> &'a HygieneDecodeContext>> { - pub fn incr_comp(ctxt: &'a HygieneDecodeContext) -> Self { - ExpnDataDecodeMode::IncrComp(ctxt) +pub fn raw_encode_expn_id<E: Encoder>( + expn: ExpnId, + context: &HygieneEncodeContext, + e: &mut E, +) -> Result<(), E::Error> { + let data = expn.expn_data(); + // 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. + if data.krate == LOCAL_CRATE { + // Record the fact that we need to serialize the corresponding + // `ExpnData` + if !context.serialized_expns.lock().contains(&expn) { + context.latest_expns.lock().insert(expn); + } } + data.orig_id.expect("Missing orig_id").encode(e)?; + data.krate.encode(e) } impl<E: Encoder> Encodable<E> for SyntaxContext { |
