fix(stub): add missing (fn new ...) to STUB_AIL — restore prep.3 spec/ship coherence (refs F4)

Fieldtest F4 surfaced that the shipped STUB_AIL had only the
TypeDef + ctor; the spec's prep.3 § "Worked author example" wired
a `(fn new ...)` def into the stub and immediately exercised it
via the worked consumer's `(new StubT 42)`. The implementer
dropped the def during the Task 6 sweep (spec-review let it
through). Without the def, the stub's `Term::New` end-to-end
ratification story is broken — F4 demonstrated this with a
`new-type-not-constructible` diagnostic on a verbatim
worked-consumer paste.

Re-added the def per the spec's design:

  (fn new
    (doc "Construct StubT<Int> from an Int. Exercises Term::New end-to-end.")
    (type (fn-type (params (con Int)) (ret (con StubT (con Int)))))
    (params x)
    (body (term-ctor StubT Stub x)))

IR snapshots refreshed because every binary now carries the `new`
function's IR (in addition to the `drop_kernel_stub_StubT` from
the original prep.3 close). All 664 workspace tests green.

This restores coherence between the spec, the design model, and
the shipped stub. The `Term::New` invocation `(new StubT 42)` is
still codegen-deferred (per spec § Architecture, raw-buf
milestone); but at least `ail check` now passes on the spec's
worked-consumer paste.

