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