Change:
I encountered an ICE today. Below you find the backtrace of running . I ran afterwards and the ICE vanished, so it seams to be connected to incremental compilation. If required I can attach the full project including the build directories, as I zipped it after the ICE.
If possible, we would most of all appreciate a reproducer that works on the playground (this will facilitate fixing the bug faster) but if that's not possible a link to the zip would be good also.
Sorry, I didn't had enough time for it lately. Are there any guidelines how to track down such an incremental compilation error? Unfortunately I cannot recall the steps I've done. I've minimized the code in such a way, that removing any more causes the ICE to vanish. I'll attach this Zip-archive, so somebody else might have a look. Note, that this is not yet a MCVE.
any luck so far? The code looks good, now you have to recall what you did (rename a variable, changed something from a struct to a trait? Deleted members of a struct? Added functions? Removed them?) I know it's hard to debug incremental bugs (I encountered two so far). Any chance that you can tell us, what you did between , and the second ?
Unfortunately no. I tried to recall things, that I've done at this point, but any change I made either also ICEs or compiles fine. I've tried to reproduce this by writing the same code again, but obviously I write it a little bit different now, so I cannot get it to crash. Are there any tips how to deal with those incremental compilation crashes? Trying to reproduce like I'm doing it now is poking around in the dark.
As said, it could be anything ^^ Here are some examples I've seen so far in the wild:
Okay, thanks, I'll have a look at the linked issues :smiley:
Today I encountered the same ICE with "the len is 1077 but the index is 1077". I was writing and running some integration tests; it involved a serialization format (with Serde). I changed an array constant in a test case, then the panic occurred. When I changed it again, the ICE went away, and then I couldn't reproduce it anymore, not even with the value that seems to have caused it in the first place.
We've got the same bug with the len number of 30, not on my machine but on (the CI account isn't mine). If you guys know how to do the magic to pull the build artifacts from travis - you're welcome, CI account's owner seems willing to cooperate
Maybe the commit succession can be of interest to investigate the bug.
I got this same panic, and it also went away after a clean build.
Another one here, looks like the same problem and it also went away for now after .

Discussion:
return; } <ins> let (_, line_hi, col_hi) = match ctx.byte_pos_to_line_and_col(span.hi) { Some(pos) => pos, None => { Hash::hash(&TAG_INVALID_SPAN, hasher); span.ctxt.hash_stable(ctx, hasher); return; } }; </ins> Hash::hash(&TAG_VALID_SPAN, hasher); // We truncate the stable ID hash and line and column numbers. The chances // of causing a collision this way should be minimal. Hash::hash(&(file_lo.name_hash as u64), hasher); <del> let col = (col_lo.0 as u64) & 0xFF; let line = ((line_lo as u64) & 0xFF_FF_FF) << 8; let len = ((span.hi - span.lo).0 as u64) << 32; let line_col_len = col | line | len; Hash::hash(&line_col_len, hasher); </del> <ins> // Hash both the length and the end location (line/column) of a span. If we // hash only the length, for example, then two otherwise equal spans with // different end locations will have the same hash. This can cause a problem // during incremental compilation wherein a previous result for a query that // depends on the end location of a span will be incorrectly reused when the // end location of the span it depends on has changed (see issue #74890). A // similar analysis applies if some query depends specifically on the length // of the span, but we only hash the end location. So hash both. let col_lo_trunc = (col_lo.0 as u64) & 0xFF; let line_lo_trunc = ((line_lo as u64) & 0xFF_FF_FF) << 8; let col_hi_trunc = (col_hi.0 as u64) & 0xFF << 32; let line_hi_trunc = ((line_hi as u64) & 0xFF_FF_FF) << 40; let col_line = col_lo_trunc | line_lo_trunc | col_hi_trunc | line_hi_trunc; let len = (span.hi - span.lo).0; Hash::hash(&col_line, hasher); Hash::hash(&len, hasher); </ins> span.ctxt.hash_stable(ctx, hasher); } }

<ins> include ../../run-make-fulldeps/tools.mk # FIXME https://github.com/rust-lang/rust/issues/78911 # ignore-32bit wrong/no cross compiler and sometimes we pass wrong gcc args (-m64) # Tests that we don't ICE during incremental compilation after modifying a # function span such that its previous end line exceeds the number of lines # in the new file, but its start line/column and length remain the same. SRC=$(TMPDIR)/src INCR=$(TMPDIR)/incr all: mkdir $(SRC) mkdir $(INCR) cp a.rs $(SRC)/main.rs $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs cp b.rs $(SRC)/main.rs $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs </ins>

<ins> fn main() { // foo must be used. foo(); } // For this test to operate correctly, foo's body must start on exactly the same // line and column and have the exact same length in bytes in a.rs and b.rs. In // a.rs, the body must end on a line number which does not exist in b.rs. // Basically, avoid modifying this file, including adding or removing whitespace! fn foo() { assert_eq!(1, 1); } </ins>

<ins> fn main() { // foo must be used. foo(); } // For this test to operate correctly, foo's body must start on exactly the same // line and column and have the exact same length in bytes in a.rs and b.rs. In // a.rs, the body must end on a line number which does not exist in b.rs. // Basically, avoid modifying this file, including adding or removing whitespace! fn foo() { assert_eq!(1, 1);//// } </ins>

include ../../run-make-fulldeps/tools.mk <ins> # FIXME https://github.com/rust-lang/rust/issues/78911 </ins> # ignore-32bit wrong/no cross compiler and sometimes we pass wrong gcc args (-m64) all: foo