-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
When we serialize a Span to crate metadata, we currently throw away the SyntaxContext:
Lines 631 to 650 in 34700c1
| impl rustc_serialize::UseSpecializedEncodable for Span { | |
| fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | |
| let span = self.data(); | |
| s.emit_struct("Span", 2, |s| { | |
| s.emit_struct_field("lo", 0, |s| span.lo.encode(s))?; | |
| s.emit_struct_field("hi", 1, |s| span.hi.encode(s)) | |
| }) | |
| } | |
| } | |
| impl rustc_serialize::UseSpecializedDecodable for Span { | |
| fn default_decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> { | |
| d.read_struct("Span", 2, |d| { | |
| let lo = d.read_struct_field("lo", 0, Decodable::decode)?; | |
| let hi = d.read_struct_field("hi", 1, Decodable::decode)?; | |
| Ok(Span::with_root_ctxt(lo, hi)) | |
| }) | |
| } | |
| } |
This is because the backing HygieneData is stored in a thread-local in rustc_span, and not serialized into crate metadata.
The result is that spans deserialized from crate metadata may have less information available than spans from the current crate. If the MIR inlining pass decides to inline a function from another crate, we may end up with suboptimal messages when we invoke span.ctxt() (e.g. when emitting debuginfo, and when evaluating the caller_location intrinsic).
It would be useful if we were to serialize HygieneData into crate metadata, and deserialize spans with the proper SyntaxContext. This will also ensure that parallel compilation works properly, since storing HygieneData in a thread local will cause problems if a Span is used on multiple threads.
I'm not really sure how best to go about doing this. ExpnIds are currently unique per-crate, since they are never serialized. We need some way of making ExpnIds globally unique.