fix(checker,codegen): reject generic-at-Unit (E206) + support Unit tuple components (#900, #902)#903
Merged
Merged
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
#900, #902 Two pre-existing check-green-then-codegen-broken bugs in the same Unit-as-a-degenerate-component family (both on release/v0.1.0 and main). #900 — a USER forall<T> function whose body READS @t, inferred to T = Unit, passed vera check but crashed in codegen: Unit is 0 bytes with no WASM representation (spec 11.2.2 / 11.3.1), so the monomorphized body's @T.n slot read lowers to a local.get with no local — the dangling-slot invariant, whose symptom was hash-seed-dependent (E699, a dropped main, or a CodegenInvariantError "file a bug report" crash). The checker's type-argument inference now rejects a body-read forall parameter inferred to bare Unit with the new E206, per DESIGN.md principle 1 (checkability over correctness). The check is NARROWED to bodies that materialize @t (a @T.n SlotRef read, computed once at registration): a @t parameter the body never reads erases cleanly from the ABI, so firstInt(@t, @int){ @Int.0 } and ignore(@t){ 0 } still run at T = Unit and are NOT rejected. Scoped to user-declared functions the monomorphizer clones — built-in generics (async/await/collection + prelude combinators) have hand-written codegen and are excluded, so async(IO.print(...)) keeps its Future<Unit> W002 path. Keyed to bare Unit only: a boxed Option<Unit> stays valid. Covers every @T-reading arg-pinned entry path (Unit-returning fn, () literal, one of several params, reads nested in let/if/match). #902 — a Tuple (or any constructor) with a Unit component (Tuple((), 3) returning Tuple<Unit, Int> passed vera check but crashed in codegen with unknown func: failed to find name : _translate_constructor_call could not infer a WASM type for the Unit field, raised a CodegenSkip, and dropped the whole function while its caller still called it. A Unit field is now laid out as a genuine zero-size field (its arg instructions run for side effects, but it occupies no bytes and stores nothing), mirroring the existing Unit skip in _translate_let_destruct. Unit detection uses _is_void_expr (the canonical produces no stack value check), so a Unit-RETURNING call in field position — IO.print(x), a user @Unit fn, a void effect op, a ModuleCall to a @Unit fn — is also laid out zero-size with its side effect preserved, not just a bare () literal. Covers Unit in any tuple position, multiple Unit fields, nested tuples, a user ADT with a Unit field, and a side-effecting Unit-returning field. Adds a check-level negative conformance fixture (ch02_generic_over_unit_rejected, E206) and a run-level positive one (ch02_tuple_unit_component), reconciles doc counts (127 conformance programs), and restores KNOWN_ISSUES to No known bugs. Co-Authored-By: Claude <[email protected]> EOF )
6e74003 to
573d7a1
Compare
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.
Closes #900
Closes #902
Targets release/v0.1.0. Two Unit-as-degenerate-component bugs, different (cited) resolutions.
#900 — generic instantiated at Unit → clean checker rejection (E206)
A
forall<T>atT=Unitwas check-green but crashed at codegen (E699 / dropped main / invariant-violation, hash-seed-dependent). Decision: checker rejection — DESIGN.md principle 1 (checkability over correctness) + spec §11.2.2/§11.3.1 (Unitis 0 bytes; a monomorphized@T.nslot resolves to no runtime local). New E206 at the single inference choke point (_check_fn_call_with_info,vera/checker/calls.py), scoped to USERforall<T>fns — built-in generics (async/await/combinators) excluded soasync(IO.print(...))keeps itsFuture<Unit>path (a regression this caught and fixed). BoxedOption<Unit>stays a valid type argument. Entry paths:@Unit-returning fn as generic arg, bare()literal,Unitbinding one of several params.#902 — Tuple with a Unit component → codegen support
fn mkt(@Int -> @Tuple<Unit, Int>)was check-green but the function was silently skipped at codegen (unknown func $mkt). Decision: codegen support — spec §2.3.1 (Tuple<>≡Unit; no Unit exclusion) + §11.2.2 (Unit is systematically zero-size). Localized fix in_translate_constructor_call(vera/wasm/data.py): aUnittuple field is laid out genuinely zero-size (arg instructions still run for side effects, occupies no bytes), mirroring the existing_translate_let_destructUnit skip; distinguishes a realUnitfield from a genuine inference failure (stillCodegenSkip). Entry paths: Unit in any position, multiple/all-Unit, nested tuples, ADT-with-Unit-field, Unit+String (i32_pair), Int-Unit-Int (offset verified 22-11=11).Evidence
RED-first both (4 E206 + 5 codegen tests fail pre-fix across seeds); mutation-killed both independently; boxed
Option<Unit>+ 10 pre-existing tuple tests stay green. Full suite 6283 passed, 0 failed; conformance 127 (+ch02_generic_over_unit_rejected[E206 negative], +ch02_tuple_unit_component[run positive]). KNOWN_ISSUES →No known bugs.Adversarial review by orchestrator (CodeRabbit at rate limit).