fix: compile-check does not record a compile whose inputs changed while it ran
Merged
HA
12h ago+51+51+01234567890123456789-10-10-01234567890123456789
Summary
- compile-check no longer reuses a compile result that was recorded for different file contents. Before this change, a source edited while csc was compiling could make a later run report what the edited file had reported, even after the file was put back.
User Impact
- To reproduce before this change:
- Edit a source to content X and run compile-check.
- While csc compiles that assembly, edit the source to Y.
- Put the source back to X and run again.
- The second run reuses the first compile and reports Y's diagnostics: errors that X does not have, or no errors where X has some.
- With this change, the second run compiles the assembly again and reports what X really has.
Changes
- The input key is computed before csc starts, but csc reads the sources while it compiles. The compile result was recorded under the key computed before the compile, so an edit during the compile was recorded under the key of the bytes before it.
- The key is now computed again just before the compile result is recorded. When it no longer matches, the result still answers this run, but nothing is recorded. The compile already removed the previous record, so the next run compiles again.
- The baseline for the changed-files check is unchanged. It already detects edits made during the compile and says so in
FastPathBaselineNotes. That step still runs after a compile whose key moved, so its note is not lost. - One visible consequence: after a compile during which an input other than the source contents changed, the next run's fallback reason changes. It used to be
no baseline: the last full compile did not record one; it is nowno baseline: no full compile of this assembly is on record, because no compile is on record. The note of the run that compiled still names the input that changed. Before this change the next run compiled in full as well, since the leftover record was under another key and could never be reused. The compile-check doc says so where it lists that reason, and where it describes edits made during a compile. - Cost: one more input-key computation per compiled assembly. It reads that assembly's sources and the references this run produced again.
Verification
- New test: an edit made during the compile and then reverted compiles again instead of being reused. Without the fix it is reused (0 compiles).
TestNonSourceInputChangedDuringCompileLeavesNoBaselinenow expects the reason above, and its comment says the compile leaves no record to reuse either.- Mutations, each restored afterwards:
- Always recording fails the new test and the test above.
- Never recording fails every reuse test, including
TestCompileUnitsReusesEveryUnitWhoseInputsDidNotMove.
cli/dispatcher:golangci-lint fmt --diffis empty;go vet ./...passes;golangci-lint runand the complexity config both report 0 issues.go test ./...andgo test -race ./internal/compilecheck/...pass.- Coverage with the CI exclusions: 94.24% (baseline 94.2).
cli/release-automation:go test ./...passes. The file-length check passes.