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 a03ac4e1fdba1..74dc904b6e614 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -1170,13 +1170,30 @@ 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. + // 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(); + } data.orig_id.expect("Missing orig_id").encode(e)?; data.krate.encode(e) }