Change:
<!-- nightly-2020-10-05 The same thing happen on the latest nightly too --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Can you please try with a recent nightly and see if it works? E.g. try with 2020-12-22.
This looks like a legitimate issue with . In the initial successful run, we get the following result (I some extra logging locally): On the second (modified incremental) run, we get this result: The return value of on the same input differs between compilation sessions - we get with an empty incremental cache, but we get with a partially outdated cache.
The issue is caused by the way that we handle regions in the evaluation cache. When we insert a result into the evaluation cache (either or , we use a 'freshened' version of the original as the key. The 'freshened' has all non-late-bound regions erased. Unfortunately, this can lead to issues if we try to evaluate the following two predicates: When we evaluate , we'll get , since the region parameter in our trait ref is known to match the impl. We will then cache the result as . If we later try to evaluate , we will end up matching the evaluation cache entry, giving us a result of . However, we should have gotten a result of , since we don't know that holds. This is really difficult to observe in practice, for a number of reasons: The relevant trait predicates need to get evaluated, not just registered in a . Trait evaluation usually goes through the query, which canonicalizes the regions in the input trait ref. To end up trying to evaluate , we need to end up calling on it, with a different original trait ref used in the original query. Using instead of only seems to cause an error when it results in the incremental hash changing (I don't know if it's possible to weaponize this into extending a lifetime). As a result, I haven't been able to minimize this.
cc
Assigning as discussed as part of the and removing .
ping cleanup might be interesting to follow up on the great analysis and see how can be reproduced on a smaller scale, possibly checking if it's a WASM target only issue and if it also happen on other than nightlies
Hey Cleanup Crew ICE-breakers! This bug has been identified as a good "Cleanup ICE-breaking candidate". In case it's useful, here are some [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev- cc
I was able to reproduce this on in the rust-analyzer repo with , so probably unrelated to . in the rust analyzer repo: I am able to reproduce on and if I enforce the flag. edit: also reproduces with 1.47 and 1.46
Adjusted the labels and title according to Aaron's analysis, the big question regarding this issue being:
Much smaller repro: With the sample above, I can reproduce the ICE by inserting an empty line in the project inside :thinking: ( check out regex , add the line and build with incr verification)
reduced as adding empty lines to this file will cause the ICE
Reduced even further
It looks like there are actually two different issues going on here. The original issue is a bug with caching in , described in The other is a bug that shows up as a changed result. This appears to be completely unrelated, as the caching bug described above shouldn't result in any changes to the MIR of a function. I think this bug is actually due to the way we handle hygiene information in incremental compilation - it goes away if is replaced with the result from . I came across a very similar bug in some other work on incremental compilation, and I'll continue to investigate.
Let's continue the discussion of the trait evaluation issue in
cpuinfo:

Discussion:
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; <del> const TAG_VALID_SPAN: u8 = 0; const TAG_INVALID_SPAN: u8 = 1; </del> <ins> // A normal span encoded with both location information and a `SyntaxContext` const TAG_FULL_SPAN: u8 = 0; // A partial span with no location information, encoded only with a `SyntaxContext` const TAG_PARTIAL_SPAN: u8 = 1; </ins> const TAG_SYNTAX_CONTEXT: u8 = 0; const TAG_EXPN_DATA: u8 = 1;

fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> { let tag: u8 = Decodable::decode(decoder)?; <del> if tag == TAG_INVALID_SPAN { return Ok(DUMMY_SP); </del> <ins> if tag == TAG_PARTIAL_SPAN { let ctxt = SyntaxContext::decode(decoder)?; return Ok(DUMMY_SP.with_ctxt(ctxt)); </ins> } else { <del> debug_assert_eq!(tag, TAG_VALID_SPAN); </del> <ins> debug_assert_eq!(tag, TAG_FULL_SPAN); </ins> } let file_lo_index = SourceFileIndex::decode(decoder)?;

{ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> { if *self == DUMMY_SP { <del> return TAG_INVALID_SPAN.encode(s); </del> <ins> TAG_PARTIAL_SPAN.encode(s)?; return SyntaxContext::root().encode(s); </ins> } let span_data = self.data(); <del> let (file_lo, line_lo, col_lo) = match s.source_map.byte_pos_to_line_and_col(span_data.lo) { Some(pos) => pos, None => return TAG_INVALID_SPAN.encode(s), </del> <ins> let pos = s.source_map.byte_pos_to_line_and_col(span_data.lo); let partial_span = match &pos { Some((file_lo, _, _)) => !file_lo.contains(span_data.hi), None => true, </ins> }; <del> if !file_lo.contains(span_data.hi) { return TAG_INVALID_SPAN.encode(s); </del> <ins> if partial_span { TAG_PARTIAL_SPAN.encode(s)?; return span_data.ctxt.encode(s); </ins> } <ins> let (file_lo, line_lo, col_lo) = pos.unwrap(); </ins> let len = span_data.hi - span_data.lo; let source_file_index = s.source_file_index(file_lo); <del> TAG_VALID_SPAN.encode(s)?; </del> <ins> TAG_FULL_SPAN.encode(s)?; </ins> source_file_index.encode(s)?; line_lo.encode(s)?; col_lo.encode(s)?;

return; } <del> if *self == DUMMY_SP { </del> <ins> if self.is_dummy() { </ins> Hash::hash(&TAG_INVALID_SPAN, hasher); <ins> self.ctxt().hash_stable(ctx, hasher); </ins> return; }

<ins> // Regression test for issue #80336 // Test that we properly handle encoding, decoding, and hashing // of spans with an invalid location and non-root `SyntaxContext` // revisions:rpass1 rpass2 // only-x86_64 pub fn main() { let _ = is_x86_feature_detected!("avx2"); } </ins>