about summary refs log tree commit diff
path: root/compiler/rustc_span/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-08-21 19:35:10 +0200
committerGitHub <noreply@github.com>2024-08-21 19:35:10 +0200
commit221b53c9b0e9eb3f06efbe4a11e724f406314db9 (patch)
treee160ca9f3cc010f3f8a85bafcf2cdf3a45200bb6 /compiler/rustc_span/src
parent982c6f8721416431ec62bb0b9105c0578a9fc603 (diff)
parent07481b9e90df0860519043b54e07529003e74814 (diff)
downloadrust-221b53c9b0e9eb3f06efbe4a11e724f406314db9.tar.gz
rust-221b53c9b0e9eb3f06efbe4a11e724f406314db9.zip
Rollup merge of #127279 - bvanjoi:fix-112680, r=petrochenkov
use old ctx if has same expand environment during decode span

Fixes #112680

The root reason why #112680 failed with incremental compilation on the second attempt is the difference in `opaque` between the span of the field [`ident`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_typeck/src/expr.rs#L2348) and the span in the incremental cache at `tcx.def_ident_span(field.did)`.

-  Let's call the span of `ident` as `span_a`, which is generated by [`apply_mark_internal`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L553-L554). Its content is similar to:

```rs
span_a_ctx -> SyntaxContextData {
      opaque: span_a_ctx,
      opaque_and_semitransparent: span_a_ctx,
      // ....
}
```

- And call the span of `tcx.def_ident_span` as `span_b`, which is generated by [`decode_syntax_context`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L1390). Its content is:

```rs
span_b_ctx -> SyntaxContextData {
      opaque: span_b_ctx,
      // note `span_b_ctx` is not same as `span_a_ctx`
      opaque_and_semitransparent: span_b_ctx,
      // ....
}
```

Although they have the same `parent` (both refer to the root) and `outer_expn`, I cannot find the specific connection between them. Therefore, I chose a solution that may not be the best: give up the incremental compile cache to ensure we can use `span_a` in this case.

r?  `@petrochenkov` Do you have any advice on this? Or perhaps this solution is acceptable?
Diffstat (limited to 'compiler/rustc_span/src')
-rw-r--r--compiler/rustc_span/src/hygiene.rs8
1 files changed, 8 insertions, 0 deletions
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 434df35a515..5e1b1b44bc2 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1415,6 +1415,14 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
 
     // Overwrite the dummy data with our decoded SyntaxContextData
     HygieneData::with(|hygiene_data| {
+        if let Some(old) = hygiene_data.syntax_context_data.get(raw_id as usize)
+            && old.outer_expn == ctxt_data.outer_expn
+            && old.outer_transparency == ctxt_data.outer_transparency
+            && old.parent == ctxt_data.parent
+        {
+            ctxt_data = old.clone();
+        }
+
         let dummy = std::mem::replace(
             &mut hygiene_data.syntax_context_data[ctxt.as_u32() as usize],
             ctxt_data,