test(raw-buf): RED-pin #51 — (new T <elem> …) must honour the element type-arg
Two failing E2E tests pinning the two legs of the #51 codegen crash, both rooted in the `Term::New` desugar dropping `NewArg::Type` (crates/ailang-core/src/desugar.rs:1053): - Leg 1 (legitimate): `(new RawBuf (con Int) 3)` used only via `RawBuf.size` — never observed by get/set, so the dropped `(con Int)` is the sole element-type carrier. The unpinned forall var defaults to Unit in mono and `ail build --alloc=rc` aborts on the unregistered `RawBuf_new__Unit` intercept. Pins build+run printing `3`. - Leg 2 (forbidden): `(new RawBuf (con Unit) 3)` — Unit is outside the param-in set {Int, Float, Bool}, but the dropped type-arg never reaches param-in enforcement, so `ail check` wrongly passes. Pins a `param-not-in-restricted-set` rejection naming Unit at check time. Both RED at HEAD. GREEN side carries the explicit element type from Term::New through to monomorphisation (must not mint __Unit) and adds the leg-2 reject pre-desugar per the Term::New/desugar lockstep. refs #51
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
(module raw_buf_new_type_arg_intsize
|
||||
(fn main
|
||||
(doc "RED-pin fixture for #51 leg 1 (raw-buf F7). A `(new RawBuf (con Int) 3)` buffer used ONLY via `RawBuf.size` — its element type is never observed by a later get/set, so the only carrier of the element type is the author's explicit `(con Int)` type-arg on `new`. Today `(new T <type> <values>)` desugars to `(app T.new <values>)` and DROPS the leading NewArg::Type (crates/ailang-core/src/desugar.rs:1053), so the result's forall var `a` is unpinned and monomorphisation defaults it to Unit (crates/ailang-check/src/mono.rs free-fn-call arm; mirror crates/ailang-codegen/src/subst.rs). Codegen then mints `RawBuf_new__Unit`, which has no registered intercept (only Int/Float/Bool are in crates/ailang-codegen/src/intercepts.rs) and `ail build --alloc=rc` aborts: `intrinsic fn RawBuf_new__Unit has no registered intercept`. Expected post-fix: the explicit `(con Int)` is carried through monomorphisation so the buffer specialises to `RawBuf_new__Int`; build succeeds and the program prints 3 (the size).")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let b (new RawBuf (con Int) 3)
|
||||
(app print (app RawBuf.size b))))))
|
||||
@@ -0,0 +1,8 @@
|
||||
(module raw_buf_new_type_arg_unit_reject
|
||||
(fn main
|
||||
(doc "RED-pin fixture for #51 leg 2 (raw-buf F7). A `(new RawBuf (con Unit) 3)` names Unit as the element type — but Unit is NOT in RawBuf's param-in restricted set {Int, Float, Bool}, so this must be REJECTED at `ail check` with `param-not-in-restricted-set` naming Unit. Today the `(new T <type> <values>)` desugar (crates/ailang-core/src/desugar.rs:1053) drops the `NewArg::Type` BEFORE check, so the `(con Unit)` element annotation never reaches the param-in enforcement in check_type_well_formed (crates/ailang-check/src/lib.rs:2084). `ail check` therefore passes (exit 0) and the program only crashes later at `ail build` with the same unregistered `RawBuf_new__Unit` intercept as leg 1. Expected post-fix: a pre-desugar reject on the Term::New shape (per the CLAUDE.md Term::New/desugar lockstep, crates/ailang-check/src/pre_desugar_validation.rs) fails `ail check` with `param-not-in-restricted-set` naming Unit; codegen is never reached.")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let b (new RawBuf (con Unit) 3)
|
||||
(app print (app RawBuf.size b))))))
|
||||
Reference in New Issue
Block a user