Auto merge of #76256 - tgnottingham:issue-74890, r=nikomatsakis

incr-comp: hash and serialize span end line/column

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. 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.

Fix #46744, fix #59954, fix #63161, fix #73640, fix #73967, fix #74890, fix #75900

---

See #74890 for a more in-depth analysis.

I haven't thought about what other problems this root cause could be responsible for. Please let me know if anything springs to mind. I believe the issue has existed since the inception of incremental compilation.
This commit is contained in:
bors 2020-11-12 15:34:09 +00:00
commit 9722952f0b
5 changed files with 74 additions and 5 deletions

View file

@ -0,0 +1,19 @@
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

View file

@ -0,0 +1,16 @@
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);
}

View file

@ -0,0 +1,12 @@
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);////
}

View file

@ -1,5 +1,6 @@
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)
all: foo