fix(check): qualify cross-module kernel type-cons in user ADT fields
A consumer module's ADT field could reference a kernel-tier auto-imported type by its bare name in op/value positions (`(new RawBuf ...)`, `RawBuf.get`) but NOT in the type-constructor position of the field declaration: `(con RawBuf (con Int))` stayed the unqualified `RawBuf<Int>` and failed to unify with the constructor argument's `raw_buf.RawBuf<Int>`, so a RawBuf could not be stored in a user ADT field without spelling the qualified `raw_buf.RawBuf`. `qualify_workspace_module` skipped `Def::Type` entirely, and the `Term::Ctor` arm only qualified field types of cross-module *owning* types — a *local* type carrying a cross-module field was the uncovered case. The fix qualifies each ctor field type in the `Def::Type` arm via the existing `qualify_workspace_types`, which upgrades only genuinely cross-module type-cons (skips `own_local_types` and primitives), so a purely-local field is never spuriously rewritten. This is a check-side workspace transform, not the on-disk canonical form, so no module hash drifts (both hash-pin tests stay green). RED test `rawbuf_in_user_adt_field_resolves_bare_name` in crates/ailang-check/tests/workspace.rs, with the bare-name fixture (now checks/builds/runs -> 42, live=0, the ADT drop cascade frees the buffer slab) and the qualified control twin. This is the Series-substrate shape (a RawBuf wrapped in a user ADT), so the inconsistency would have bitten the pending series milestone. closes #50
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
(module raw_buf_adt_field_bare
|
||||
(data Box (ctor Box (con RawBuf (con Int))))
|
||||
(fn slot1
|
||||
(doc "Reads a RawBuf stored in a user ADT field through a borrow. The Box field is typed with the bare kernel name `(con RawBuf (con Int))`; the kernel-tier auto-import must resolve it to raw_buf.RawBuf exactly as it does in op/value positions.")
|
||||
(type (fn-type (params (borrow (con Box))) (ret (con Int))))
|
||||
(params bx)
|
||||
(body (match bx (case (pat-ctor Box buf) (app RawBuf.get buf 1)))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body (let buf (new RawBuf (con Int) 3)
|
||||
(let buf (app RawBuf.set buf 1 42)
|
||||
(let bx (term-ctor Box Box buf) (app print (app slot1 bx))))))))
|
||||
@@ -0,0 +1,13 @@
|
||||
(module raw_buf_adt_field_qualified
|
||||
(data Box (ctor Box (con raw_buf.RawBuf (con Int))))
|
||||
(fn slot1
|
||||
(doc "Control twin of raw_buf_adt_field_bare: identical module but the Box field is typed with the fully-qualified `(con raw_buf.RawBuf (con Int))`. This checks clean today, isolating the bug to bare-name resolution in the type-constructor position.")
|
||||
(type (fn-type (params (borrow (con Box))) (ret (con Int))))
|
||||
(params bx)
|
||||
(body (match bx (case (pat-ctor Box buf) (app RawBuf.get buf 1)))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body (let buf (new RawBuf (con Int) 3)
|
||||
(let buf (app RawBuf.set buf 1 42)
|
||||
(let bx (term-ctor Box Box buf) (app print (app slot1 bx))))))))
|
||||
Reference in New Issue
Block a user