@@ -187,11 +187,48 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
187
187
188
188
impl < ' a , ' tcx > Encodable < EncodeContext < ' a , ' tcx > > for Span {
189
189
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) ?;
192
227
}
193
228
194
- let span = self . data ( ) ;
229
+ if self . is_dummy ( ) {
230
+ return TAG_PARTIAL_SPAN . encode ( s) ;
231
+ }
195
232
196
233
// The Span infrastructure should make sure that this invariant holds:
197
234
debug_assert ! ( span. lo <= span. hi) ;
@@ -206,7 +243,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
206
243
if !s. source_file_cache . 0 . contains ( span. hi ) {
207
244
// Unfortunately, macro expansion still sometimes generates Spans
208
245
// that malformed in this way.
209
- return TAG_INVALID_SPAN . encode ( s) ;
246
+ return TAG_PARTIAL_SPAN . encode ( s) ;
210
247
}
211
248
212
249
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 {
262
299
let len = hi - lo;
263
300
len. encode ( s) ?;
264
301
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
-
302
302
if tag == TAG_VALID_SPAN_FOREIGN {
303
303
// This needs to be two lines to avoid holding the `s.source_file_cache`
304
304
// while calling `cnum.encode(s)`
0 commit comments