@@ -184,11 +184,48 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
184
184
185
185
impl < ' a , ' tcx > Encodable < EncodeContext < ' a , ' tcx > > for Span {
186
186
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) ?;
189
224
}
190
225
191
- let span = self . data ( ) ;
226
+ if self . is_dummy ( ) {
227
+ return TAG_PARTIAL_SPAN . encode ( s) ;
228
+ }
192
229
193
230
// The Span infrastructure should make sure that this invariant holds:
194
231
debug_assert ! ( span. lo <= span. hi) ;
@@ -203,7 +240,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
203
240
if !s. source_file_cache . 0 . contains ( span. hi ) {
204
241
// Unfortunately, macro expansion still sometimes generates Spans
205
242
// that malformed in this way.
206
- return TAG_INVALID_SPAN . encode ( s) ;
243
+ return TAG_PARTIAL_SPAN . encode ( s) ;
207
244
}
208
245
209
246
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 {
259
296
let len = hi - lo;
260
297
len. encode ( s) ?;
261
298
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
-
299
299
if tag == TAG_VALID_SPAN_FOREIGN {
300
300
// This needs to be two lines to avoid holding the `s.source_file_cache`
301
301
// while calling `cnum.encode(s)`
0 commit comments