From 955aebf529787fd49b05f07346e3de97da31cb09 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 4 Aug 2020 04:53:28 -0400 Subject: [PATCH 1/2] Don't serialize ExpnData for foreign crates When we encode an ExpnId into the crate metadata, we write out the CrateNum of the crate that 'owns' the corresponding `ExpnData`, which is later used to decode the `ExpnData` from its owning crate. However, we current serialize the `ExpnData` for all `ExpnIds` that we serialize, even if the `ExpnData` was already serialized into a foreign crate. This commit skips encoding this kind of `ExpnData`, which should hopefully speed up metadata encoding and reduce the total metadata size. --- src/librustc_span/hygiene.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs index a03ac4e1fdba1..87c2c1e6bd08b 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -1170,13 +1170,27 @@ pub fn raw_encode_expn_id( mode: ExpnDataEncodeMode, e: &mut E, ) -> Result<(), E::Error> { - if !context.serialized_expns.lock().contains(&expn) { - context.latest_expns.lock().insert(expn); - } + // 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 => expn.0.encode(e), + 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. + if data.krate == LOCAL_CRATE { + needs_data(); + } data.orig_id.expect("Missing orig_id").encode(e)?; data.krate.encode(e) } From ef49032297b90e7010b08db04d569dd8a5f0a8f2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 9 Aug 2020 08:42:41 -0400 Subject: [PATCH 2/2] Add comment about the lack of `ExpnData` serialization for proc-macro crates --- src/librustc_metadata/rmeta/encoder.rs | 4 ++++ src/librustc_span/hygiene.rs | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 352b8bff7e2fb..6872693a66cb8 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -280,6 +280,10 @@ impl<'a, 'tcx> SpecializedEncoder for EncodeContext<'a, 'tcx> { // cross-crate inconsistencies (getting one behavior in the same // crate, and a different behavior in another crate) due to the // limited surface that proc-macros can expose. + // + // IMPORTANT: If this is ever changed, be sure to update + // `rustc_span::hygiene::raw_encode_expn_id` to handle + // encoding `ExpnData` for proc-macro crates. if self.is_proc_macro { SyntaxContext::root().encode(self)?; } else { diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs index 87c2c1e6bd08b..74dc904b6e614 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -1188,6 +1188,9 @@ pub fn raw_encode_expn_id( 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` impl + // for crate metadata. if data.krate == LOCAL_CRATE { needs_data(); }