@@ -184,11 +184,48 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
184184
185185impl < ' a , ' tcx > Encodable < EncodeContext < ' a , ' tcx > > for Span {
186186 fn encode ( & self , s : & mut EncodeContext < ' a , ' tcx > ) -> opaque:: EncodeResult {
187- if * self == rustc_span:: DUMMY_SP {
188- return TAG_INVALID_SPAN . encode ( s) ;
187+ let span = self . data ( ) ;
188+
189+ // Don't serialize any `SyntaxContext`s from a proc-macro crate,
190+ // since we don't load proc-macro dependencies during serialization.
191+ // This means that any hygiene information from macros used *within*
192+ // a proc-macro crate (e.g. invoking a macro that expands to a proc-macro
193+ // definition) will be lost.
194+ //
195+ // This can show up in two ways:
196+ //
197+ // 1. Any hygiene information associated with identifier of
198+ // a proc macro (e.g. `#[proc_macro] pub fn $name`) will be lost.
199+ // Since proc-macros can only be invoked from a different crate,
200+ // real code should never need to care about this.
201+ //
202+ // 2. Using `Span::def_site` or `Span::mixed_site` will not
203+ // include any hygiene information associated with the definition
204+ // site. This means that a proc-macro cannot emit a `$crate`
205+ // identifier which resolves to one of its dependencies,
206+ // which also should never come up in practice.
207+ //
208+ // Additionally, this affects `Span::parent`, and any other
209+ // span inspection APIs that would otherwise allow traversing
210+ // the `SyntaxContexts` associated with a span.
211+ //
212+ // None of these user-visible effects should result in any
213+ // cross-crate inconsistencies (getting one behavior in the same
214+ // crate, and a different behavior in another crate) due to the
215+ // limited surface that proc-macros can expose.
216+ //
217+ // IMPORTANT: If this is ever changed, be sure to update
218+ // `rustc_span::hygiene::raw_encode_expn_id` to handle
219+ // encoding `ExpnData` for proc-macro crates.
220+ if s. is_proc_macro {
221+ SyntaxContext :: root ( ) . encode ( s) ?;
222+ } else {
223+ span. ctxt . encode ( s) ?;
189224 }
190225
191- let span = self . data ( ) ;
226+ if self . is_dummy ( ) {
227+ return TAG_PARTIAL_SPAN . encode ( s) ;
228+ }
192229
193230 // The Span infrastructure should make sure that this invariant holds:
194231 debug_assert ! ( span. lo <= span. hi) ;
@@ -203,7 +240,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
203240 if !s. source_file_cache . 0 . contains ( span. hi ) {
204241 // Unfortunately, macro expansion still sometimes generates Spans
205242 // that malformed in this way.
206- return TAG_INVALID_SPAN . encode ( s) ;
243+ return TAG_PARTIAL_SPAN . encode ( s) ;
207244 }
208245
209246 let source_files = s. required_source_files . as_mut ( ) . expect ( "Already encoded SourceMap!" ) ;
@@ -259,43 +296,6 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
259296 let len = hi - lo;
260297 len. encode ( s) ?;
261298
262- // Don't serialize any `SyntaxContext`s from a proc-macro crate,
263- // since we don't load proc-macro dependencies during serialization.
264- // This means that any hygiene information from macros used *within*
265- // a proc-macro crate (e.g. invoking a macro that expands to a proc-macro
266- // definition) will be lost.
267- //
268- // This can show up in two ways:
269- //
270- // 1. Any hygiene information associated with identifier of
271- // a proc macro (e.g. `#[proc_macro] pub fn $name`) will be lost.
272- // Since proc-macros can only be invoked from a different crate,
273- // real code should never need to care about this.
274- //
275- // 2. Using `Span::def_site` or `Span::mixed_site` will not
276- // include any hygiene information associated with the definition
277- // site. This means that a proc-macro cannot emit a `$crate`
278- // identifier which resolves to one of its dependencies,
279- // which also should never come up in practice.
280- //
281- // Additionally, this affects `Span::parent`, and any other
282- // span inspection APIs that would otherwise allow traversing
283- // the `SyntaxContexts` associated with a span.
284- //
285- // None of these user-visible effects should result in any
286- // cross-crate inconsistencies (getting one behavior in the same
287- // crate, and a different behavior in another crate) due to the
288- // limited surface that proc-macros can expose.
289- //
290- // IMPORTANT: If this is ever changed, be sure to update
291- // `rustc_span::hygiene::raw_encode_expn_id` to handle
292- // encoding `ExpnData` for proc-macro crates.
293- if s. is_proc_macro {
294- SyntaxContext :: root ( ) . encode ( s) ?;
295- } else {
296- span. ctxt . encode ( s) ?;
297- }
298-
299299 if tag == TAG_VALID_SPAN_FOREIGN {
300300 // This needs to be two lines to avoid holding the `s.source_file_cache`
301301 // while calling `cnum.encode(s)`
0 commit comments