about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2021-06-27 10:38:06 +0200
committerCamille GILLOT <gillot.camille@gmail.com>2021-07-17 19:41:07 +0200
commit2fe37c5bd1cc7d6cfa176f408c2b834e1b2617bf (patch)
tree6fbc2c6730e434a7c31dc915f8e18dbf1664c9f9 /compiler
parent078dd37f882a59d4277d80b829d729bfd2b5a5c2 (diff)
downloadrust-2fe37c5bd1cc7d6cfa176f408c2b834e1b2617bf.tar.gz
rust-2fe37c5bd1cc7d6cfa176f408c2b834e1b2617bf.zip
Choose encoding format in caller code.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs9
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs10
-rw-r--r--compiler/rustc_middle/src/ty/query/on_disk_cache.rs23
-rw-r--r--compiler/rustc_span/src/hygiene.rs98
4 files changed, 55 insertions, 85 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 4b72ac86957..8b8ca987b38 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -377,7 +377,11 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
         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 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
                 .unwrap()
                 .decode((&crate_data, sess));
             (expn_data, expn_hash)
-        })
+        });
+        Ok(expn_id)
     }
 }
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 4684daef4a1..6877d6ef542 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -182,7 +182,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext {
 
 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)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
index 358d016368e..685cb3a61ec 100644
--- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
@@ -794,25 +794,26 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
 
 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 @@ where
     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)
     }
 }
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 138ec061423..198bb588142 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -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>());