Repository navigation
Join a record update to its base's type class as an occurrence - #12683
Open
Karakatiza666 wants to merge 1 commit into
Open
Karakatiza666 wants to merge 1 commit into
Karakatiza666 wants to merge 1 commit into
Conversation
resumeRecordUpdateCheck unified (base, update). Unification keeps its second operand as the checked representative, so the update's variable became the representative of the base's whole class. When the update then mismatched its annotation, poisonOnMismatch poisoned that whole class, and the base binding became erroneous. Post-check then lowered an earlier constant that read the base, met the erroneous type, and panicked with "erroneous checked type reached Monotype instantiation". Unify (update, base), the order that a lookup and a block's final value already use, so a mismatch at the update poisons only the update.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #12682
The bug
A record update
{ ..base, f: v }that mismatches its annotation makes post-check panic with "erroneous checked type reached Monotype instantiation". This happens when an earlier top-level constant readsbase.How it happens:
basejoins the variable class ofbase.resumeRecordUpdateCheckinsrc/check/Check.zigranunify(record_being_updated_var, expr_var). Unification keeps its second operand as the checked representative (see design.md, "the checked representative"). So the update's own variable became the representative of the whole class ofbase.poisonOnMismatchpoisons the representative's class. That class is the class ofbase, so the bindingbasebecomes.err..errin the type ofbase, and panics.If the constant comes after the update, the checker sees the
.errwhen it checks the constant and retires it, so there is no panic. That is why source order matters in the repro.Why this is a bug
unify(expr_var, use_var)and a block doesunify(expr_var, final_expr_var). In both, the operand keeps the representative and the expression joins the class as an occurrence. The record update used the opposite order.baseis well typed, and other definitions may already have used its type.The fix
Unify
(expr_var, record_being_updated_var). The base keeps the checked representative, and the update joins its class as an occurrence. The mismatch against the annotation then poisons only the update, andbasekeeps its type. The user gets the type mismatch report.The PR also adds a design.md paragraph next to the description of the checked representative. It states the rule for expressions whose type is the type of an operand.
No
CACHE_VERSIONbump: the serialized layout does not change, and earlier poisoning fixes (#11745, #10707) did not bump it either.Tests
src/check/test/rejected_relation_owner_test.zig, 4 tests:ruthkeeps typeVetandruth_labelkeeps typeStr;Str.inspect(base)and no alias;label : Vet -> Strkeeps its type (without the fix it becameError -> Str);test/cli/RecordUpdateAnnotationMismatch.rocwith a subcommands case insrc/cli/test/parallel_cli_runner.zig:roc checkreports "type mismatch" and "1 error and 0 warnings", with no panic.All 4 checker tests and the CLI test fail with the old operand order and pass with the fix. Also run:
run-test-zig-module-check(2010/2010),run-test-cli --suite subcommands --filter "record update",run-check-snapshots,run-check-zig-format,run-check-zig-lints,run-check-tidy,run-check-type-checker-patterns,run-check-semantic-audit,run-check-test-wiring.