A related and more substantive bug (F3 — kernel-tier auto-import
not registering the module as a qualifier prefix, making
`kernel_stub.StubT` consumer-unreachable) is handled separately
via the debug skill.
This commit is contained in:
2026-05-28 19:21:57 +02:00
parent aa49a56d5a
commit 171a986f82
6 changed files with 91 additions and 1 deletions
+16
View File
@@ -25,6 +25,7 @@ declare ptr @ailang_str_concat(ptr, ptr)
declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_hello_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_hello_main_adapter, ptr null }
@ail_kernel_stub_new_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_kernel_stub_new_adapter, ptr null }
@ail_prelude_float_eq_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_eq_adapter, ptr null }
@ail_prelude_float_ne_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_ne_adapter, ptr null }
@ail_prelude_float_lt_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_lt_adapter, ptr null }
@@ -45,6 +46,21 @@ entry:
ret i8 %r
}
define ptr @ail_kernel_stub_new(i64 %arg_x) {
entry:
%v1 = call ptr @ailang_rc_alloc(i64 16)
store i64 0, ptr %v1, align 8
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
store i64 %arg_x, ptr %v2, align 8
ret ptr %v1
}
define ptr @ail_kernel_stub_new_adapter(ptr %_env, i64 %a0) {
entry:
%r = call ptr @ail_kernel_stub_new(i64 %a0)
ret ptr %r
}
define void @drop_kernel_stub_StubT(ptr %p) {
entry:
%is_null = icmp eq ptr %p, null
+16
View File
@@ -22,6 +22,7 @@ declare ptr @ailang_str_clone(ptr)
declare ptr @ailang_str_concat(ptr, ptr)
declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_kernel_stub_new_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_kernel_stub_new_adapter, ptr null }
@ail_list_sum_list_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_list_sum_list_adapter, ptr null }
@ail_list_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_list_main_adapter, ptr null }
@ail_prelude_float_eq_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_eq_adapter, ptr null }
@@ -32,6 +33,21 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_prelude_float_ge_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_ge_adapter, ptr null }
@ail_prelude_show__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_show__Int_adapter, ptr null }
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
define ptr @ail_kernel_stub_new(i64 %arg_x) {
entry:
%v1 = call ptr @ailang_rc_alloc(i64 16)
store i64 0, ptr %v1, align 8
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
store i64 %arg_x, ptr %v2, align 8
ret ptr %v1
}
define ptr @ail_kernel_stub_new_adapter(ptr %_env, i64 %a0) {
entry:
%r = call ptr @ail_kernel_stub_new(i64 %a0)
ret ptr %r
}
define void @drop_kernel_stub_StubT(ptr %p) {
entry:
%is_null = icmp eq ptr %p, null
+16
View File
@@ -22,6 +22,7 @@ declare ptr @ailang_str_clone(ptr)
declare ptr @ailang_str_concat(ptr, ptr)
declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_kernel_stub_new_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_kernel_stub_new_adapter, ptr null }
@ail_max3_max_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_max3_max_adapter, ptr null }
@ail_max3_max3_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_max3_max3_adapter, ptr null }
@ail_max3_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_max3_main_adapter, ptr null }
@@ -35,6 +36,21 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_prelude_gt__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_gt__Int_adapter, ptr null }
@ail_prelude_show__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_show__Int_adapter, ptr null }
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
define ptr @ail_kernel_stub_new(i64 %arg_x) {
entry:
%v1 = call ptr @ailang_rc_alloc(i64 16)
store i64 0, ptr %v1, align 8
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
store i64 %arg_x, ptr %v2, align 8
ret ptr %v1
}
define ptr @ail_kernel_stub_new_adapter(ptr %_env, i64 %a0) {
entry:
%r = call ptr @ail_kernel_stub_new(i64 %a0)
ret ptr %r
}
define void @drop_kernel_stub_StubT(ptr %p) {
entry:
%is_null = icmp eq ptr %p, null
+16
View File
@@ -22,6 +22,7 @@ declare ptr @ailang_str_clone(ptr)
declare ptr @ailang_str_concat(ptr, ptr)
declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_kernel_stub_new_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_kernel_stub_new_adapter, ptr null }
@ail_prelude_float_eq_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_eq_adapter, ptr null }
@ail_prelude_float_ne_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_ne_adapter, ptr null }
@ail_prelude_float_lt_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_lt_adapter, ptr null }
@@ -33,6 +34,21 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
@ail_sum_sum_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_sum_sum_adapter, ptr null }
@ail_sum_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_sum_main_adapter, ptr null }
define ptr @ail_kernel_stub_new(i64 %arg_x) {
entry:
%v1 = call ptr @ailang_rc_alloc(i64 16)
store i64 0, ptr %v1, align 8
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
store i64 %arg_x, ptr %v2, align 8
ret ptr %v1
}
define ptr @ail_kernel_stub_new_adapter(ptr %_env, i64 %a0) {
entry:
%r = call ptr @ail_kernel_stub_new(i64 %a0)
ret ptr %r
}
define void @drop_kernel_stub_StubT(ptr %p) {
entry:
%is_null = icmp eq ptr %p, null
+16
View File
@@ -22,6 +22,7 @@ declare ptr @ailang_str_clone(ptr)
declare ptr @ailang_str_concat(ptr, ptr)
declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_kernel_stub_new_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_kernel_stub_new_adapter, ptr null }
@ail_prelude_float_eq_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_eq_adapter, ptr null }
@ail_prelude_float_ne_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_ne_adapter, ptr null }
@ail_prelude_float_lt_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_float_lt_adapter, ptr null }
@@ -32,6 +33,21 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
@ail_ws_lib_add_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_ws_lib_add_adapter, ptr null }
@ail_ws_main_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_ws_main_main_adapter, ptr null }
define ptr @ail_kernel_stub_new(i64 %arg_x) {
entry:
%v1 = call ptr @ailang_rc_alloc(i64 16)
store i64 0, ptr %v1, align 8
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
store i64 %arg_x, ptr %v2, align 8
ret ptr %v1
}
define ptr @ail_kernel_stub_new_adapter(ptr %_env, i64 %a0) {
entry:
%r = call ptr @ail_kernel_stub_new(i64 %a0)
ret ptr %r
}
define void @drop_kernel_stub_StubT(ptr %p) {
entry:
%is_null = icmp eq ptr %p, null
+11 -1
View File
@@ -19,9 +19,19 @@
/// Source-of-truth Form-A text for the stub kernel module. Parsed
/// by `ailang_surface::parse_kernel_stub` (and round-trip-pinned by
/// `kernel_stub_module_round_trips` in `design_schema_drift.rs`).
///
/// Ships a `(fn new ...)` def so consumers can spell `(new StubT 42)`,
/// the worked-consumer example from prep.3 of the spec — without it,
/// the stub's `Term::New` end-to-end ratification story is broken
/// (per fieldtest F4, 2026-05-28).
pub const STUB_AIL: &str = r#"(module kernel_stub
(kernel)
(data StubT (vars a)
(ctor Stub a)
(param-in (a Int Float))))
(param-in (a Int Float)))
(fn new
(doc "Construct StubT<Int> from an Int. Exercises Term::New end-to-end.")
(type (fn-type (params (con Int)) (ret (con StubT (con Int)))))
(params x)
(body (term-ctor StubT Stub x))))
"#;