From c785687b3d2fd6af15fd0196e1e8c08c1a036aa1 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Wed, 7 Oct 2026 14:38:42 +0700 Subject: [PATCH 01/10] t27b: an array length that is a compile-time expression (Closes #7347) [W + 1]u8, [(W + 1) * 2]u16, [H * 2]u64 with H: u32: the length text is parsed back and folded as a module constant is, as Zig folds the text t27c prints. Run-time names, calls and negative lengths are refused. Co-Authored-By: Claude Opus 5.5 --- cli/t27b/src/lower.rs | 46 +++++++++ cli/t27b/tests/source.rs | 69 ++++++++++++++ specs/tri/t27b/conformance/array_len_expr.t27 | 93 +++++++++++++++++++ tools/policy/foreign-exceptions.txt | 6 ++ 4 files changed, 214 insertions(+) create mode 100644 specs/tri/t27b/conformance/array_len_expr.t27 diff --git a/cli/t27b/src/lower.rs b/cli/t27b/src/lower.rs index 77b143e36e..b974c1fc88 100644 --- a/cli/t27b/src/lower.rs +++ b/cli/t27b/src/lower.rs @@ -4169,6 +4169,8 @@ impl<'a> Lower<'a> { Some(Val::E(Expr { kind: ExprKind::Const(c), ty })) if ty.is_int() => Some(c), _ => None, } + } else if let Some(e) = len_expr(len) { + self.fold_len(&e)? } else { None }; @@ -4179,6 +4181,25 @@ impl<'a> Lower<'a> { } } + /// A length spelled as an expression (`N+1`, `(W+1)*2`): t27c prints the + /// text unchanged and Zig folds it, so it is folded here the way a + /// module constant is -- run-time names are not visible, and a typed + /// constant keeps its type. None when the value is not an integer known + /// at compile time. + fn fold_len(&mut self, e: &Node) -> R> { + let saved_line = self.line; + let saved_ct = std::mem::replace(&mut self.comptime, true); + let r = self.expr(e); + self.comptime = saved_ct; + self.line = saved_line; + Ok(match r? { + Val::Poison => return Err(()), + Val::Ct(c) => Some(c), + Val::E(Expr { kind: ExprKind::Const(c), ty }) if ty.is_int() => Some(c), + _ => None, + }) + } + /// The fieldless, zero-size struct that stands for `void`. Its key is /// a keyword, so no declared struct can take it. fn void_struct(&mut self) -> u32 { @@ -6890,6 +6911,31 @@ fn find_const<'n>(n: &'n Node, name: &str) -> Option<&'n Node> { n.children.iter().find_map(|c| find_const(c, name)) } +/// An array length kept as text (`N+1`) parsed back as an expression, when it +/// is built only from integer literals, names, `+ - *` and parentheses. +fn len_expr(len: &str) -> Option { + if !len.contains(['+', '-', '*', '(']) { + return None; + } + let src = format!("module r {{ const r = {}; }}", len); + let ast = crate::compiler::Compiler::parse_ast_strict(&src).ok()?; + let mut e = find_const(&ast, "r")?.clone(); + fn ok(n: &Node) -> bool { + match n.kind { + NodeKind::ExprLiteral => n.children.is_empty() && parse_int(&n.value).is_some(), + NodeKind::ExprIdentifier => n.children.is_empty() && !n.name.contains("::"), + NodeKind::ExprBinary => matches!(n.extra_op.as_str(), "+" | "-" | "*") && n.children.len() == 2 && n.children.iter().all(ok), + NodeKind::ExprUnary => n.extra_op == "-" && n.children.len() == 1 && ok(&n.children[0]), + _ => false, + } + } + if !ok(&e) { + return None; + } + zero_lines(&mut e); + Some(e) +} + /// Whether a repeat element parsed back from its text is one of the shapes /// `repeat_elem` takes. fn simple_repeat_elem(n: &Node) -> bool { diff --git a/cli/t27b/tests/source.rs b/cli/t27b/tests/source.rs index 0316192768..60c8266bb4 100644 --- a/cli/t27b/tests/source.rs +++ b/cli/t27b/tests/source.rs @@ -3047,3 +3047,72 @@ fn bare_abs_rejections() { assert!(m.starts_with(&format!("t27b: unsupported construct {} at line", construct)), "{}: {}", body, m); } } + +// ------------------------------------------------------------ array length expressions + +/// An array length spelled as an expression (`[W+1]u8`, `[(W+1)*2]u16`) is +/// folded at compile time, as Zig folds the text t27c prints: an untyped +/// constant is a comptime_int, a typed one keeps its type. +#[test] +fn array_length_expression_folds() { + let src = "module a; + +const W = 4; +const H: u32 = 3; +const AREA = W * H; + +fn total(xs: [W * H]u32) -> u32 { + var s: u32 = 0; + for (xs) |x| { + s = s + x; + } + return s; +} + +test ok { + var a: [W + 1]u8 = undefined; + a[0] = 1; + assert(a.len == 5); + var c: [(W + 1) * 2]u16 = undefined; + c[9] = 3; + assert(c.len == 10); + var d: [H * 2]u64 = undefined; + d[5] = 1; + assert(d.len == 6); + var b: [AREA - 2]u8 = undefined; + b[0] = 1; + assert(b.len == 10); + var r: [W * H]u32 = undefined; + for (0..r.len) |i| { + r[i] = 2; + } + assert(total(r) == 24); +} + +test fails { + var a: [W - 1]u8 = undefined; + a[0] = 1; + assert(a.len == 4); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("ok", false, true), ("fails", false, false)]); +} + +/// A length that is negative, reads a run-time value or calls a fn is +/// refused as `type [N]T`; one that overflows its typed constant is refused +/// by the fold. Zig refuses all but the call. +#[test] +fn array_length_expression_rejections() { + let cases: &[(&str, bool)] = &[ + ("const W = 4;\nfn f() -> u32 {\n var a: [W - 5]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), + ("fn f() -> u32 {\n var n: u32 = 3;\n n = n + 1;\n var a: [n + 1]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), + ("fn g(x: u32) -> u32 {\n return x;\n}\nfn f() -> u32 {\n var a: [g(2) + 1]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), + ("const H: u8 = 200;\nfn f() -> u32 {\n var a: [H + 100]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", false), + ]; + for (body, len) in cases { + let m = rejected(&format!("module a;\n\n{}\ntest t {{\n assert(f() == 1);\n}}\n", body)); + let want = if *len { "t27b: unsupported construct type [N]T at line" } else { "t27b: unsupported construct" }; + assert!(m.starts_with(want), "{}: {}", body, m); + } +} diff --git a/specs/tri/t27b/conformance/array_len_expr.t27 b/specs/tri/t27b/conformance/array_len_expr.t27 new file mode 100644 index 0000000000..1229e5dae3 --- /dev/null +++ b/specs/tri/t27b/conformance/array_len_expr.t27 @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/tri/t27b/conformance/array_len_expr.t27 -- an array type whose length is a compile-time +; expression, `[N + 1]T`, as the reference runs it (gHashTag/t27#6063 lane: type [N]T). +; Every test here passes `t27c test-report`; t27b must give the same verdict on each, or refuse the file. +; t27c's Zig backend prints the length text unchanged, so Zig folds it: module constants, literals, +; `+ - *` and parentheses. The fold follows Zig: an untyped constant is a comptime_int, a typed one +; keeps its type (so `H * 2` with `H: u32` is a u32 and must not overflow it). +; Not here: a length that calls a fn, reads a run-time value, or goes negative; Zig refuses the last two. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module T27bConformanceArrayLenExpr; + +const W = 4; +const H: u32 = 3; +const AREA = W * H; + +const Grid = struct { + cells: [W * H]u32, + pad: [W + 2]u8, +}; + +fn ramp() -> [W * H]u32 { + var a: [W * H]u32 = undefined; + var i: u32 = 0; + while (i < AREA) { + a[i] = i * 2; + i = i + 1; + } + return a; +} + +fn total(xs: [W * H]u32) -> u32 { + var s: u32 = 0; + for (xs) |x| { + s = s + x; + } + return s; +} + +fn first_last(xs: [AREA - 2]u8) -> u8 { + return xs[0] + xs[xs.len - 1]; +} + +test length_is_the_folded_sum { + var a: [W + 1]u8 = undefined; + assert(a.len == 5); + for (0..a.len) |i| { + a[i] = 7; + } + assert(a[0] == 7); + assert(a[4] == 7); +} + +test product_length_as_result_and_parameter { + const r = ramp(); + assert(r.len == 12); + assert(r[11] == 22); + assert(total(r) == 132); +} + +test length_from_a_constant_that_is_itself_an_expression { + var b: [AREA - 2]u8 = undefined; + assert(b.len == 10); + var i: usize = 0; + while (i < b.len) { + b[i] = 1; + i = i + 1; + } + b[0] = 3; + b[9] = 4; + assert(first_last(b) == 7); +} + +test parenthesised_and_typed_lengths { + var c: [(W + 1) * 2]u16 = undefined; + assert(c.len == 10); + var d: [H * 2]u64 = undefined; + assert(d.len == 6); + d[5] = 9; + c[9] = 8; + assert(d[5] == 9); + assert(c[9] == 8); +} + +test lengths_inside_a_struct { + var g: Grid = undefined; + g.cells = ramp(); + g.pad[5] = 2; + assert(g.pad.len == 6); + assert(g.cells.len == 12); + assert(g.cells[3] == 6); + assert(g.pad[5] == 2); +} diff --git a/tools/policy/foreign-exceptions.txt b/tools/policy/foreign-exceptions.txt index e160746825..5f9c872d06 100644 --- a/tools/policy/foreign-exceptions.txt +++ b/tools/policy/foreign-exceptions.txt @@ -335,3 +335,9 @@ cli/t27b/tests/tail.rs # discount_holds). The workflow runs the rule; the selftest drives it against stubbed master runs. .github/workflows/auto-merge-ready-prs.yml tools/bees/merger_gate_selftest.py + +# owner 2026-10-06, epic #6063 (label owner-approved-foreign on #6063; "add the label yourself and do the +# work", translated): t27b coverage lane 1, issue #7347 -- an array length that is a compile-time expression +# (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. +cli/t27b/src/lower.rs +cli/t27b/tests/source.rs From 69f9580d0b0e5d4f737f568b6407e334730a2ddb Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Wed, 7 Oct 2026 14:44:12 +0700 Subject: [PATCH 02/10] t27b: fold typed constant arithmetic in array lengths and module consts (Closes #7347) Co-Authored-By: Claude Opus 5.5 --- cli/t27b/src/lower.rs | 55 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/cli/t27b/src/lower.rs b/cli/t27b/src/lower.rs index b974c1fc88..6cc0b7a9d1 100644 --- a/cli/t27b/src/lower.rs +++ b/cli/t27b/src/lower.rs @@ -1468,6 +1468,7 @@ impl<'a> Lower<'a> { } return self.rodata(init, t); } + let saved_sites = self.sites.len(); let v = if node.extra_type.trim().is_empty() { self.expr(init)? } else { @@ -1475,6 +1476,21 @@ impl<'a> Lower<'a> { let v = self.expr_as(init, <y::S(ty))?; Val::E(self.coerce(v, ty)?) }; + // `const AREA = W * H;` with a typed `H`: Zig folds the typed + // arithmetic at compile time, and a step out of range is an error. + let v = match v { + Val::E(x) if !matches!(x.kind, ExprKind::Const(_)) => match const_eval(&x) { + Some(Some(c)) => { + self.sites.truncate(saved_sites); + Val::E(Expr { kind: ExprKind::Const(c), ty: x.ty }) + } + Some(None) => { + return self.reject("ConstDecl", format!("`{}` overflows {}", node.name, x.ty.name())) + } + None => Val::E(x), + }, + v => v, + }; match &v { Val::Ct(_) | Val::Cf(..) | Val::S(..) | Val::A(..) | Val::Poison => Ok(v), Val::E(e) if matches!(e.kind, ExprKind::Const(_)) => Ok(v), @@ -4189,13 +4205,22 @@ impl<'a> Lower<'a> { fn fold_len(&mut self, e: &Node) -> R> { let saved_line = self.line; let saved_ct = std::mem::replace(&mut self.comptime, true); + let saved_sites = self.sites.len(); let r = self.expr(e); self.comptime = saved_ct; + // The trap sites of the folded tree are never emitted. + self.sites.truncate(saved_sites); self.line = saved_line; Ok(match r? { Val::Poison => return Err(()), Val::Ct(c) => Some(c), - Val::E(Expr { kind: ExprKind::Const(c), ty }) if ty.is_int() => Some(c), + Val::E(x) => match const_eval(&x) { + Some(Some(c)) => Some(c), + Some(None) => { + return self.reject("type [N]T", format!("length overflows {}", x.ty.name())) + } + None => None, + }, _ => None, }) } @@ -6913,6 +6938,34 @@ fn find_const<'n>(n: &'n Node, name: &str) -> Option<&'n Node> { /// An array length kept as text (`N+1`) parsed back as an expression, when it /// is built only from integer literals, names, `+ - *` and parentheses. +/// The value of a typed integer expression built only from constants, `+ - *` +/// and widenings, as Zig evaluates it at compile time: every step must fit +/// its type. None when the tree is not of that shape; Some(None) when a step +/// leaves its type's range (a compile error in Zig). +fn const_eval(e: &Expr) -> Option> { + if !e.ty.is_int() { + return None; + } + let v = match &e.kind { + ExprKind::Const(c) => Some(*c), + ExprKind::Widen(x) => const_eval(x)?, + ExprKind::Arith { op, lhs, rhs, .. } => { + let (x, y) = match (const_eval(lhs)?, const_eval(rhs)?) { + (Some(x), Some(y)) => (x, y), + _ => return Some(None), + }; + match op { + ArithOp::Add | ArithOp::AddW => x.checked_add(y), + ArithOp::Sub | ArithOp::SubW => x.checked_sub(y), + ArithOp::Mul | ArithOp::MulW => x.checked_mul(y), + _ => return None, + } + } + _ => return None, + }; + Some(v.filter(|v| e.ty.fits(*v))) +} + fn len_expr(len: &str) -> Option { if !len.contains(['+', '-', '*', '(']) { return None; From 49cc75ecd2a5d95e94809d618587ed8c19fb02e1 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Wed, 7 Oct 2026 14:57:05 +0700 Subject: [PATCH 03/10] t27b: a wrapping op in a typed module const folds as Zig wraps it (Closes #7347) Co-Authored-By: Claude Opus 5.5 --- cli/t27b/src/lower.rs | 27 ++++++++++++++++----------- cli/t27b/tests/source.rs | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/cli/t27b/src/lower.rs b/cli/t27b/src/lower.rs index 6cc0b7a9d1..611d41d9d4 100644 --- a/cli/t27b/src/lower.rs +++ b/cli/t27b/src/lower.rs @@ -1479,7 +1479,7 @@ impl<'a> Lower<'a> { // `const AREA = W * H;` with a typed `H`: Zig folds the typed // arithmetic at compile time, and a step out of range is an error. let v = match v { - Val::E(x) if !matches!(x.kind, ExprKind::Const(_)) => match const_eval(&x) { + Val::E(x) if !matches!(x.kind, ExprKind::Const(_)) => match const_eval(&x, self.mode == OverflowMode::Trap) { Some(Some(c)) => { self.sites.truncate(saved_sites); Val::E(Expr { kind: ExprKind::Const(c), ty: x.ty }) @@ -4214,7 +4214,7 @@ impl<'a> Lower<'a> { Ok(match r? { Val::Poison => return Err(()), Val::Ct(c) => Some(c), - Val::E(x) => match const_eval(&x) { + Val::E(x) => match const_eval(&x, self.mode == OverflowMode::Trap) { Some(Some(c)) => Some(c), Some(None) => { return self.reject("type [N]T", format!("length overflows {}", x.ty.name())) @@ -6939,25 +6939,30 @@ fn find_const<'n>(n: &'n Node, name: &str) -> Option<&'n Node> { /// An array length kept as text (`N+1`) parsed back as an expression, when it /// is built only from integer literals, names, `+ - *` and parentheses. /// The value of a typed integer expression built only from constants, `+ - *` -/// and widenings, as Zig evaluates it at compile time: every step must fit -/// its type. None when the tree is not of that shape; Some(None) when a step -/// leaves its type's range (a compile error in Zig). -fn const_eval(e: &Expr) -> Option> { +/// and widenings, as Zig evaluates it at compile time: every checked step +/// must fit its type, and `+% -% *%` wrap. None when the tree is not of that +/// shape; Some(None) when a checked step leaves its type's range (a compile +/// error in Zig). `trap` is false when `+` itself lowers to a wrapping op, +/// so a wrapping op cannot be told from a checked one and is not folded. +fn const_eval(e: &Expr, trap: bool) -> Option> { if !e.ty.is_int() { return None; } let v = match &e.kind { ExprKind::Const(c) => Some(*c), - ExprKind::Widen(x) => const_eval(x)?, + ExprKind::Widen(x) => const_eval(x, trap)?, ExprKind::Arith { op, lhs, rhs, .. } => { - let (x, y) = match (const_eval(lhs)?, const_eval(rhs)?) { + let (x, y) = match (const_eval(lhs, trap)?, const_eval(rhs, trap)?) { (Some(x), Some(y)) => (x, y), _ => return Some(None), }; match op { - ArithOp::Add | ArithOp::AddW => x.checked_add(y), - ArithOp::Sub | ArithOp::SubW => x.checked_sub(y), - ArithOp::Mul | ArithOp::MulW => x.checked_mul(y), + ArithOp::Add => x.checked_add(y), + ArithOp::Sub => x.checked_sub(y), + ArithOp::Mul => x.checked_mul(y), + ArithOp::AddW if trap => return Some(Some(e.ty.wrap(x.wrapping_add(y)))), + ArithOp::SubW if trap => return Some(Some(e.ty.wrap(x.wrapping_sub(y)))), + ArithOp::MulW if trap => return Some(Some(e.ty.wrap(x.wrapping_mul(y)))), _ => return None, } } diff --git a/cli/t27b/tests/source.rs b/cli/t27b/tests/source.rs index 60c8266bb4..eb93af8b97 100644 --- a/cli/t27b/tests/source.rs +++ b/cli/t27b/tests/source.rs @@ -3116,3 +3116,28 @@ fn array_length_expression_rejections() { assert!(m.starts_with(want), "{}: {}", body, m); } } + +/// A module const built from typed constants is folded as Zig folds it at +/// compile time: a checked step out of range is refused, `+%` wraps. +#[test] +fn typed_constant_arithmetic_folds() { + let src = "module a; + +const H: u32 = 3; +const A = H * 5; +const Q: u8 = 250; +const R = Q +% 10; + +test ok { + var x: u32 = A; + x = x + 1; + assert(x == 16); + assert(R == 4); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("ok", false, true)]); + let m = rejected("module a;\n\nconst B: u8 = 200;\nconst OV = B + 100;\n\ntest t {\n assert(OV == 44);\n}\n"); + assert!(m.starts_with("t27b: unsupported construct ConstDecl at line"), "{}", m); + assert!(m.contains("`OV` overflows u8"), "{}", m); +} From 7a7688c3ed3549a2d185dc827bfe1947c0030f24 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Wed, 7 Oct 2026 15:13:19 +0700 Subject: [PATCH 04/10] t27b: typed-constant test assigns inside a fn, not at test top level (Closes #7347) Co-Authored-By: Claude Opus 5.5 --- cli/t27b/tests/source.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cli/t27b/tests/source.rs b/cli/t27b/tests/source.rs index eb93af8b97..8095061897 100644 --- a/cli/t27b/tests/source.rs +++ b/cli/t27b/tests/source.rs @@ -3128,10 +3128,14 @@ const A = H * 5; const Q: u8 = 250; const R = Q +% 10; -test ok { +fn next() -> u32 { var x: u32 = A; x = x + 1; - assert(x == 16); + return x; +} + +test ok { + assert(next() == 16); assert(R == 4); } "; From 48ef7c6a6dfb01b7a31dc2ae7d2cbe037d06ece1 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Wed, 7 Oct 2026 15:39:40 +0700 Subject: [PATCH 05/10] t27b: ledger and NOW entry for array lengths written as constant expressions (Closes #7347) array_len_expr.t27 moves to pass; routes/memory.t27 now stops at FnDecl(frame size). Lab corpus at --jobs 2: 818 -> 819, mismatch 0. Co-Authored-By: Claude Opus 5.5 --- docs/now/2026-10-07-t27b-array-len-expr.md | 10 ++++++++++ docs/reports/t27b_expectations.json | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 docs/now/2026-10-07-t27b-array-len-expr.md diff --git a/docs/now/2026-10-07-t27b-array-len-expr.md b/docs/now/2026-10-07-t27b-array-len-expr.md new file mode 100644 index 0000000000..cb0b53ac8f --- /dev/null +++ b/docs/now/2026-10-07-t27b-array-len-expr.md @@ -0,0 +1,10 @@ +# NOW -- t27b: an array length written as a constant expression (2026-10-07) + +## `[W*H]u8` and `[N]T` where N is itself an expression (Closes #7347) + +- New conformance spec `specs/tri/t27b/conformance/array_len_expr.t27`. It gives 5 pass with 0 vacuous under `t27c test-report`, and the same 5 under t27b, with 16 runtime asserts. +- t27b refused an array type whose length is not a bare literal or a bare constant name (`type [N]T`). It now folds the length at compile time: integer literals, module constants (typed or untyped, including one defined by another expression), `+ - *`, the wrapping forms, parentheses and unary minus. A length that does not fold to a non-negative integer is still refused: a division, a call, a run-time value, a negative length, or a typed constant that overflows its type. Module constants with a declared type are folded the same way, so `const R = Q +% 10` with `Q: u8 = 250` is 4, and `const OV = B + 100` with `B: u8 = 200` is refused as the reference refuses it. +- 7 mutants each fail the same tests in t27b and in the reference. Of 22 probes, 9 pass in both, 2 fail in both, and 8 are blocked by the reference and refused by t27b. The other 3 are refused by t27b while the reference passes: a length using `/`, a length using a fn call, and a 50 KB local array over the frame limit. +- Code is in `cli/t27b/src/lower.rs`. Tests are in `cli/t27b/tests/source.rs`. Both files are listed in `tools/policy/foreign-exceptions.txt` under the owner's approval on #6063. +- Lab corpus at --jobs 2 against master: t27b pass where the reference passes 818 -> 819, mismatch 0. Ledger `docs/reports/t27b_expectations.json`: the new spec moves to pass. `routes/memory.t27` now stops at `FnDecl(frame size)`. +Refs #6063. Closes #7347. diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index 9cc65a400f..b8e90cd690 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -14,7 +14,7 @@ }, "max_not_pass": 28, "counts": { - "pass": 530, + "pass": 531, "pass_vacuous": 262, "not_pass": 28 }, @@ -333,7 +333,7 @@ {"path": "specs/port/bootstrap/src/phi_f64_literals.t27", "t27b": "blocked", "blocker": "type i128", "reason": "unimplemented"}, {"path": "specs/port/bootstrap/src/sensitivity.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/health.t27", "t27b": "pass"}, - {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/memory.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/memory.t27", "t27b": "codegen", "blocker": "t27b: unsupported construct FnDecl(frame size) at line 0 (fn save_memory_content_too_long: 50032 bytes of local aggregates; at most 16384 per frame)", "reason": "unimplemented"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-needs-you.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-registry.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-rehearsal.t27", "t27b": "pass"}, @@ -739,6 +739,7 @@ {"path": "specs/tri/sort/insertion_sort.t27", "t27b": "pass"}, {"path": "specs/tri/sort/selection_sort.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/anonymous_struct.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/array_len_expr.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/array_literal.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/array_literal_value.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/array_repeat_text.t27", "t27b": "pass"}, From d10065325e7205d5bd7f277e476cdb7bae5a967b Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sat, 10 Oct 2026 18:07:36 +0700 Subject: [PATCH 06/10] sync: pre-resolve the three files that conflict with master Takes master's ledger rows (the ratchet re-bless after the merge recounts max_not_pass and re-adds array_len_expr.t27), keeps both sides' source.rs tests and foreign-exception blocks, so GitHub's update-branch can merge master in without a conflict. Co-Authored-By: Claude Opus 5.5 (1M context) --- cli/t27b/tests/source.rs | 225 ++++++- docs/reports/t27b_expectations.json | 942 +++++++++++++++++++++------- tools/policy/foreign-exceptions.txt | 94 ++- 3 files changed, 1001 insertions(+), 260 deletions(-) diff --git a/cli/t27b/tests/source.rs b/cli/t27b/tests/source.rs index 8095061897..164f4b5fe9 100644 --- a/cli/t27b/tests/source.rs +++ b/cli/t27b/tests/source.rs @@ -525,6 +525,39 @@ test wrong_name_fails { assert_eq!(r[3].2, Err((TrapKind::Assert, 59))); } +/// A module var with a string in it (#7448): every test starts from its +/// initial value, which a fn may overwrite with another string. +#[test] +fn module_vars_hold_strings() { + let src = "module a;\n\nstruct Pin {\n port: str,\n bank: u8,\n}\n\nconst CLK: Pin = Pin{ .port = \"clk\", .bank = 14 };\n\nvar label: str = \"board\";\nvar pins: [2]Pin = [CLK, Pin{ .port = \"tx\", .bank = 34 }];\n\nfn rename() -> void {\n pins[0].port = \"renamed\";\n label = \"x\";\n}\n\ntest writes {\n rename();\n assert(pins[0].port == \"renamed\" and label == \"x\");\n}\n\ntest starts_fresh {\n assert(pins[0].port == \"clk\" and pins[1].bank == 34 and label == \"board\");\n}\n\ntest wrong_fails {\n assert(label == \"board\");\n assert(pins[1].port == \"clk\");\n}\n"; + let r = run(src); + let want = vec![("writes", false, true), ("starts_fresh", false, true), ("wrong_fails", false, false)]; + assert_eq!(names_ok(&r), want); + assert_eq!(r[2].2, Err((TrapKind::Assert, line_of(src, "assert(pins[1].port == \"clk\")")))); +} + +/// A module var declared `= undefined` starts as Zig's Debug build leaves it, +/// 0xAA in every byte, in every test (#7448). +#[test] +fn undefined_module_vars_read_as_0xaa() { + let src = "module a;\n\nstruct C {\n k: u32,\n on: bool,\n}\n\nvar w: [3]u32 = undefined;\nvar b: u8 = undefined;\nvar c: C = undefined;\n\ntest fresh {\n assert(w[0] == 0xAAAAAAAA and w[2] == 2863311530 and b == 170);\n}\n\ntest writes {\n w[1] = 4;\n c = C{ .k = 9, .on = true };\n assert(w[1] == 4 and w[0] == 0xAAAAAAAA and c.k == 9 and c.on);\n}\n\ntest fresh_again {\n assert(w[1] == 0xAAAAAAAA and c.k == 0xAAAAAAAA);\n}\n\ntest wrong_fails {\n assert(b == 170);\n assert(w[1] == 0);\n}\n"; + let r = run(src); + let want = vec![("fresh", false, true), ("writes", false, true), ("fresh_again", false, true), ("wrong_fails", false, false)]; + assert_eq!(names_ok(&r), want); + assert_eq!(r[3].2, Err((TrapKind::Assert, line_of(src, "assert(w[1] == 0)")))); +} + +/// A module var of an optional type that starts as `null` (#7910): zero bytes, a null flag, in every test; the +/// conformance spec passes (`t27c test-report`: 4 pass, none vacuous). Any other initial value stays refused. +#[test] +fn optional_module_vars_start_null() { + let ran = run(include_str!("../../../specs/tri/t27b/conformance/optional_module_var.t27")); + let got = names_ok(&ran); + assert!(got.len() == 4 && got.iter().all(|(_, inv, ok)| !inv && *ok), "{:?}", got); + let m = rejected("module a;\n\nvar g: ?u32 = 5;\n\ntest t {\n assert(g.? == 5);\n}\n"); + assert!(m.starts_with("t27b: unsupported construct VarDecl(module, pointer/slice) at line 3"), "{}", m); +} + #[test] fn string_rejections_are_precise() { let head = "module s;\n\nconst S: str = \"ab\";\n\n"; @@ -534,7 +567,8 @@ fn string_rejections_are_precise() { ("test t { assert(S.ptr == 0); }", "ExprFieldAccess(str)", "`.ptr` of a str"), ("test t { var s: str = \"x\"; s.len = 2; }", "StmtAssign", "assignment through a constant"), ("test t { assert(S); }", "condition", "expected bool, found a string"), - ("const P = struct { s: str };\nvar Q: P = P{ .s = \"x\" };\ntest t { assert(Q.s.len == 1); }", "VarDecl(module, pointer/str/slice)", "module-level var `Q`"), + ("var Q: []i32 = [1];\ntest t { assert(Q.len == 1); }", "VarDecl(module, pointer/slice)", "module-level var `Q`"), + ("var Q: str = undefined;\ntest t { assert(Q.len == 1); }", "ConstDecl", "`undefined` in a constant with strings"), ("fn g() str { return \"x\"; }\nconst P = struct { s: str };\nconst Q = P{ .s = g() };\ntest t { assert(Q.s.len == 1); }", "ConstDecl", "not a string literal"), ("const P = struct { s: str, n: u8 };\nfn h() u8 { return 1; }\nconst Q = P{ .s = \"x\", .n = h() };\ntest t { assert(Q.n == 1); }", "ConstDecl", "not a compile-time value"), ("fn f() u32 { return 1; }\nconst T: str = f();\ntest t { assert(T.len == 0); }", "ConstDecl", "not a string literal"), @@ -845,7 +879,7 @@ test text_repeat_fails { fn t27_array_spelling_rejections_are_precise() { let head = "module a;\n\nconst ONE: u32 = 1;\n\nfn total(xs: [u32]) u32 {\n return 0;\n}\n\nfn nested(xs: [[2]u32]) u32 {\n return 0;\n}\n\n"; let cases: &[(&str, &str, &str)] = &[ - ("fn f(p: [*]u8) u32 { return 0; }", "type [*]T", "a many-item pointer"), + ("fn f(p: [*]u8) u32 { return 0; }\ntest t { assert(f(undefined) == 0); }", "type [*]T", "a many-item pointer"), ("fn f(m: [str:u32]) u32 { return 0; }", "type [K:V]", "a map"), ("test t { assert(total([1; 2]) == 2); }", "ExprArrayLiteral(repeat to slice)", "where a slice is declared"), ( @@ -1291,12 +1325,18 @@ test overflow_traps { fn module_var_rejections_are_precise() { let head = "module a;\n\nvar g: u32 = 0;\n\n"; let cases: &[(&str, &str, &str)] = &[ - ("test t { var g: u32 = 1; assert(g == 1); }", "StmtLocal(shadows module var)", "`g` shadows"), + // The reference renames `g` to `g_lv` in the whole test: here that + // reaches a mention before the declaration, or one outside the + // block that declares it, and Zig refuses the file. + ("test t { assert(g == 0); var g: u32 = 1; assert(g == 1); }", "StmtLocal(shadows module var)", "`g` shadows"), + ("test t { if (true) { var g: u32 = 1; assert(g == 1); } assert(g == 0); }", "StmtLocal(shadows module var)", "`g` shadows"), + ("test t { var g: u32 = g + 1; assert(g == 1); }", "StmtLocal(shadows module var)", "`g` shadows"), + ("fn f() u32 { var g: u32 = 1; var g: u32 = 2; return g; }\ntest t { assert(f() == 2); }", "StmtLocal(shadows module var)", "`g` shadows"), ("fn f(g: u32) u32 { g = g + 1; return g; }\ntest t { assert(f(1) == 2); }", "StmtLocal(shadows module var)", "`g` shadows"), ("fn f(g: u32) u32 { return g; }\ntest t { assert(g == 0); }", "ExprIdentifier(renamed module var)", "`g_arg`"), ("invariant i { assert(g == 0); }", "ExprIdentifier(var at comptime)", "module-level var `g`"), ("var h = 3;\ntest t { assert(h == 3); }", "VarDecl(module, untyped)", "`h` has no type"), - ("const B: u32 = 2;\nvar h: u32 = B * 2;\ntest t { assert(h == 4); }", "VarDecl(module)", "not a compile-time integer"), + ("const B: u32 = 2;\nvar h: u32 = B / 0;\ntest t { assert(h == 1); }", "VarDecl(module)", "not a compile-time integer"), ]; for (body, construct, detail) in cases { let m = rejected(&format!("{}{}\n", head, body)); @@ -1312,6 +1352,13 @@ fn module_var_rejections_are_precise() { // next test starts from the declared value again. let write = "module c;\n\nvar g: u32 = 0;\n\nfn read() u32 { return g; }\n\ntest w {\n g = 5;\n assert(read() == 5);\n g += 1;\n assert(g == 6);\n}\n\ntest fresh {\n assert(g == 0);\n}\n"; assert_eq!(names_ok(&run(write)), vec![("w", false, true), ("fresh", false, true)]); + // A top-level local declared before any mention of the name, in a test + // or a fn: the reference's `g_lv` reaches exactly the mentions that are + // the local's, and a fn the body calls still reads the module var. + let shadow = "module d;\n\nvar g: u32 = 7;\n\nfn read() u32 { return g; }\n\nfn f(x: u32) u32 {\n var g: u32 = x * 3;\n g = g + 1;\n return g + read();\n}\n\ntest t {\n var g: u32 = 100;\n g = g + 5;\n assert(g == 105);\n assert(read() == 7);\n assert(f(2) == 14);\n}\n\ntest u {\n var g: u32 = 1;\n assert(g == 7);\n}\n"; + let r = run(shadow); + assert_eq!(names_ok(&r), vec![("t", false, true), ("u", false, false)]); + assert_eq!(r[1].2, Err((TrapKind::Assert, line_of(shadow, "g == 7")))); } #[test] @@ -2643,13 +2690,7 @@ fn optionals_the_reference_does_not_match_are_refused() { /// BLOCKED under `t27c test-report`, so t27b must not pass it either. #[test] fn shapes_the_reference_cannot_compile_are_refused() { - let cases: [(&str, &str); 5] = [ - // `var w = 1; w = 9;` at the top of a test: the reference emits the - // assignment as `const w = 9;`, a redeclaration. - ( - "module a;\n\ntest t {\n var w: u32 = 1;\n w = 9;\n assert(w == 9);\n}\n", - "StmtAssign(reference redeclares)", - ), + let cases: [(&str, &str); 4] = [ // A pointer param written only through `p.*`: the reference rebinds // it `var p = p_arg;`, which Zig rejects as never mutated. ( @@ -2676,6 +2717,9 @@ fn shapes_the_reference_cannot_compile_are_refused() { let m = rejected(src); assert!(m.starts_with(&format!("t27b: unsupported construct {}", want)), "{}", m); } + // Since #6295 the reference writes a test's own local in place (#7422). + let r = run("module w;\n\ntest t {\n var w: u32 = 1;\n w = 9;\n assert(w == 9);\n}\n\ntest u {\n var w: u32 = 1;\n w += 2;\n assert(w == 3);\n}\n\ntest v {\n var w: u32 = 1;\n w = 9;\n assert(w == 1);\n}\n"); + assert_eq!(names_ok(&r), vec![("t", false, true), ("u", false, true), ("v", false, false)]); // The near misses still run: a param the body assigns directly (the // reference's `var n = n_arg;` is then mutated) and a mapped field type. let r = run("module h;\n\nconst S = struct { name: str, xs: [u32; 2] };\n\nfn inc(n: u32) -> u32 {\n n = n + 1;\n return n;\n}\n\ntest t {\n assert(inc(1) == 2);\n}\n"); @@ -2732,7 +2776,7 @@ fn array_literals_typed_by_their_use() { /// The shapes next to those: the reference refuses the first three (`.{ ... }` /// of the wrong length, `.{ ... }` for a slice field of an anonymous literal) -/// or points into a constant (a non-empty slice field); a local also read +/// or builds it in the frame (run-time elements in a slice field); a local also read /// other than as an argument stays unsupported. #[test] fn array_literals_typed_by_their_use_rejections() { @@ -2740,9 +2784,9 @@ fn array_literals_typed_by_their_use_rejections() { let cases: &[(&str, &str, &str)] = &[ ("test t { const p = [1, 2, 3]; assert(first(p) == 1); }", "ExprArrayLiteral", "3 elements for `[2]u8`"), ( - "test t { const c = Cur{ .pos = 0, .data = [1, 2] }; assert(c.data.len == 2); }", + "test t { var v: i32 = 3; v += 1; const c = Cur{ .pos = 0, .data = [v, 2] }; assert(c.data.len == 2); }", "ExprArrayLiteral(to slice field)", - "a non-empty array literal for a slice field", + "an array literal of run-time values for a slice field", ), ( "test t { assert(take(.{ .pos = 0, .data = [] }) == 0); }", @@ -3145,3 +3189,156 @@ test ok { assert!(m.starts_with("t27b: unsupported construct ConstDecl at line"), "{}", m); assert!(m.contains("`OV` overflows u8"), "{}", m); } + +/// `return undefined;` in a void fn is a plain `return;`: the work before it +/// is kept, the work after it skipped. In a test block it stays refused. +#[test] +fn return_undefined_in_a_void_fn() { + let src = "module a; + +const C = struct { + n: u32, +}; + +fn bump(c: *C, stop: bool) -> void { + c.n = c.n + 1; + if (stop) { + return undefined; + } + c.n = c.n + 10; +} + +test kept { + var c = C{ .n = 0 }; + bump(&c, true); + assert(c.n == 1); + bump(&c, false); + assert(c.n == 12); +} + +test wrong { + var c = C{ .n = 0 }; + bump(&c, true); + assert(c.n == 11); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("kept", false, true), ("wrong", false, false)]); + assert_eq!(r[1].2, Err((TrapKind::Assert, line_of(src, "== 11")))); + let m = rejected("module a;\n\ntest t {\n return undefined;\n}\n"); + assert!(m.starts_with("t27b: unsupported construct "), "{}", m); +} + +/// `@setEvalBranchQuota(n);` does nothing at run time; a run-time, negative +/// or too-large operand is refused. +#[test] +fn eval_branch_quota_is_a_no_op() { + let src = "module a; + +const Q: u32 = 5000; + +fn f(x: u32) -> u32 { + var y: u32 = x; + @setEvalBranchQuota(Q); + y = y + 1; + @setEvalBranchQuota(10000); + return y; +} + +test t { + @setEvalBranchQuota(1); + assert(f(1) == 2); +} + +test wrong { + assert(f(1) == 1); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("t", false, true), ("wrong", false, false)]); + let cases = [ + "fn f() -> u32 {\n var n: u32 = 3;\n n = n + 1;\n @setEvalBranchQuota(n);\n return 0;\n}", + "fn f() -> u32 {\n @setEvalBranchQuota(-1);\n return 0;\n}", + "fn f() -> u32 {\n @setEvalBranchQuota(4294967296);\n return 0;\n}", + "fn f() -> u32 {\n @setEvalBranchQuota(1, 2);\n return 0;\n}", + ]; + for body in cases { + let m = rejected(&format!("module a;\n\n{}\n\ntest t {{\n assert(f() == 0);\n}}\n", body)); + assert!(m.starts_with("t27b: unsupported construct ExprCall(@setEvalBranchQuota) at line"), "{}: {}", body, m); + } +} + +/// #7415: a struct field's `T?` is `?T`, as t27c's type mapper writes it; +/// `T??` and `?T?` are an optional of an optional and are refused. +#[test] +fn postfix_optional_is_prefix_optional() { + let src = "module a; + +const R = struct { + note: str?, + n: u32?, +}; + +fn mk(b: bool) -> R { + if (b) { + return R{ .note = \"hi\", .n = 3 }; + } + return R{ .note = null, .n = null }; +} + +test t { + assert(mk(true).note.?.len == 2); + assert(mk(false).note == null); +} + +test wrong { + assert(mk(false).n != null); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("t", false, true), ("wrong", false, false)]); + for ty in ["u32??", "?u32?"] { + let m = rejected(&format!( + "module a;\n\nconst R = struct {{\n a: {},\n}};\n\nfn f(r: R) -> u32 {{\n return 1;\n}}\n\ntest t {{\n assert(f(R{{ .a = null }}) == 1);\n}}\n", + ty + )); + assert!(m.contains("type ?T(??T)"), "{}: {}", ty, m); + } +} + +/// `==` / `!=` between pointers and optional pointers compare addresses +/// (#7742): the conformance spec runs as `t27c test-report` does (3 pass). +#[test] +fn pointer_equality() { + let r = run(include_str!("../../../specs/tri/t27b/conformance/pointer_equality.t27")); + assert!(r.len() == 3 && names_ok(&r).iter().all(|(_, inv, ok)| !inv && *ok), "{:?}", names_ok(&r)); +} + +/// A frame over 16 KiB is allocated a page at a time, touching each page +/// (#7367): it runs, recursion included, no two frames overlap (each level +/// checks every byte of its array after the deeper ones returned), and a trap +/// inside one still names its line. A frame over 1 MiB is still refused. +#[test] +fn large_frames_are_probed() { + let src = "module a;\n\nfn deep(depth: u8) -> u32 {\n var block: [20000]u8 = undefined;\n var i: usize = 0;\n while (i < 20000) {\n block[i] = depth;\n i = i + 1;\n }\n var below: u32 = 0;\n if (depth > 0) {\n below = deep(depth - 1);\n }\n i = 0;\n while (i < 20000) {\n if (block[i] != depth) {\n return 0;\n }\n i = i + 1;\n }\n return below + 1;\n}\n\ntest ok {\n var buf: [16448]u8 = undefined;\n buf[0] = 7;\n buf[16447] = 9;\n assert(buf[0] + buf[16447] == 16);\n assert(deep(5) == 6);\n}\n\ntest fails {\n var big: [70000]u8 = undefined;\n big[69999] = 3;\n assert(big[69999] == 4);\n}\n"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("ok", false, true), ("fails", false, false)]); + assert_eq!(r[1].2, Err((TrapKind::Assert, line_of(src, "== 4")))); + if JIT_SUPPORTED { + let too_big = "module a;\n\ntest t {\n var huge: [1048600]u8 = undefined;\n huge[0] = 1;\n assert(huge[0] == 1);\n}\n"; + let prog = lower_src(too_big).expect("lowers"); + let e = codegen::compile(&prog, TrapStyle::Jit, true).err().expect("refused"); + assert_eq!(e.construct, "FnDecl(frame size)"); + } +} + +/// `?*anyopaque` and `@ptrFromInt` to an optional pointer (#7737): the +/// conformance spec runs as `t27c test-report` does (3 pass, none vacuous), +/// and a non-optional result is refused by name. +#[test] +fn opaque_pointers() { + let r = run(include_str!("../../../specs/tri/t27b/conformance/opaque_pointer.t27")); + assert!(r.len() == 3 && names_ok(&r).iter().all(|(_, inv, ok)| !inv && *ok), "{:?}", names_ok(&r)); + let m = rejected("module a;\n\nfn f(p: *anyopaque) -> bool {\n return true;\n}\n\ntest t {\n assert(f(@ptrFromInt(8)));\n}\n"); + assert!(m.contains("ExprCall(@ptrFromInt)") && m.contains("not optional"), "{}", m); +} diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index 8a40ea1e9b..abe3812d2b 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -2,9 +2,9 @@ "schema_version": 1, "generated_by": "tri t27b ratchet --bless (scripts/tri_loop/t27b.py), #6115", "source": { - "commit": "099ac2224267d28839ae880bda839e6d1dd5b0a4", + "commit": "606611ced01f3970553dced70e1a2547ab8fb383", "ref": "master", - "finished": "2026-10-06T01:49:39Z", + "finished": "2026-10-10T02:49:52Z", "asserts_counted": true }, "reasons": { @@ -12,37 +12,32 @@ "reference-bug": "the reference passes it for the wrong reason; t27b is right not to", "n/a": "outside what t27b is for (say why in the PR that sets it)" }, - "max_not_pass": 25, - "counts": { - "pass": 534, - "pass_vacuous": 262, - "not_pass": 25 - }, + "max_not_pass": 22, "entries": [ {"path": "specs/a/b_c.t27", "t27b": "pass_vacuous"}, {"path": "specs/a_b/c.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/a.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/b.t27", "t27b": "pass_vacuous"}, + {"path": "specs/agents/a.t27", "t27b": "pass"}, + {"path": "specs/agents/b.t27", "t27b": "pass"}, {"path": "specs/agents/c.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/d.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/e.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/f.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/g.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/h.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/i.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/j.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/k.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/l.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/m.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/n.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/o.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/p.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/q.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/r.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/s.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/t.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/ti.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/u.t27", "t27b": "pass_vacuous"}, + {"path": "specs/agents/d.t27", "t27b": "pass"}, + {"path": "specs/agents/e.t27", "t27b": "pass"}, + {"path": "specs/agents/f.t27", "t27b": "pass"}, + {"path": "specs/agents/g.t27", "t27b": "pass"}, + {"path": "specs/agents/h.t27", "t27b": "pass"}, + {"path": "specs/agents/i.t27", "t27b": "pass"}, + {"path": "specs/agents/j.t27", "t27b": "pass"}, + {"path": "specs/agents/k.t27", "t27b": "pass"}, + {"path": "specs/agents/l.t27", "t27b": "pass"}, + {"path": "specs/agents/m.t27", "t27b": "pass"}, + {"path": "specs/agents/n.t27", "t27b": "pass"}, + {"path": "specs/agents/o.t27", "t27b": "pass"}, + {"path": "specs/agents/p.t27", "t27b": "pass"}, + {"path": "specs/agents/q.t27", "t27b": "pass"}, + {"path": "specs/agents/r.t27", "t27b": "pass"}, + {"path": "specs/agents/s.t27", "t27b": "pass"}, + {"path": "specs/agents/t.t27", "t27b": "pass"}, + {"path": "specs/agents/ti.t27", "t27b": "pass"}, + {"path": "specs/agents/u.t27", "t27b": "pass"}, {"path": "specs/agents/v.t27", "t27b": "pass_vacuous"}, {"path": "specs/agents/w.t27", "t27b": "pass_vacuous"}, {"path": "specs/agents/x.t27", "t27b": "pass_vacuous"}, @@ -54,17 +49,38 @@ {"path": "specs/api/tri_api_permissions.t27", "t27b": "pass"}, {"path": "specs/api/tri_api_session.t27", "t27b": "pass"}, {"path": "specs/api/tri_net_api.t27", "t27b": "pass"}, + {"path": "specs/automation/agent-claims-honest.t27", "t27b": "pass"}, {"path": "specs/automation/agent-conversations.t27", "t27b": "pass"}, {"path": "specs/automation/agent-hive-group.t27", "t27b": "pass"}, + {"path": "specs/automation/agent-media-kie.t27", "t27b": "pass"}, + {"path": "specs/automation/agent-neuro-kie.t27", "t27b": "pass"}, {"path": "specs/automation/agent-provider-chain.t27", "t27b": "pass"}, + {"path": "specs/automation/agent-spec-bank.t27", "t27b": "pass"}, {"path": "specs/automation/ball-board.t27", "t27b": "pass"}, {"path": "specs/automation/ball-grants.t27", "t27b": "pass"}, {"path": "specs/automation/blog-share.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-agent-memory.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-agent-stream.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-agent-team.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-event-tabs.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-menu-press.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-neuro-office.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-office-crm.t27", "t27b": "pass"}, + {"path": "specs/automation/bot-topic-tabs.t27", "t27b": "pass"}, {"path": "specs/automation/browser-pod-restart.t27", "t27b": "pass"}, {"path": "specs/automation/browser-sign-in.t27", "t27b": "pass"}, + {"path": "specs/automation/browser-tab-strip.t27", "t27b": "pass"}, + {"path": "specs/automation/browser-viewer-boot.t27", "t27b": "pass"}, + {"path": "specs/automation/card-chat-night-watch.t27", "t27b": "pass"}, + {"path": "specs/automation/ci-bridge.t27", "t27b": "pass"}, + {"path": "specs/automation/claim-guard-bar.t27", "t27b": "pass"}, + {"path": "specs/automation/connect-card.t27", "t27b": "pass"}, + {"path": "specs/automation/course-outreach.t27", "t27b": "pass"}, + {"path": "specs/automation/crm-client-onboard.t27", "t27b": "pass"}, {"path": "specs/automation/crm-client-ownership.t27", "t27b": "pass"}, {"path": "specs/automation/crm-client-workspace.t27", "t27b": "pass"}, {"path": "specs/automation/crm-duet.t27", "t27b": "pass"}, + {"path": "specs/automation/crm-first-screen.t27", "t27b": "pass"}, {"path": "specs/automation/crm-lead-magnet.t27", "t27b": "pass"}, {"path": "specs/automation/crm-sellers.t27", "t27b": "pass"}, {"path": "specs/automation/crm-story-reel.t27", "t27b": "pass"}, @@ -78,16 +94,51 @@ {"path": "specs/automation/mail-push.t27", "t27b": "pass"}, {"path": "specs/automation/meeting-reminders.t27", "t27b": "pass"}, {"path": "specs/automation/meta-connect.t27", "t27b": "pass"}, + {"path": "specs/automation/owner-studio.t27", "t27b": "pass"}, + {"path": "specs/automation/photo-actions.t27", "t27b": "pass"}, + {"path": "specs/automation/plan-reel.t27", "t27b": "pass"}, {"path": "specs/automation/poster-facts-overlay.t27", "t27b": "pass"}, {"path": "specs/automation/queen-contributor-keys.t27", "t27b": "pass"}, {"path": "specs/automation/queen-growth.t27", "t27b": "pass"}, + {"path": "specs/automation/reddit-desk.t27", "t27b": "pass"}, {"path": "specs/automation/review-jam.t27", "t27b": "pass"}, {"path": "specs/automation/social-api.t27", "t27b": "pass"}, {"path": "specs/automation/split-reel.t27", "t27b": "pass"}, - {"path": "specs/automation/wrapup-auto.t27", "t27b": "blocked", "blocker": "StmtAssign", "reason": "unimplemented"}, + {"path": "specs/automation/token-wallet.t27", "t27b": "pass"}, + {"path": "specs/automation/tri-claim-batch.t27", "t27b": "pass"}, + {"path": "specs/automation/tri-wallet-chains.t27", "t27b": "pass"}, + {"path": "specs/automation/wrapup-auto.t27", "t27b": "pass"}, {"path": "specs/base/debounce.t27", "t27b": "pass"}, {"path": "specs/base/ring_32.t27", "t27b": "pass"}, {"path": "specs/base/seed.t27", "t27b": "pass"}, + {"path": "specs/base/types.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, + {"path": "specs/basics/01_what_a_spec_is.t27", "t27b": "pass"}, + {"path": "specs/basics/02_the_module_line.t27", "t27b": "pass"}, + {"path": "specs/basics/03_comments_and_prose.t27", "t27b": "pass"}, + {"path": "specs/basics/04_constants.t27", "t27b": "pass"}, + {"path": "specs/basics/05_whole_numbers.t27", "t27b": "pass"}, + {"path": "specs/basics/06_true_false_and_text.t27", "t27b": "pass"}, + {"path": "specs/basics/07_arrays.t27", "t27b": "pass"}, + {"path": "specs/basics/08_trits.t27", "t27b": "pass"}, + {"path": "specs/basics/09_expressions.t27", "t27b": "pass"}, + {"path": "specs/basics/10_a_test_block.t27", "t27b": "pass"}, + {"path": "specs/basics/11_many_tests.t27", "t27b": "pass"}, + {"path": "specs/basics/12_functions.t27", "t27b": "pass"}, + {"path": "specs/basics/13_local_names.t27", "t27b": "pass"}, + {"path": "specs/basics/14_if_and_else.t27", "t27b": "pass"}, + {"path": "specs/basics/15_loops.t27", "t27b": "blocked", "blocker": "type mismatch", "reason": "reference-bug"}, + {"path": "specs/basics/16_pub_or_private.t27", "t27b": "pass"}, + {"path": "specs/basics/17_structs.t27", "t27b": "pass"}, + {"path": "specs/basics/18_enums.t27", "t27b": "pass"}, + {"path": "specs/basics/19_use_other_modules.t27", "t27b": "pass"}, + {"path": "specs/basics/20_invariants.t27", "t27b": "pass"}, + {"path": "specs/basics/21_gen_ts.t27", "t27b": "pass"}, + {"path": "specs/basics/22_seven_backends.t27", "t27b": "pass"}, + {"path": "specs/basics/23_stages_of_t27c.t27", "t27b": "pass"}, + {"path": "specs/basics/24_tri_commands.t27", "t27b": "pass_vacuous"}, + {"path": "specs/basics/25_reading_errors.t27", "t27b": "pass"}, + {"path": "specs/basics/26_a_small_program.t27", "t27b": "pass"}, + {"path": "specs/basics/27_where_next.t27", "t27b": "pass"}, {"path": "specs/benchmarks/bench_main.t27", "t27b": "pass_vacuous"}, {"path": "specs/benchmarks/bench_nn.t27", "t27b": "pass"}, {"path": "specs/benchmarks/gf16_bfloat16_nmse.t27", "t27b": "pass"}, @@ -102,88 +153,112 @@ {"path": "specs/boards/arty_a7.t27", "t27b": "pass"}, {"path": "specs/boards/wukong_v1.t27", "t27b": "pass"}, {"path": "specs/boards/xc7a100t_full.t27", "t27b": "pass"}, - {"path": "specs/boards/xc7a100t_minimal.t27", "t27b": "blocked", "blocker": "VarDecl(module, pointer/str/slice)", "reason": "unimplemented"}, + {"path": "specs/boards/xc7a100t_minimal.t27", "t27b": "pass"}, {"path": "specs/brain/bus.t27", "t27b": "pass"}, {"path": "specs/brain/cognitive_loop.t27", "t27b": "pass"}, {"path": "specs/brain/phi_timing.t27", "t27b": "pass"}, {"path": "specs/brain/unified_state.t27", "t27b": "pass"}, {"path": "specs/catalog/discovery.t27", "t27b": "pass"}, + {"path": "specs/ci/affected.t27", "t27b": "pass"}, {"path": "specs/ci/delivery_metrics.t27", "t27b": "pass"}, {"path": "specs/ci/derived_data.t27", "t27b": "pass"}, + {"path": "specs/ci/gates/conflict_markers.t27", "t27b": "pass"}, + {"path": "specs/ci/gates/documented_commands.t27", "t27b": "pass"}, + {"path": "specs/ci/gates/verilog_widths.t27", "t27b": "pass"}, + {"path": "specs/ci/schema.t27", "t27b": "pass"}, {"path": "specs/compiler/c_array_repeat_wrapper.t27", "t27b": "pass"}, + {"path": "specs/compiler/c_fixed_array_return.t27", "t27b": "pass"}, + {"path": "specs/compiler/core/t27core.t27", "t27b": "pass"}, + {"path": "specs/compiler/core/t27core_ddc.t27", "t27b": "pass"}, {"path": "specs/compiler/meta_compile.t27", "t27b": "pass"}, {"path": "specs/compiler/optimizer.t27", "t27b": "pass"}, {"path": "specs/compiler/rust_constant_case.t27", "t27b": "pass"}, + {"path": "specs/compiler/rust_enum_order.t27", "t27b": "pass"}, + {"path": "specs/compiler/rust_optional_returns.t27", "t27b": "pass"}, {"path": "specs/compiler/rust_tail_returns.t27", "t27b": "pass"}, {"path": "specs/compiler/rust_value_parameters.t27", "t27b": "pass"}, + {"path": "specs/compiler/test_report_exit.t27", "t27b": "pass"}, {"path": "specs/compiler/theory/isa_round_trip.t27", "t27b": "pass"}, + {"path": "specs/compiler/theory/reproducible.t27", "t27b": "pass"}, {"path": "specs/compiler/theory/sieve.t27", "t27b": "pass"}, + {"path": "specs/compiler/theory/speed_quality.t27", "t27b": "pass"}, {"path": "specs/compiler/theory/toolchain.t27", "t27b": "pass"}, + {"path": "specs/compiler/theory/vacuity_census.t27", "t27b": "pass"}, + {"path": "specs/compiler/theory/warmup.t27", "t27b": "pass"}, + {"path": "specs/compiler/theory/warmup_t27b.t27", "t27b": "pass"}, + {"path": "specs/compiler/verilog_aos_memory.t27", "t27b": "pass"}, {"path": "specs/compiler/verilog_branch_context.t27", "t27b": "pass"}, - {"path": "specs/compiler/zig_field_syntax.t27", "t27b": "blocked", "blocker": "type str?", "reason": "unimplemented"}, + {"path": "specs/compiler/zig_empty_typed_array.t27", "t27b": "blocked", "blocker": "ExprArrayLiteral(reference empty typed)", "reason": "unimplemented"}, + {"path": "specs/compiler/zig_field_syntax.t27", "t27b": "blocked", "blocker": "ExprLiteral(literal)", "reason": "unimplemented"}, + {"path": "specs/compiler/zig_float_call_cast.t27", "t27b": "pass"}, {"path": "specs/compiler/zig_primitive_bindings.t27", "t27b": "pass"}, {"path": "specs/compiler/zig_scoped_type.t27", "t27b": "pass"}, - {"path": "specs/compiler/zig_test_shadowing.t27", "t27b": "blocked", "blocker": "StmtAssign(reference redeclares)", "reason": "unimplemented"}, + {"path": "specs/compiler/zig_test_shadowing.t27", "t27b": "pass"}, {"path": "specs/compiler/zig_value_ignored.t27", "t27b": "pass"}, {"path": "specs/conformance/e2e_scenarios.t27", "t27b": "pass"}, - {"path": "specs/crons/999-multibots-telegraf-agent-autopilot-L1118.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-bot-owner-billing-L474.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-check-stuck-trainings.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-ci.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-crmProactive-L375.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-daily-sales-advisor.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-generate-jobs-L164.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-health-check.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-log-monitor.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-notificationHandler-L318.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-notificationHandler-L324.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-periodic-webhook-health-check.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-production-monitor-L80.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-provider-health-monitor-L344.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-render-server-L10845.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-render-server-L2301.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-render-server-L2325.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-render-server-L919.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-security.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-skill-detector.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-taskCache-L27.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/999-multibots-telegraf-video-task-store-L156.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-alerts-digest.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-alerts-watchdog.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-browseros-cron-watchdog.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-dev-cache-clean.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-jobsearch-poller.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-leela-dailyquote.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-mail-bridge.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-mcp-hub.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-neo-boards.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-neo-jobsearch.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-reviewer-bees.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-signup-watch.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-trios-cycle-heal.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-trios-cycle.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-trios-doctor.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-trios-feed.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/mac-trios-heal.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/railway-jobsearch-cron.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/t27-formal-mutation.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/t27-pr-dashboard.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/trinity-agent-cron-cleanup.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/trinity-agent-queue-drain.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/trinity-brain-ci.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/trinity-codegen.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/trinity-discover-callers.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/trinity-pages-health-check.t27", "t27b": "pass_vacuous"}, - {"path": "specs/crons/trinity-signal-health-self.t27", "t27b": "pass_vacuous"}, + {"path": "specs/crons/999-multibots-telegraf-agent-autopilot-L1118.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-bot-owner-billing-L474.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-check-stuck-trainings.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-ci.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-client-telemetry-daily.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-club-invoice-abandoned-watch.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-crm-proactive-sweep.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-crmProactive-L375.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-daily-sales-advisor.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-generate-jobs-L164.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-health-check.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-log-monitor.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-notificationHandler-L318.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-notificationHandler-L324.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-periodic-webhook-health-check.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-production-monitor-L80.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-provider-health-monitor-L344.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-render-server-L10845.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-render-server-L2301.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-render-server-L2325.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-render-server-L919.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-robokassa-unclaimed-watch.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-security.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-skill-detector.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-taskCache-L27.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-ton-pending-watch.t27", "t27b": "pass"}, + {"path": "specs/crons/999-multibots-telegraf-video-task-store-L156.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-alerts-digest.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-alerts-watchdog.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-browseros-cron-watchdog.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-dev-cache-clean.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-jobsearch-poller.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-leela-dailyquote.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-mail-bridge.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-mcp-hub.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-neo-boards.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-neo-jobsearch.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-reviewer-bees.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-signup-watch.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-trios-cycle-heal.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-trios-cycle.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-trios-doctor.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-trios-feed.t27", "t27b": "pass"}, + {"path": "specs/crons/mac-trios-heal.t27", "t27b": "pass"}, + {"path": "specs/crons/railway-jobsearch-cron.t27", "t27b": "pass"}, + {"path": "specs/crons/t27-formal-mutation.t27", "t27b": "pass"}, + {"path": "specs/crons/t27-pr-dashboard.t27", "t27b": "pass"}, + {"path": "specs/crons/trinity-agent-cron-cleanup.t27", "t27b": "pass"}, + {"path": "specs/crons/trinity-agent-queue-drain.t27", "t27b": "pass"}, + {"path": "specs/crons/trinity-brain-ci.t27", "t27b": "pass"}, + {"path": "specs/crons/trinity-codegen.t27", "t27b": "pass"}, + {"path": "specs/crons/trinity-discover-callers.t27", "t27b": "pass"}, + {"path": "specs/crons/trinity-pages-health-check.t27", "t27b": "pass"}, + {"path": "specs/crons/trinity-signal-health-self.t27", "t27b": "pass"}, {"path": "specs/crons/trinity-site-live-gate.t27", "t27b": "pass"}, {"path": "specs/demos/simple_test.t27", "t27b": "pass"}, - {"path": "specs/docs/chapters/alphabet.t27", "t27b": "pass_vacuous"}, - {"path": "specs/docs/chapters/evidence.t27", "t27b": "pass_vacuous"}, - {"path": "specs/docs/chapters/layers.t27", "t27b": "pass_vacuous"}, - {"path": "specs/docs/chapters/project.t27", "t27b": "pass_vacuous"}, - {"path": "specs/docs/chapters/queen.t27", "t27b": "pass_vacuous"}, - {"path": "specs/docs/chapters/rules.t27", "t27b": "pass_vacuous"}, - {"path": "specs/docs/chapters/tooling.t27", "t27b": "pass_vacuous"}, + {"path": "specs/docs/chapters/alphabet.t27", "t27b": "pass"}, + {"path": "specs/docs/chapters/evidence.t27", "t27b": "pass"}, + {"path": "specs/docs/chapters/layers.t27", "t27b": "pass"}, + {"path": "specs/docs/chapters/project.t27", "t27b": "pass"}, + {"path": "specs/docs/chapters/queen.t27", "t27b": "pass"}, + {"path": "specs/docs/chapters/rules.t27", "t27b": "pass"}, + {"path": "specs/docs/chapters/tooling.t27", "t27b": "pass"}, {"path": "specs/docs/system.t27", "t27b": "pass_vacuous"}, {"path": "specs/fpga/adapter.t27", "t27b": "pass"}, {"path": "specs/fpga/assembler.t27", "t27b": "pass"}, @@ -192,17 +267,27 @@ {"path": "specs/fpga/bootrom.t27", "t27b": "pass"}, {"path": "specs/fpga/bpsk.t27", "t27b": "pass"}, {"path": "specs/fpga/clock_domain.t27", "t27b": "pass"}, + {"path": "specs/fpga/coverage.t27", "t27b": "pass"}, {"path": "specs/fpga/crossopt.t27", "t27b": "pass"}, {"path": "specs/fpga/cts.t27", "t27b": "pass"}, {"path": "specs/fpga/dft.t27", "t27b": "pass"}, {"path": "specs/fpga/e2e_demo.t27", "t27b": "pass"}, + {"path": "specs/fpga/eth_beacon.t27", "t27b": "pass"}, + {"path": "specs/fpga/eth_crc.t27", "t27b": "pass"}, + {"path": "specs/fpga/eth_rx.t27", "t27b": "pass"}, {"path": "specs/fpga/fifo.t27", "t27b": "pass"}, {"path": "specs/fpga/gf16_accel.t27", "t27b": "pass"}, {"path": "specs/fpga/hw_types.t27", "t27b": "pass"}, {"path": "specs/fpga/linker.t27", "t27b": "pass"}, {"path": "specs/fpga/memory.t27", "t27b": "pass"}, + {"path": "specs/fpga/mmcm.t27", "t27b": "pass"}, + {"path": "specs/fpga/mtbf.t27", "t27b": "pass"}, {"path": "specs/fpga/partition.t27", "t27b": "pass"}, {"path": "specs/fpga/power.t27", "t27b": "pass"}, + {"path": "specs/fpga/power_analysis.t27", "t27b": "pass"}, + {"path": "specs/fpga/reset_sync.t27", "t27b": "pass"}, + {"path": "specs/fpga/rgmii.t27", "t27b": "pass"}, + {"path": "specs/fpga/rgmii_sniff.t27", "t27b": "pass"}, {"path": "specs/fpga/router.t27", "t27b": "pass"}, {"path": "specs/fpga/simulator.t27", "t27b": "pass"}, {"path": "specs/fpga/stdlib.t27", "t27b": "pass"}, @@ -216,41 +301,48 @@ {"path": "specs/fpga/testbench/power_tb.t27", "t27b": "pass"}, {"path": "specs/fpga/testbench/router_tb.t27", "t27b": "pass"}, {"path": "specs/fpga/testbench/simulator_tb.t27", "t27b": "pass"}, + {"path": "specs/fpga/testbench/timing_tb.t27", "t27b": "pass"}, {"path": "specs/fpga/testbench/vcd_trace_tb.t27", "t27b": "pass"}, {"path": "specs/fpga/timing.t27", "t27b": "pass"}, - {"path": "specs/functions/analytics-sales-advise.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/analytics-skills-detect.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/broadcast-message-send.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/content-detailed-script-generate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/content-scenario-clips-generate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/content-scripts-generate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/crm-proactive-sweep.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/instagram-competitors-find.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/instagram-reels-analyze.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/instagram-top-content-extract.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/monitoring-error-report.t27", "t27b": "pass_vacuous"}, + {"path": "specs/fpga/trinet_node.t27", "t27b": "pass"}, + {"path": "specs/fpga/verification/build_verify.t27", "t27b": "pass"}, + {"path": "specs/functions/analytics-sales-advise.t27", "t27b": "pass"}, + {"path": "specs/functions/analytics-skills-detect.t27", "t27b": "pass"}, + {"path": "specs/functions/broadcast-message-send.t27", "t27b": "pass"}, + {"path": "specs/functions/client-telemetry-daily.t27", "t27b": "pass"}, + {"path": "specs/functions/club-invoice-abandoned-watch.t27", "t27b": "pass"}, + {"path": "specs/functions/content-detailed-script-generate.t27", "t27b": "pass"}, + {"path": "specs/functions/content-scenario-clips-generate.t27", "t27b": "pass"}, + {"path": "specs/functions/content-scripts-generate.t27", "t27b": "pass"}, + {"path": "specs/functions/crm-proactive-sweep.t27", "t27b": "pass"}, + {"path": "specs/functions/instagram-competitors-find.t27", "t27b": "pass"}, + {"path": "specs/functions/instagram-reels-analyze.t27", "t27b": "pass"}, + {"path": "specs/functions/instagram-top-content-extract.t27", "t27b": "pass"}, + {"path": "specs/functions/monitoring-error-report.t27", "t27b": "pass"}, {"path": "specs/functions/monitoring-health-check.t27", "t27b": "pass_vacuous"}, {"path": "specs/functions/monitoring-logs-analyze.t27", "t27b": "pass_vacuous"}, {"path": "specs/functions/monitoring-logs-trigger.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/morph-images-generate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/neuro-image-generate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/payment-ai-server-process.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/reels-ai-callback.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/reels-ai-generate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/reels-loop-generate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/render-avatar-video-run.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/render-job-run.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/render-riddle-run.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/training-model-complete.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/training-model-start.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/training-model-v2-start.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/training-stuck-check.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/webhook-generation-validate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/functions/welcome-avatar-generate.t27", "t27b": "pass_vacuous"}, + {"path": "specs/functions/morph-images-generate.t27", "t27b": "pass"}, + {"path": "specs/functions/neuro-image-generate.t27", "t27b": "pass"}, + {"path": "specs/functions/payment-ai-server-process.t27", "t27b": "pass"}, + {"path": "specs/functions/reels-ai-callback.t27", "t27b": "pass"}, + {"path": "specs/functions/reels-ai-generate.t27", "t27b": "pass"}, + {"path": "specs/functions/reels-loop-generate.t27", "t27b": "pass"}, + {"path": "specs/functions/render-avatar-video-run.t27", "t27b": "pass"}, + {"path": "specs/functions/render-job-run.t27", "t27b": "pass"}, + {"path": "specs/functions/render-riddle-run.t27", "t27b": "pass"}, + {"path": "specs/functions/robokassa-unclaimed-watch.t27", "t27b": "pass"}, + {"path": "specs/functions/ton-pending-watch.t27", "t27b": "pass"}, + {"path": "specs/functions/training-model-complete.t27", "t27b": "pass"}, + {"path": "specs/functions/training-model-start.t27", "t27b": "pass"}, + {"path": "specs/functions/training-model-v2-start.t27", "t27b": "pass"}, + {"path": "specs/functions/training-stuck-check.t27", "t27b": "pass"}, + {"path": "specs/functions/webhook-generation-validate.t27", "t27b": "pass"}, + {"path": "specs/functions/welcome-avatar-generate.t27", "t27b": "pass"}, {"path": "specs/github/auth.t27", "t27b": "pass"}, - {"path": "specs/i18n/agents-ru.t27", "t27b": "pass_vacuous"}, + {"path": "specs/i18n/agents-ru.t27", "t27b": "pass"}, {"path": "specs/i18n/blog-ru.t27", "t27b": "pass"}, - {"path": "specs/i18n/docs-ru.t27", "t27b": "pass_vacuous"}, + {"path": "specs/i18n/docs-ru.t27", "t27b": "pass"}, {"path": "specs/igla/race/mvp_ternary_classifier.t27", "t27b": "pass"}, {"path": "specs/igla/race/phi_accumulator_growth.t27", "t27b": "pass"}, {"path": "specs/igla/race/phi_gain_freedom.t27", "t27b": "pass"}, @@ -260,20 +352,35 @@ {"path": "specs/igla/race/ternary_node.t27", "t27b": "pass"}, {"path": "specs/igla/race/unit_weights_node.t27", "t27b": "pass"}, {"path": "specs/igla/w535_bounded_while_module.t27", "t27b": "pass"}, + {"path": "specs/isa/t27a.t27", "t27b": "pass"}, + {"path": "specs/isa/t27a_mnemonics.t27", "t27b": "pass"}, {"path": "specs/isa/ternary_encoding.t27", "t27b": "pass"}, - {"path": "specs/isa/ternary_gates.t27", "t27b": "blocked", "blocker": "ExprArrayLiteral", "reason": "unimplemented"}, + {"path": "specs/isa/ternary_gates.t27", "t27b": "pass"}, {"path": "specs/isa/ternary_graph.t27", "t27b": "pass_vacuous"}, {"path": "specs/isa/tri27_bytecode.t27", "t27b": "pass"}, + {"path": "specs/isa/tri27_machine.t27", "t27b": "pass"}, + {"path": "specs/jobs/release_t27c.t27", "t27b": "pass"}, {"path": "specs/lsp/language.t27", "t27b": "pass_vacuous"}, + {"path": "specs/math/constants.t27", "t27b": "blocked", "blocker": "ExprCall(@rem)", "reason": "unimplemented"}, {"path": "specs/math/gf_competitive.t27", "t27b": "pass"}, + {"path": "specs/memory/graph/crypt.t27", "t27b": "pass"}, + {"path": "specs/memory/graph/scope.t27", "t27b": "pass"}, + {"path": "specs/memory/graph/temporal.t27", "t27b": "pass"}, + {"path": "specs/memory/graph/types.t27", "t27b": "pass"}, {"path": "specs/memory/tmem/session.t27", "t27b": "pass"}, {"path": "specs/memory/tmem/types.t27", "t27b": "pass"}, {"path": "specs/mesh_routing.t27", "t27b": "pass_vacuous"}, - {"path": "specs/ml/activation/sigmoid_activation.t27", "t27b": "blocked", "blocker": "ExprCall(@exp)", "reason": "unimplemented"}, - {"path": "specs/ml/activation/silu_swish_vbt_activation.t27", "t27b": "pass_vacuous"}, + {"path": "specs/ml/activation/sigmoid_activation.t27", "t27b": "blocked", "blocker": "StmtAssign", "reason": "unimplemented"}, {"path": "specs/ml/layers/conv2d_layer.t27", "t27b": "pass"}, - {"path": "specs/ml/layers/layernorm_layer.t27", "t27b": "blocked", "blocker": "StmtAssign(undeclared)", "reason": "unimplemented"}, - {"path": "specs/ml/rl/dqn.t27", "t27b": "blocked", "blocker": "ExprCall(@max)", "reason": "unimplemented"}, + {"path": "specs/ml/layers/layernorm_layer.t27", "t27b": "pass"}, + {"path": "specs/ml/layers/residual_connection.t27", "t27b": "pass"}, + {"path": "specs/ml/loss/huber_loss.t27", "t27b": "pass"}, + {"path": "specs/ml/loss/kl_divergence.t27", "t27b": "pass"}, + {"path": "specs/ml/loss/mse_loss.t27", "t27b": "pass"}, + {"path": "specs/ml/optimizer/rmsprop.t27", "t27b": "pass"}, + {"path": "specs/ml/recurrent/self_attention.t27", "t27b": "pass"}, + {"path": "specs/ml/rl/dqn.t27", "t27b": "pass"}, + {"path": "specs/ml/transformer/multi_head_attention.t27", "t27b": "pass"}, {"path": "specs/multipath_router.t27", "t27b": "pass_vacuous"}, {"path": "specs/numeric/bnf1024.t27", "t27b": "pass"}, {"path": "specs/numeric/bnf128.t27", "t27b": "pass"}, @@ -283,28 +390,32 @@ {"path": "specs/numeric/bnf512.t27", "t27b": "pass"}, {"path": "specs/numeric/bnf64.t27", "t27b": "pass"}, {"path": "specs/numeric/bnf8.t27", "t27b": "pass"}, + {"path": "specs/numeric/catalog_paper_count.t27", "t27b": "pass"}, {"path": "specs/numeric/e8m0.t27", "t27b": "pass"}, + {"path": "specs/numeric/formats.t27", "t27b": "blocked", "blocker": "ExprArrayLiteral", "reason": "unimplemented"}, {"path": "specs/numeric/formats_catalog.t27", "t27b": "pass_vacuous"}, {"path": "specs/numeric/gf10.t27", "t27b": "pass"}, {"path": "specs/numeric/gf1024.t27", "t27b": "pass"}, {"path": "specs/numeric/gf128.t27", "t27b": "pass"}, {"path": "specs/numeric/gf14.t27", "t27b": "pass"}, + {"path": "specs/numeric/gf16.t27", "t27b": "pass"}, {"path": "specs/numeric/gf256.t27", "t27b": "pass"}, {"path": "specs/numeric/gf48.t27", "t27b": "pass"}, {"path": "specs/numeric/gf512.t27", "t27b": "pass"}, {"path": "specs/numeric/gf6.t27", "t27b": "pass"}, {"path": "specs/numeric/gf96.t27", "t27b": "pass"}, - {"path": "specs/numeric/gft1024.t27", "t27b": "blocked", "blocker": "type u1024", "reason": "unimplemented"}, - {"path": "specs/numeric/gft128.t27", "t27b": "blocked", "blocker": "type u128", "reason": "unimplemented"}, + {"path": "specs/numeric/gft1024.t27", "t27b": "pass"}, + {"path": "specs/numeric/gft128.t27", "t27b": "pass"}, {"path": "specs/numeric/gft16.t27", "t27b": "pass"}, - {"path": "specs/numeric/gft256.t27", "t27b": "blocked", "blocker": "type u256", "reason": "unimplemented"}, + {"path": "specs/numeric/gft256.t27", "t27b": "pass"}, {"path": "specs/numeric/gft32.t27", "t27b": "pass"}, {"path": "specs/numeric/gft4.t27", "t27b": "pass"}, - {"path": "specs/numeric/gft512.t27", "t27b": "blocked", "blocker": "type u512", "reason": "unimplemented"}, + {"path": "specs/numeric/gft512.t27", "t27b": "pass"}, {"path": "specs/numeric/gft64.t27", "t27b": "pass"}, {"path": "specs/numeric/gft8.t27", "t27b": "pass"}, - {"path": "specs/numeric/gfternary.t27", "t27b": "blocked", "blocker": "ExprCall(@setEvalBranchQuota)", "reason": "unimplemented"}, + {"path": "specs/numeric/gfternary.t27", "t27b": "pass"}, {"path": "specs/numeric/golden_sieve.t27", "t27b": "pass"}, + {"path": "specs/numeric/ocp_mx.t27", "t27b": "pass"}, {"path": "specs/numeric/requant_boundary.t27", "t27b": "pass_vacuous"}, {"path": "specs/numeric/tnf1024.t27", "t27b": "pass"}, {"path": "specs/numeric/tnf128.t27", "t27b": "pass"}, @@ -322,67 +433,161 @@ {"path": "specs/physics/hslm_benchmark.t27", "t27b": "pass"}, {"path": "specs/physics/lqg_cs_bridge.t27", "t27b": "pass"}, {"path": "specs/physics/lqg_entropy.t27", "t27b": "pass_vacuous"}, + {"path": "specs/policy/issue_shape.t27", "t27b": "pass"}, + {"path": "specs/policy/l2_generation.t27", "t27b": "pass"}, + {"path": "specs/policy/lang_en.t27", "t27b": "pass"}, + {"path": "specs/policy/merge_ours.t27", "t27b": "pass"}, {"path": "specs/policy/own_language.t27", "t27b": "pass"}, + {"path": "specs/policy/required_contexts.t27", "t27b": "pass"}, + {"path": "specs/policy/text_lines.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/bridge.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/cc_gate.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/check_calls.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/AsmRelocEntry_new.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/compiler/AsmSectionKind_from_i8.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/AssembledInstr_r_type.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/compiler/HirBusPort_axi4_lite_slave.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/HirClockDomain_new.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/compiler/HirCoverPoint_new.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/compiler/HirGf16FftConfig_fft_stages.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/HirIpCatalog_new.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/compiler/HirTernaryRegFile_new.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/HwType_hw_width.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/LinkSection_text.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/LoopGuard_loop_cond.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/compiler/TbCheck_new.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/compiler/collect_type_decls.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/enrichment/mod.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/jwt.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/parse_conform.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/phi_f64_literals.t27", "t27b": "blocked", "blocker": "type i128", "reason": "unimplemented"}, + {"path": "specs/port/bootstrap/src/phi_selfcheck.t27", "t27b": "pass"}, {"path": "specs/port/bootstrap/src/sensitivity.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/source_kind.t27", "t27b": "pass"}, + {"path": "specs/port/bootstrap/src/weight_bram.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/health.t27", "t27b": "pass"}, - {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/memory.t27", "t27b": "codegen", "blocker": "t27b: unsupported construct FnDecl(frame size) at line 0 (fn save_memory_content_too_long: 50032 bytes of local aggregates; at most 16384 per frame)", "reason": "unimplemented"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/memory.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-lease.t27", "t27b": "blocked", "blocker": "ExprArrayLiteral(reference empty typed)", "reason": "unimplemented"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-needs-you.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-public-agents.t27", "t27b": "blocked", "blocker": "type anytype", "reason": "unimplemented"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-registry.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-rehearsal.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/queen-report.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/routes/status.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/services/a2a/a2a-liveness.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/api/services/openclaw/claw-session.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/browser/bookmarks.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/browser/history.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/lib/agents/runtime/registry.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/lib/db/retry.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/lib/identity.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/lib/port-binding.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/lib/provider-error-classifier.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/monitoring/envelope.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/skills/catalog.t27", "t27b": "pass"}, {"path": "specs/port/browseros/trios/agent-server/apps/server/src/tools/filesystem/ls.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/tools/memory/write.t27", "t27b": "pass"}, + {"path": "specs/port/browseros/trios/agent-server/apps/server/src/tools/tool-registry.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/bscan_spi_qmtech/bscan_spi_qmtech.t27", "t27b": "pass"}, {"path": "specs/port/fpga/openxc7-synth/phi_temporal/temporal_heartbeat.t27", "t27b": "pass"}, {"path": "specs/port/fpga/verilog/dsp_probe.t27", "t27b": "pass"}, {"path": "specs/port/fpga/verilog/dsp_probe_live.t27", "t27b": "pass"}, {"path": "specs/port/fpga/verilog/e8m0_jtag.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/gft_bitnet_neuron_jtag.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/gft_dot4_comm_jtag.t27", "t27b": "pass"}, {"path": "specs/port/fpga/verilog/gft_dup2_jtag.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/gft_dup3_jtag.t27", "t27b": "pass"}, {"path": "specs/port/fpga/verilog/gft_signed_dot4_jtag.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/gft_smul_jtag.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/gft_train1_jtag.t27", "t27b": "pass"}, {"path": "specs/port/fpga/verilog/link_node.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/mvp_ternary_classifier_top.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/phi_weights_jtag.t27", "t27b": "pass"}, {"path": "specs/port/fpga/verilog/ternary_mac_demo_top.t27", "t27b": "pass"}, - {"path": "specs/port/fpga/verilog/ternary_mac_synth.t27", "t27b": "blocked", "blocker": "ExprArrayLiteral(reference empty typed)", "reason": "unimplemented"}, + {"path": "specs/port/fpga/verilog/ternary_mac_synth.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/verilog/ternary_node_jtag.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/vivado/blinky.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/vivado/gf16_matmul4x4.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/vivado/gf16_top.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/vivado/gf16_uart_sim_bench.t27", "t27b": "pass"}, {"path": "specs/port/fpga/vivado/uart_detect_top.t27", "t27b": "pass"}, {"path": "specs/port/fpga/vivado/uart_echo_top.t27", "t27b": "pass"}, + {"path": "specs/port/fpga/vsa/temporal_heartbeat_top.t27", "t27b": "pass"}, {"path": "specs/port/scripts/aggregate-experience.t27", "t27b": "pass"}, {"path": "specs/port/scripts/bulk-create-notebooks.t27", "t27b": "pass"}, {"path": "specs/port/scripts/check-conflicts.t27", "t27b": "pass"}, {"path": "specs/port/scripts/check-pagination-truncation.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/check_first_party_doc_language.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/ci/loop-tools-tracked.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/ci/rings_matrix.t27", "t27b": "pass"}, {"path": "specs/port/scripts/fpga-build.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/fpga/flash.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w309.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w310.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w311.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w314.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w315.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w316.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w317.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w318.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w320.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w322.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w326.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w363.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w365.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w368.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w377.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w378.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w379.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w380.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w381.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w381_lean.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w382.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w384.t27", "t27b": "pass"}, - {"path": "specs/port/scripts/gen_w384_lean.t27", "t27b": "codegen", "blocker": "t27b: unsupported construct FnDecl(frame size) at line 0 (fn main_appends_the_exact_w384_text: 16448 bytes of local aggregates; at most 16384 per frame)", "reason": "unimplemented"}, + {"path": "specs/port/scripts/gen_w384_lean.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w385.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w386.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w387.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w388_lean.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w391.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w391_lean.t27", "t27b": "pass"}, {"path": "specs/port/scripts/gen_w631.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w632.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w633.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w634.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w635.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w636.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w637.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w638.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w639.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w640.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w641.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w642.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w643.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w644.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w645.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w646.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w647.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w648.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w649.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w650.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w651.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w652.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w653.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w654.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w655.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w656.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w657.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w662.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/gen_w_blocks.t27", "t27b": "pass"}, {"path": "specs/port/scripts/generate_episodes.t27", "t27b": "pass"}, {"path": "specs/port/scripts/git_commands_tasks_1_4.t27", "t27b": "pass"}, {"path": "specs/port/scripts/install-constitutional-hook.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/lee_monte_carlo_baseline.t27", "t27b": "pass"}, {"path": "specs/port/scripts/mcp-wrapper.t27", "t27b": "pass"}, {"path": "specs/port/scripts/print_pellis_seal_decimal.t27", "t27b": "pass"}, {"path": "specs/port/scripts/pysr_trinity_blind_test_v2.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/reseal-apply.t27", "t27b": "pass"}, {"path": "specs/port/scripts/reseal-check.t27", "t27b": "pass"}, {"path": "specs/port/scripts/run_v51_multiple.t27", "t27b": "pass"}, {"path": "specs/port/scripts/test-agent-bridge.t27", "t27b": "pass"}, @@ -390,32 +595,57 @@ {"path": "specs/port/scripts/tri-pr-create.t27", "t27b": "pass"}, {"path": "specs/port/scripts/tri-search.t27", "t27b": "pass"}, {"path": "specs/port/scripts/tri-sync.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/tri_loop/claims.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/tri_loop/corpus_parse.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/tri_loop/loop_rules.t27", "t27b": "pass_vacuous"}, + {"path": "specs/port/scripts/tri_loop/now_numbers.t27", "t27b": "pass"}, {"path": "specs/port/scripts/tri_loop/t27b_rules.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/ultra_engine_v70_ultimate.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/validate_phi_f64.t27", "t27b": "pass"}, {"path": "specs/port/scripts/verify_precision.t27", "t27b": "pass"}, {"path": "specs/port/scripts/verify_smoking_guns.t27", "t27b": "pass"}, + {"path": "specs/port/scripts/wrapup/extract-context.t27", "t27b": "pass"}, + {"path": "specs/port/tools/backend_parity_table.t27", "t27b": "pass"}, + {"path": "specs/port/tools/bees/merger_gate_selftest.t27", "t27b": "blocked", "blocker": "type (anonymous struct)", "reason": "unimplemented"}, + {"path": "specs/port/tools/check_catalog_integrity.t27", "t27b": "pass"}, {"path": "specs/port/tools/check_duplicate_declarations.t27", "t27b": "pass_vacuous"}, {"path": "specs/port/tools/check_fix_carries_source.t27", "t27b": "pass"}, {"path": "specs/port/tools/ci/check_specs_still_parse.t27", "t27b": "pass"}, {"path": "specs/port/tools/gft_deep_demo.t27", "t27b": "pass"}, + {"path": "specs/port/tools/jtag/tdo_verdict.t27", "t27b": "pass"}, {"path": "specs/port/tools/oracle/run.t27", "t27b": "pass"}, {"path": "specs/port/tools/run_conformance_vvp.t27", "t27b": "pass"}, {"path": "specs/port/tools/ternary_model.t27", "t27b": "pass"}, + {"path": "specs/port/tools/toolbelt.t27", "t27b": "pass"}, + {"path": "specs/port/tools/verify_emit_bitexact.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/fly-vivado/verilog/trinity_qmtech.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/gft/tb32.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-regress/regress-fabric-bufg/fabric_bufg.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/DSP48E1_mock.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/blink_correct.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/blink_fast.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/blink_fixed.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/blink_minimal.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/blink_r23.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/blink_simple.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/blink_slow.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/blink_working.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/clk_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/clock_test.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/d6_blink.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d6_inv_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d6_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_bank13_test.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/d_blink_high.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_bufg_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_clk_direct.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/d_direct.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_e21_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_f19_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_full_path.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_g22_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_lut_only.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/d_multi_led.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_oscillator.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_simple_ff.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_simple_led.t27", "t27b": "pass"}, @@ -425,88 +655,173 @@ {"path": "specs/port/trinity/fpga/openxc7-synth/d_static_one.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/d_y0_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/definitive_diagnostic_inv.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/dsp_mul.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/led_both_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/led_d5_test.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/led_d6_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/led_diagnostic.t27", "t27b": "pass"}, - {"path": "specs/port/trinity/fpga/openxc7-synth/led_off_test.t27", "t27b": "blocked", "blocker": "type u1", "reason": "unimplemented"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/led_off_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/led_on_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/led_simple_test.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/led_test_inv.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/multi_led_test.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/quantum_bridge_top.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/singularity_d6_top.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/symbiflow_blink.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/ternary_activation.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/openxc7-synth/trinity_top.t27", "t27b": "pass"}, {"path": "specs/port/trinity/fpga/openxc7-synth/uart_echo.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/rtl/fpga_test_reporter.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/uart_loopback.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/fpga/uart_loopback_core.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/background_agent/main.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/brain/orbitofrontal_value.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/brain/weber_tuning.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/cli/health_check.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/cli/railway_create_full.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/cli/railway_create_project.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/cli/railway_deployment_create.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/cli/railway_null_startcmd.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/firebird/governance_temp.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/phi-engine/vibeec_original/bogatyrs_registry.t27", "t27b": "blocked", "blocker": "type (generic)", "reason": "unimplemented"}, + {"path": "specs/port/trinity/src/phi-engine/vibeec_original/tnc.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/server_main.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/storm/experience_engine.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_aabb.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_arithmetic.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_assertion.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_barrier.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_base64.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_bezier.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_cache.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_caesar.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_canvas.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_color.t27", "t27b": "pass"}, - {"path": "specs/port/trinity/src/tri/gen_cross_entropy.t27", "t27b": "blocked", "blocker": "ExprCall(@log)", "reason": "unimplemented"}, + {"path": "specs/port/trinity/src/tri/gen_cross_entropy.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_cursor.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_epoch_reclamation.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_escape.t27", "t27b": "pass"}, - {"path": "specs/port/trinity/src/tri/gen_fuzz.t27", "t27b": "blocked", "blocker": "ExprCall(@intCast)", "reason": "unimplemented"}, + {"path": "specs/port/trinity/src/tri/gen_fuzz.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_geo_hash2d.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_gradient.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_gradient_descent.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_hazard_pointers.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_image.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_index.t27", "t27b": "pass_vacuous"}, + {"path": "specs/port/trinity/src/tri/gen_key_value.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_kmeans.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_leb128.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_linear_regression.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_lockfree_stack.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_matrix3x3.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_mock.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_neuron.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_path_utils.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_perceptron.t27", "t27b": "blocked", "blocker": "StmtAssign", "reason": "reference-bug"}, {"path": "specs/port/trinity/src/tri/gen_quaternion.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_radix_tree.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_ray.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_record_store.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_rect.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_regression.t27", "t27b": "blocked", "blocker": "type std.mem.Allocator", "reason": "unimplemented"}, {"path": "specs/port/trinity/src/tri/gen_relu.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_ring_buffer.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_rle.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_rsa_simple.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_rtree.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_rwlock.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_semaphore.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_sigmoid.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_snapshot.t27", "t27b": "pass"}, - {"path": "specs/port/trinity/src/tri/gen_softmax.t27", "t27b": "blocked", "blocker": "ExprCall(@exp)", "reason": "unimplemented"}, + {"path": "specs/port/trinity/src/tri/gen_softmax.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_temp_file.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/tri/gen_test_runner.t27", "t27b": "pass"}, - {"path": "specs/port/trinity/src/tri/gen_work_stealing.t27", "t27b": "blocked", "blocker": "ExprReturn", "reason": "unimplemented"}, - {"path": "specs/port/trinity/src/tri/string_dualities.t27", "t27b": "blocked", "blocker": "ExprFieldAccess", "reason": "unimplemented"}, + {"path": "specs/port/trinity/src/tri/gen_transaction.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_transform.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_varint.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_wal.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/gen_websocket.t27", "t27b": "blocked", "blocker": "type ?void", "reason": "unimplemented"}, + {"path": "specs/port/trinity/src/tri/gen_work_stealing.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/tri/string_dualities.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/vibeec/gen_cmd_minimal.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/vibeec/gen_cmd_simple.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/vibeec/p2p_module.t27", "t27b": "pass"}, + {"path": "specs/port/trinity/src/vibeec/tnc.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/vibeec/validation_engine.t27", "t27b": "pass"}, {"path": "specs/port/trinity/src/wasm_stubs/auto_shard_stub.t27", "t27b": "pass"}, + {"path": "specs/port/trios/apps/trios-macos/rings/RUST-04/clade-improve/src/oversight.t27", "t27b": "pass"}, {"path": "specs/port/trios/apps/trios-macos/rings/RUST-13/clade-meshd/src/transport.t27", "t27b": "pass"}, + {"path": "specs/port/trios/apps/trios-macos/rings/RUST-13/trios-mesh/build.t27", "t27b": "pass"}, {"path": "specs/port/trios/apps/trios-macos/rings/RUST-13/trios-mesh/src/bin/smoke_m1.t27", "t27b": "pass"}, {"path": "specs/port/trios/apps/trios-macos/rings/RUST-13/trios-mesh/tools/ad9361_config.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/tri-tunnel/src/main.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trinity_loss/src/lib.t27", "t27b": "blocked", "blocker": "ExprLiteral(literal)", "reason": "unimplemented"}, {"path": "specs/port/trios/crates/trios-bridge/src/main.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-01/src/key_package_expiry_guard.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-02/src/epoch_rollover_wraparound_guard.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_decoy_ratio_governor.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-LAWS/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/agent.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/commit.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-cli/src/cmd/gates.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/leaderboard.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-cli/src/cmd/report.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/roster.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-cli/src/cmd/run.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/status.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/submit.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-cli/src/gh.t27", "t27b": "pass_vacuous"}, + {"path": "specs/port/trios/crates/trios-cli/src/lock.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/metrics.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-doctor/rings/BRONZE-RING-DR/src/main.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-doctor/rings/SILVER-RING-DR-00/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-doctor/src/main.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-ext/rings/SILVER-RING-EXT-00/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-ext/xtask/src/main.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-git/src/commit.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-git/src/log.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-git/src/stash.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-git/src/status.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-golden-float/build.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-hdc/build.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-hdc/rings/HD-01/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-igla-race/src/main.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-igla-trainer/src/jepa_runner.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-mcp/rings/BR-XTASK/src/main.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-mcp/rings/SR-01/src/lighthouse.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-mcp/rings/SR-02/src/discovery.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-mcp/rings/SR-02/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-mcp/src/main.t27", "t27b": "pass"}, - {"path": "specs/port/trios/crates/trios-mesh/src/packet.t27", "t27b": "blocked", "blocker": "type [*]T", "reason": "unimplemented"}, + {"path": "specs/port/trios/crates/trios-mesh/src/identity.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-mesh/src/packet.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-openclaw/rings/OC-01/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-physics/build.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-physics/rings/PH-01/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-physics/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-rainbow-bridge/src/funnel_client.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-rainbow-bridge/src/lamport.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-sacred/rings/SC-00/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-sacred/rings/SC-01/src/lib.t27", "t27b": "pass_vacuous"}, + {"path": "specs/port/trios/crates/trios-scarab-types/rings/SR-00/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-scarab-types/rings/SR-01/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-scarab-types/rings/SR-02/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-scarab-types/rings/SR-03/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-scarab-types/rings/SR-04/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-server/src/mcp_endpoints/tasks.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-server/src/tools/git.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-server/src/tools/git_extended.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-server/src/tools/gitbutler.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-server/src/tools/golden_float.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-server/src/tools/mod.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-store/rings/ST-00/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-ternary/rings/TR-01/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-train-cpu/src/bin/tjepa_modules/encoder.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-train-cpu/src/bin/train_state.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-trainer/src/train_loop.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-trainer/src/validation.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-trinity-brain/src/phi.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-vsa/rings/VS-01/src/lib.t27", "t27b": "pass"}, + {"path": "specs/port/trios/validate_bpb.t27", "t27b": "pass"}, {"path": "specs/providers/catalog.t27", "t27b": "pass"}, {"path": "specs/providers/gonka/deepseek-v4-flash-0731.t27", "t27b": "pass"}, {"path": "specs/providers/gonka/glm-5-2-fp8.t27", "t27b": "pass"}, @@ -516,52 +831,72 @@ {"path": "specs/providers/tri_gnk_pair.t27", "t27b": "pass"}, {"path": "specs/providers/trinet/fpga-xc7a200t.t27", "t27b": "pass"}, {"path": "specs/providers/trinet/gpu-consumer-24gb.t27", "t27b": "pass"}, + {"path": "specs/queen/actors.t27", "t27b": "pass"}, + {"path": "specs/queen/actors_hw.t27", "t27b": "pass"}, + {"path": "specs/queen/app.t27", "t27b": "pass"}, + {"path": "specs/queen/control.t27", "t27b": "pass"}, + {"path": "specs/queen/dashboard.t27", "t27b": "pass"}, {"path": "specs/queen/dispatch.t27", "t27b": "pass"}, + {"path": "specs/queen/dispatch_exit.t27", "t27b": "pass"}, + {"path": "specs/queen/domains.t27", "t27b": "pass"}, + {"path": "specs/queen/events.t27", "t27b": "pass"}, + {"path": "specs/queen/hive.t27", "t27b": "pass"}, + {"path": "specs/queen/holds.t27", "t27b": "pass"}, + {"path": "specs/queen/jobs.t27", "t27b": "pass"}, + {"path": "specs/queen/keyed.t27", "t27b": "pass"}, + {"path": "specs/queen/merger_gate.t27", "t27b": "pass"}, + {"path": "specs/queen/netlink.t27", "t27b": "pass"}, {"path": "specs/queen/priority.t27", "t27b": "pass"}, + {"path": "specs/queen/replay/actors_decisions.t27", "t27b": "pass"}, + {"path": "specs/queen/replay/reviewer_decisions.t27", "t27b": "pass"}, + {"path": "specs/queen/replay/telemetry_decisions.t27", "t27b": "pass"}, + {"path": "specs/queen/review_log.t27", "t27b": "pass"}, {"path": "specs/queen/review_valve.t27", "t27b": "pass"}, + {"path": "specs/queen/reviewer.t27", "t27b": "pass"}, + {"path": "specs/queen/reviewer_sizing.t27", "t27b": "pass"}, + {"path": "specs/queen/shaping.t27", "t27b": "pass"}, + {"path": "specs/queen/simulation.t27", "t27b": "pass"}, {"path": "specs/queen/task_analysis.t27", "t27b": "pass"}, + {"path": "specs/queen/tasks.t27", "t27b": "pass"}, + {"path": "specs/queen/telemetry.t27", "t27b": "pass"}, + {"path": "specs/queen/turn_stop.t27", "t27b": "pass"}, {"path": "specs/queen/views.t27", "t27b": "pass"}, + {"path": "specs/queen/waits.t27", "t27b": "pass"}, {"path": "specs/rings/ring_103_phi_sgd.t27", "t27b": "pass"}, - {"path": "specs/sacred/cosmology.t27", "t27b": "pass_vacuous"}, - {"path": "specs/sacred/dark_matter.t27", "t27b": "pass_vacuous"}, - {"path": "specs/sacred/gravity.t27", "t27b": "pass_vacuous"}, - {"path": "specs/sacred/monopoles.t27", "t27b": "pass_vacuous"}, - {"path": "specs/sacred/quantum.t27", "t27b": "pass_vacuous"}, - {"path": "specs/sacred/quantum_gravity.t27", "t27b": "pass_vacuous"}, - {"path": "specs/sacred/superconductivity.t27", "t27b": "pass_vacuous"}, {"path": "specs/sandbox/health.t27", "t27b": "pass"}, {"path": "specs/sandbox/https_enforce.t27", "t27b": "pass"}, {"path": "specs/sandbox/modules.t27", "t27b": "pass_vacuous"}, {"path": "specs/sandbox/orphan_detection.t27", "t27b": "pass"}, - {"path": "specs/skills/t27-measure-corpus.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/t27-phi-loop.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/t27-providers-steward.t27", "t27b": "pass_vacuous"}, + {"path": "specs/sandbox/session_timeout.t27", "t27b": "pass"}, + {"path": "specs/skills/t27-measure-corpus.t27", "t27b": "pass"}, + {"path": "specs/skills/t27-phi-loop.t27", "t27b": "pass"}, + {"path": "specs/skills/t27-providers-steward.t27", "t27b": "pass"}, {"path": "specs/skills/t27-self-host.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/t27-tri-pipeline.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/t27-tri.t27", "t27b": "pass_vacuous"}, + {"path": "specs/skills/t27-tri-pipeline.t27", "t27b": "pass"}, + {"path": "specs/skills/t27-tri.t27", "t27b": "pass"}, {"path": "specs/skills/t27-wave-audit.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/t27-wrap-up.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-blog-post.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-board-sync.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-cloud.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-connect-accounts.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-doctor.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-farm-garden.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-fpga-synth.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-god-mode.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-implement-issue.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-queen-hive-visuals.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-review-code.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-run-tests.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-scholar.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-status.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-tech-tree.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-tri.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-trinity-test.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-ux-wave.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-vibee-gen.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-vsa-verify.t27", "t27b": "pass_vacuous"}, - {"path": "specs/skills/trinity-wave.t27", "t27b": "pass_vacuous"}, + {"path": "specs/skills/t27-wrap-up.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-blog-post.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-board-sync.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-cloud.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-connect-accounts.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-doctor.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-farm-garden.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-fpga-synth.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-god-mode.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-implement-issue.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-queen-hive-visuals.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-review-code.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-run-tests.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-scholar.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-status.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-tech-tree.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-tri.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-trinity-test.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-ux-wave.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-vibee-gen.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-vsa-verify.t27", "t27b": "pass"}, + {"path": "specs/skills/trinity-wave.t27", "t27b": "pass"}, {"path": "specs/system/unified-agent-operations.t27", "t27b": "pass_vacuous"}, {"path": "specs/ternary/activation_quantizer.t27", "t27b": "pass"}, {"path": "specs/ternary/bitnet_layer.t27", "t27b": "pass"}, @@ -594,6 +929,7 @@ {"path": "specs/ternary/gft_log2.t27", "t27b": "pass"}, {"path": "specs/ternary/gft_logistic.t27", "t27b": "pass"}, {"path": "specs/ternary/gft_madd.t27", "t27b": "pass"}, + {"path": "specs/ternary/gft_magsub_tie.t27", "t27b": "pass"}, {"path": "specs/ternary/gft_mlp2.t27", "t27b": "pass"}, {"path": "specs/ternary/gft_mlp3.t27", "t27b": "pass"}, {"path": "specs/ternary/gft_mul_rne.t27", "t27b": "pass"}, @@ -624,6 +960,7 @@ {"path": "specs/ternary/ternary_ripple_adder.t27", "t27b": "pass"}, {"path": "specs/ternary/ternary_xor.t27", "t27b": "pass"}, {"path": "specs/tools/catalog.t27", "t27b": "pass"}, + {"path": "specs/tools/epic_ci.t27", "t27b": "pass"}, {"path": "specs/tools/mcp/gitbutler.t27", "t27b": "pass_vacuous"}, {"path": "specs/tools/mcp/inngest-dev.t27", "t27b": "pass_vacuous"}, {"path": "specs/tools/mcp/needle.t27", "t27b": "pass_vacuous"}, @@ -631,18 +968,18 @@ {"path": "specs/tools/mcp/notebooklm.t27", "t27b": "pass_vacuous"}, {"path": "specs/tools/mcp/railway-mcp-server.t27", "t27b": "pass_vacuous"}, {"path": "specs/tools/mcp/t27-traceability.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/mcp/tri-mcp.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/mcp/tri-ssot.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/mcp/trinity.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/mcp/zig-docs.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tools/mcp/tri-mcp.t27", "t27b": "pass"}, + {"path": "specs/tools/mcp/tri-ssot.t27", "t27b": "pass"}, + {"path": "specs/tools/mcp/trinity.t27", "t27b": "pass"}, + {"path": "specs/tools/mcp/zig-docs.t27", "t27b": "pass"}, {"path": "specs/tools/mcp_protocol.t27", "t27b": "pass"}, - {"path": "specs/tools/tri/abandoned.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/cell.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/census.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/ci.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/competitors.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/discard.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/doctor.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tools/tri/abandoned.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/cell.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/census.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/ci.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/competitors.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/discard.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/doctor.t27", "t27b": "pass"}, {"path": "specs/tools/tri/elab.t27", "t27b": "pass"}, {"path": "specs/tools/tri/emit.t27", "t27b": "pass"}, {"path": "specs/tools/tri/experience.t27", "t27b": "pass"}, @@ -650,44 +987,44 @@ {"path": "specs/tools/tri/fmt.t27", "t27b": "pass"}, {"path": "specs/tools/tri/fpga.t27", "t27b": "pass"}, {"path": "specs/tools/tri/gates.t27", "t27b": "pass"}, - {"path": "specs/tools/tri/gen.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/harness.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/health.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/hooks.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/issues.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/jumps.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/kinds.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/lean.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/ledgers.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/loop.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/merging.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/misread.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/mods.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/mutate.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/now.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/one-away.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/orphaned.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/pr.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/prose.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/quantifiers.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/red.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/reseal.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/rtl.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/seals.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/serve.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/skill.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/status.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/sweep.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/synth.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/test.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/topic.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/types.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/unparsed.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/vectors.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/verdict.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/vsim.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/window.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/tri/worktrees.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tools/tri/gen.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/harness.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/health.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/hooks.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/issues.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/jumps.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/kinds.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/lean.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/ledgers.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/loop.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/merging.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/misread.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/mods.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/mutate.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/now.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/one-away.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/orphaned.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/pr.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/prose.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/quantifiers.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/red.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/reseal.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/rtl.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/seals.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/serve.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/skill.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/status.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/sweep.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/synth.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/test.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/topic.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/types.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/unparsed.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/vectors.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/verdict.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/vsim.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/window.t27", "t27b": "pass"}, + {"path": "specs/tools/tri/worktrees.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/bench.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/bio.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/blindspots.t27", "t27b": "pass"}, @@ -695,13 +1032,13 @@ {"path": "specs/tools/trinity/tri/constants.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/cosmos.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/dashboard.t27", "t27b": "pass"}, - {"path": "specs/tools/trinity/tri/fib.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/trinity/tri/fpga.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/trinity/tri/gematria.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/trinity/tri/govern.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/trinity/tri/hardware.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/trinity/tri/identity.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tools/trinity/tri/lucas.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tools/trinity/tri/fib.t27", "t27b": "pass"}, + {"path": "specs/tools/trinity/tri/fpga.t27", "t27b": "pass"}, + {"path": "specs/tools/trinity/tri/gematria.t27", "t27b": "pass"}, + {"path": "specs/tools/trinity/tri/govern.t27", "t27b": "pass"}, + {"path": "specs/tools/trinity/tri/hardware.t27", "t27b": "pass"}, + {"path": "specs/tools/trinity/tri/identity.t27", "t27b": "pass"}, + {"path": "specs/tools/trinity/tri/lucas.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/mesh.t27", "t27b": "pass_vacuous"}, {"path": "specs/tools/trinity/tri/needle-check.t27", "t27b": "pass_vacuous"}, {"path": "specs/tools/trinity/tri/needle-search.t27", "t27b": "pass_vacuous"}, @@ -716,67 +1053,154 @@ {"path": "specs/tools/trinity/tri/swarm.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/test.t27", "t27b": "pass"}, {"path": "specs/tools/trinity/tri/vsa.t27", "t27b": "pass"}, - {"path": "specs/tools/trinity/tri/wallet.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tools/trinity/tri/wallet.t27", "t27b": "pass"}, {"path": "specs/traffic_animator.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/agent/agent_run.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/agent/agents.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/agent/autonomous_universe.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/agent/experience_hooks.t27", "t27b": "pass_vacuous"}, {"path": "specs/tri/agent/faculty_board.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/agent/memory.t27", "t27b": "pass_vacuous"}, {"path": "specs/tri/catalog/health.t27", "t27b": "pass"}, - {"path": "specs/tri/collections/context.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tri/collections/namespace.t27", "t27b": "pass"}, + {"path": "specs/tri/crypto/ed25519.t27", "t27b": "pass"}, {"path": "specs/tri/crypto/hex.t27", "t27b": "pass"}, + {"path": "specs/tri/crypto/sha256.t27", "t27b": "pass"}, + {"path": "specs/tri/crypto/sha512.t27", "t27b": "pass"}, + {"path": "specs/tri/graph/bellman_ford.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tri/graph/graph.t27", "t27b": "pass"}, + {"path": "specs/tri/graph/topological_sort.t27", "t27b": "pass"}, {"path": "specs/tri/math/math.t27", "t27b": "pass_vacuous"}, {"path": "specs/tri/math/measurement.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/net/cloud.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/pipeline/cloud_orchestrator.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/pipeline/pipeline.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/pipeline/spec_parser.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tri/mutate/census.t27", "t27b": "pass"}, + {"path": "specs/tri/mutate/lab.t27", "t27b": "pass"}, + {"path": "specs/tri/mutate/plant.t27", "t27b": "pass"}, + {"path": "specs/tri/mutate/survivors.t27", "t27b": "pass"}, + {"path": "specs/tri/pipeline/codegen.t27", "t27b": "pass"}, {"path": "specs/tri/pipeline/spec_writer.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/pipeline/workflow_executor.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/pipeline/workflow_parser.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tri/pipeline/workflow.t27", "t27b": "pass"}, + {"path": "specs/tri/search/pattern.t27", "t27b": "pass"}, {"path": "specs/tri/sort/insertion_sort.t27", "t27b": "pass"}, + {"path": "specs/tri/sort/merge_sort.t27", "t27b": "pass"}, {"path": "specs/tri/sort/selection_sort.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/a64.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/any_param_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/arith_op.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/ast_scan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/ast_walk.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/bit_cast_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/blockers.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/builtin_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/check_budget.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/cmp_op.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/coerce_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/comptime_float.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/anonymous_struct.t27", "t27b": "pass"}, - {"path": "specs/tri/t27b/conformance/array_len_expr.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/array_literal.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/array_literal_value.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/array_repeat_text.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/bare_abs.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/big_repeat_global.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/bit_cast.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/brace_invariant.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/builtin_abs_max_min_pi.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/cmp_out_of_range.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/comptime_float.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/comptime_float_f128.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/const_division.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/const_optional.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/discard_value.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/div_trunc_panic.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/empty_anon_literal.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/eval_branch_quota.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/float_as.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/float_call_cast.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/float_from_int_literal.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/float_mul_pow2.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/float_sqrt.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/frame_address_caller_owned.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/frame_address_return.t27", "t27b": "blocked", "blocker": "ExprReturn(frame address)", "reason": "reference-bug"}, + {"path": "specs/tri/t27b/conformance/frame_address_store.t27", "t27b": "blocked", "blocker": "StmtAssign(frame address)", "reason": "reference-bug"}, + {"path": "specs/tri/t27b/conformance/int_cast.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/int_cast_index.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/large_frame.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/lazy_signature.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/libm_logf.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/libm_powf.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/libm_rounding.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/libm_std_math.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/module_var_in_test.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/negative_float_literal.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/numeric_coercion.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/odd_width_int.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/opaque_pointer.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/optional_enum_compare.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/optional_module_var.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/param_discard.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/pointer_equality.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/postfix_optional.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/repeat_addr_unreached.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/repeat_local.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/return_undefined_void.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/scaffold_local.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/scope_exit.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/scoped_gf16.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/shadow_module_var.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/static_slice_literal.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/std_mem_byte_slice.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/str_module_var.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/string_slice_literal.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/struct_lit_if.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/test_local_write.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/tuple_local.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/tuple_local_index.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/type_alias.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/type_void.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/undefined_arg.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/undefined_module_var.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/unread_anytype.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/unresolved_signature.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/untyped_local.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/untyped_local_uses.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/value_ignored.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/value_params.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/void_bind.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/conformance/wide_int_const.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/conformance/zig_keyword_field.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/const_div_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/discard_plan.t27", "t27b": "pass"}, {"path": "specs/tri/t27b/dogfood.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/empty_lit_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/eval_arith.t27", "t27b": "blocked", "blocker": "type i128", "reason": "unimplemented"}, + {"path": "specs/tri/t27b/float_as_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/frame_store_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/fuzz.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/fuzz_oracle.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/int_cast_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/lazy_sig_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/lencall.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/libm.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/libm_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/literal_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/macho.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/opaque_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/optional_compare_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/ptr_eq_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/reduce.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/scaffold_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/slice_lit_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/source_text.t27", "t27b": "blocked", "blocker": "type i128", "reason": "unimplemented"}, {"path": "specs/tri/t27b/steward.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/tuple_local_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/type_text.t27", "t27b": "blocked", "blocker": "ExprCall(@intCast)", "reason": "unimplemented"}, + {"path": "specs/tri/t27b/undefined_arg_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/verdict_key.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/void_bind_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/t27b/wide_plan.t27", "t27b": "pass"}, + {"path": "specs/tri/test/report.t27", "t27b": "pass"}, {"path": "specs/tri/utils/args.t27", "t27b": "pass"}, - {"path": "specs/tri/utils/arrow_time.t27", "t27b": "pass_vacuous"}, - {"path": "specs/tri/utils/colors.t27", "t27b": "pass_vacuous"}, {"path": "specs/tri/utils/error.t27", "t27b": "pass_vacuous"}, {"path": "specs/tri/utils/exit_codes.t27", "t27b": "pass"}, {"path": "specs/tri/utils/string.t27", "t27b": "pass_vacuous"}, + {"path": "specs/tri/utils/template.t27", "t27b": "pass"}, {"path": "specs/trinet/etx.t27", "t27b": "pass"}, + {"path": "specs/trinet/node-work-credit.t27", "t27b": "pass"}, + {"path": "specs/trinet/tri-bridge.t27", "t27b": "pass"}, {"path": "specs/trinity/build_graph.t27", "t27b": "pass"}, {"path": "specs/trinity/capabilities/abi.c-api.t27", "t27b": "pass"}, {"path": "specs/trinity/capabilities/agent.daemons.t27", "t27b": "pass"}, @@ -833,9 +1257,39 @@ {"path": "specs/trinity/compiler_matrix.t27", "t27b": "pass_vacuous"}, {"path": "specs/trinity/project.t27", "t27b": "pass"}, {"path": "specs/ui/queen_evidence.t27", "t27b": "pass"}, + {"path": "specs/verified/bench_agent.t27", "t27b": "pass"}, + {"path": "specs/verified/bitstream_reuse.t27", "t27b": "pass"}, + {"path": "specs/verified/corpus_merkle.t27", "t27b": "pass"}, + {"path": "specs/verified/corpus_receipt.t27", "t27b": "pass"}, + {"path": "specs/verified/ddc_receipt.t27", "t27b": "pass"}, + {"path": "specs/verified/device_dna.t27", "t27b": "pass"}, + {"path": "specs/verified/device_evidence.t27", "t27b": "pass"}, + {"path": "specs/verified/die_binding.t27", "t27b": "pass"}, + {"path": "specs/verified/evidence_chain.t27", "t27b": "pass"}, + {"path": "specs/verified/failure_loop.t27", "t27b": "pass"}, + {"path": "specs/verified/frontier.t27", "t27b": "pass"}, + {"path": "specs/verified/independence.t27", "t27b": "pass"}, + {"path": "specs/verified/payout.t27", "t27b": "pass"}, + {"path": "specs/verified/poc/a/slot.t27", "t27b": "pass"}, + {"path": "specs/verified/poc/b/slot.t27", "t27b": "pass"}, + {"path": "specs/verified/poc/run.t27", "t27b": "pass"}, + {"path": "specs/verified/poc/static_counter.t27", "t27b": "pass"}, + {"path": "specs/verified/receipt.t27", "t27b": "pass"}, + {"path": "specs/verified/region.t27", "t27b": "pass"}, + {"path": "specs/verified/reuse.t27", "t27b": "pass"}, + {"path": "specs/verified/review_gate.t27", "t27b": "pass"}, + {"path": "specs/verified/run_record.t27", "t27b": "pass"}, + {"path": "specs/verified/seal_check.t27", "t27b": "pass"}, + {"path": "specs/verified/seal_identity.t27", "t27b": "pass"}, + {"path": "specs/verified/signed_receipt.t27", "t27b": "pass"}, + {"path": "specs/verified/silicon_queue.t27", "t27b": "pass"}, + {"path": "specs/verified/silicon_runs.t27", "t27b": "pass"}, + {"path": "specs/verified/ternary_link_run.t27", "t27b": "pass"}, + {"path": "specs/verified/verdict.t27", "t27b": "pass"}, {"path": "specs/vm/trinity_vm.t27", "t27b": "pass"}, - {"path": "specs/vsa/similarity_search.t27", "t27b": "blocked", "blocker": "VarDecl(module, undefined)", "reason": "unimplemented"}, + {"path": "specs/vsa/similarity_search.t27", "t27b": "pass"}, {"path": "specs/vsa/trinity_compat.t27", "t27b": "pass"}, + {"path": "specs/xilinx7/bench_coverage.t27", "t27b": "pass"}, {"path": "specs/xilinx7/far.t27", "t27b": "pass"}, {"path": "specs/xilinx7/flow.t27", "t27b": "pass"}, {"path": "specs/xilinx7/frames.t27", "t27b": "pass"}, diff --git a/tools/policy/foreign-exceptions.txt b/tools/policy/foreign-exceptions.txt index 453a4f752e..ddb175476e 100644 --- a/tools/policy/foreign-exceptions.txt +++ b/tools/policy/foreign-exceptions.txt @@ -3,8 +3,10 @@ # One path prefix per line; a path under an entry may be added or modified by hand. '#' starts a comment. # The rule that reads this file is specs/policy/own_language.t27. # -# - Locally (lefthook) the working-tree copy is read, so an agent on an owner-approved branch adds its -# entry in the same branch and can commit. +# - Locally (lefthook) the copy on origin/master is read, never the working tree (#7371): a branch cannot +# list itself; an entry takes effect for local commits once the owner merged it. +# - No entry lifts the foreign-line budget (check_budget, owner rule 2026-10-07, #7371): at most 40 added +# hand-written foreign lines per file and 80 per pull request, entry or label or not. # - In CI the copy on the pull request's BASE is read, and any change to this file fails unless the owner # put the label `owner-approved-foreign` on the pull request. So every entry here was owner-approved. # @@ -12,6 +14,37 @@ # cli/t27b/src/lower.rs # with a comment line above it: "# owner 2026-10-05, PR #NNNN: ". +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7367 +# (epic #6063 lane 5): t27b allocates a frame over 16 KiB one 4 KiB page at a time and stores to each page +# (AArch64 stack probing), so the aggregate cap per frame rises from 16 KiB to 1 MiB. The conformance spec is +# specs/tri/t27b/conformance/large_frame.t27; cli/t27b/tests/source.rs is already listed below. +cli/t27b/src/codegen.rs + +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7448 +# (epic #6063 lane 5): t27b fills a module var declared `undefined` with 0xAA bytes (Zig Debug on x86_64; +# not portable, so no fixture reads one before a write), and writes a module var that holds a string at the start of every test, invariant and bench. +# Conformance specs: specs/tri/t27b/conformance/str_module_var.t27 and undefined_module_var.t27. +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7668 +# (the rest of #7422; epic #6063, lane 5): t27b lowers a top-level local that takes a module var's name +# where the reference's `_lv` rename agrees with t27 scoping. +# The fixture is specs/tri/t27b/conformance/shadow_module_var.t27. +cli/t27b/src/lower.rs +cli/t27b/tests/source.rs +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), epic #6063, +# issue #7368: t27b coverage lane 3 -- integer types of every width 1..31 (`type u1`, i2, u4, u21) are held +# like a u8 and checked against their own range. Conformance spec first: +# specs/tri/t27b/conformance/odd_width_int.t27. lower.rs is listed below. +cli/t27b/src/ir.rs +cli/t27b/src/codegen.rs +cli/t27b/src/eval.rs +cli/t27b/tests/differential.rs + +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7376 +# (epic #5980): t27b fills a constant array repeat once and copies its bytes, so a module var is no longer +# capped at 65536 elements and the self-hosted core's buffers can grow. The conformance spec is +# specs/tri/t27b/conformance/big_repeat_global.t27. +cli/t27b/src/lower.rs + # owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7332 # (epic #6655, R3-1 tool half): `t27c silicon --nonce` signs every receipt with Ed25519, `t27c receipt-key` # makes the host key outside the tree, `t27c run-record --challenge --require-level` reports each receipt's @@ -64,6 +97,10 @@ bootstrap/src/main.rs # FROZEN_HASH moves with compiler.rs. bootstrap/tests/t27a_cli.rs bootstrap/stage0/FROZEN_HASH +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), gen-c +# defects lane of epic #5980 (self-host P1): one regression test per gen-c defect. compiler.rs and FROZEN_HASH +# are listed above. #7318: array dimensions and negated literal consts keep no `_` separator. +bootstrap/tests/genc_digit_separators.rs # owner-approved 2026-10-05, #6457: via the coordinator ("fix it and do not stop, do what is best"), the parked # `tri t27b dogfood` command and the `tri t27b next` tie-break land as an exception. Every decision is # specs/tri/t27b/dogfood.t27 (gen-c); the Python is I/O plumbing only. Debt #6198. Removed again before merge. @@ -204,6 +241,12 @@ cli/t27b/tests/differential.rs fpga/verilog/poc_slot_a_jtag.v fpga/verilog/poc_slot_b_jtag.v +# owner 2026-10-08, chat (approving "a thin Verilog wrapper of Xilinx primitives, <=40 lines, and an XDC, +# <=40 lines" for the board's Ethernet firmware, translated), issue #7788: the AX7203 Ethernet beacon. +# Every decision is specs/fpga/eth_beacon.t27; the wrapper holds IBUFDS, PLLE2_ADV, BUFG and ODDR only. +fpga/verilog/eth_beacon_top.v +fpga/verilog/eth_beacon_top.xdc + # owner 2026-10-06, epic #6971 / issue #6993 (label owner-approved-foreign on #6993; standing approval "add # the label yourself and do the foreign part, never ask about labels", translated): `tri mutate spec` -- # guard and operator mutants of a .t27 spec, judged by `t27c gen` + `zig test`. An edit to existing Rust @@ -382,3 +425,50 @@ tools/queen/criteria_backfill.py # (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. cli/t27b/src/lower.rs cli/t27b/tests/source.rs +======= +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7415: +# t27b reads the postfix optional `T?` as t27c's type mapper writes it, `?T` (the parser keeps the suffix only +# on a struct field's type). The behaviour is pinned by specs/tri/t27b/conformance/postfix_optional.t27. +cli/t27b/src/lower.rs +cli/t27b/tests/source.rs + +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7526 +# (port epic #6198): cli/t27b/src/macho.rs shrinks to glue around gen/rust/tri/t27b/macho.rs, the t27c gen-rust +# output of specs/tri/t27b/macho.t27 (Mach-O layout and bytes). The glue adds 21 lines and deletes 153. +cli/t27b/src/macho.rs + +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7402: +# t27b coverage lane 1 -- `return undefined;` in a void fn is a plain return. Conformance spec first: +# specs/tri/t27b/conformance/return_undefined_void.t27. +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7410: +# t27b coverage lane 1 -- `@setEvalBranchQuota(n);` is a compile-time no-op. Conformance spec first: +# specs/tri/t27b/conformance/eval_branch_quota.t27. +cli/t27b/src/lower.rs +cli/t27b/tests/source.rs + +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7524: +# which call t27b lowers as the `.len` field is decided by specs/tri/t27b/lencall.t27 (t27c gen-rust output +# gen/rust/tri/t27b/lencall.rs, mounted in lower.rs); cli/t27b/src/lower/lencall.rs is deleted and lower.rs +# keeps only the glue that builds the nodes it names. Debt #6198/#5980. +cli/t27b/src/lower.rs + +# owner approval pending (label owner-approved-foreign), issue #7927: tools/jtag/mpsse_jtag.py takes the libftdi +# path from $T27_LIBFTDI or the platform default, so stage B2 of t27c silicon reads on Linux (R3-3 die C, #7906). +# A 5-line change; no Python back end exists, so no .t27 can generate this file. +tools/jtag/mpsse_jtag.py + +# owner instruction 2026-10-09 (translated: "do this as a priority, yourself"), epic #8095 step 4, issue #8111: +# CI applies the reuse rule of specs/verified/seal_identity.t27. spec-guards.yml prints "reused N of M" +# from t27c frontier with the BASE revision's seals (a pull request cannot vouch for itself); suite.rs and +# corpus-ratchet.yml skip specs the generated node_decision marks REUSE. Every decision is generated; these +# files only call it. The foreign-line budget (40 per file, 80 per PR) applies to each change. +.github/workflows/spec-guards.yml +.github/workflows/corpus-ratchet.yml +bootstrap/src/suite.rs + +# owner standing rule ("add the label yourself and do the foreign part", translated), issue #8171, epic #8095: +# the t27b reference cache keys verdicts by specs/tri/t27b/verdict_key.t27 (gen-rust), so a t27c rebuild that +# leaves a spec's generated code unchanged reuses its verdict; ledger rows carry the key (steward.t27, gen-c). +# blockers.rs and t27b_rules.py only call the generated functions. Budget 40 per file, 80 per PR applies. +cli/t27b/src/blockers.rs +scripts/tri_loop/t27b_rules.py From 3bb120663491a1353687f198b30ac5d4a5a8bf33 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sat, 10 Oct 2026 18:29:33 +0700 Subject: [PATCH 07/10] sync: take the merged content of the four files both sides changed lower.rs with master's auto-merge, source.rs with both sides' tests, master's current ledger rows (the ratchet re-bless recounts after the merge), and both sides' foreign-exception blocks -- so update-branch merges master in without a conflict. Co-Authored-By: Claude Opus 5.5 (1M context) --- cli/t27b/src/lower.rs | 1418 ++++++++++++++++----------- docs/reports/t27b_expectations.json | 19 +- tools/policy/foreign-exceptions.txt | 2 +- 3 files changed, 862 insertions(+), 577 deletions(-) diff --git a/cli/t27b/src/lower.rs b/cli/t27b/src/lower.rs index 611d41d9d4..41d1c329db 100644 --- a/cli/t27b/src/lower.rs +++ b/cli/t27b/src/lower.rs @@ -73,6 +73,9 @@ mod arraylit; mod floatas; mod formulti; +/// Which call is the `.len` field: `specs/tri/t27b/lencall.t27`, t27c gen-rust. +#[path = "../../../gen/rust/tri/t27b/lencall.rs"] +#[allow(dead_code, unused_parens)] mod lencall; mod stdmem; mod unanalyzed; @@ -84,8 +87,58 @@ use std::collections::{HashMap, HashSet}; #[path = "lower_float.rs"] mod float; +#[path = "../../../gen/rust/tri/t27b/builtin_plan.rs"] #[allow(dead_code, unused_parens)] +mod bp; // t27c gen-rust of specs/tri/t27b/builtin_plan.t27: @abs, @max, @min, std.math.pi / e +#[path = "../../../gen/rust/tri/t27b/int_cast_plan.rs"] #[allow(dead_code, unused_parens)] +pub(crate) mod ic; // t27c gen-rust of specs/tri/t27b/int_cast_plan.t27: @intCast with an integer result type; `widens` serves ir.rs +#[path = "../../../gen/rust/tri/t27b/ptr_eq_plan.rs"] #[allow(dead_code, unused_parens)] +mod pe; // t27c gen-rust of specs/tri/t27b/ptr_eq_plan.t27: `==` / `!=` of pointers and optional pointers +#[path = "../../../gen/rust/tri/t27b/libm_plan.rs"] #[allow(dead_code, unused_parens)] +mod xp; // t27c gen-rust of specs/tri/t27b/libm_plan.t27: @exp, @log call compiler_rt's in specs/tri/t27b/libm.t27 +#[path = "../../../gen/rust/tri/t27b/wide_plan.rs"] #[allow(dead_code, unused_parens, unexpected_cfgs)] +mod wp; // t27c gen-rust of specs/tri/t27b/wide_plan.t27: integer constants wider than 64 bits, folded +#[path = "../../../gen/rust/tri/t27b/opaque_plan.rs"] #[allow(dead_code, unused_parens)] +mod oq; // t27c gen-rust of specs/tri/t27b/opaque_plan.t27: `anyopaque`, `@ptrFromInt` to an optional pointer +#[path = "../../../gen/rust/tri/t27b/slice_lit_plan.rs"] #[allow(dead_code, unused_parens)] +mod sl; // t27c gen-rust of specs/tri/t27b/slice_lit_plan.t27: array literals printed `@constCast(&[_]E{ .. })` +#[path = "../../../gen/rust/tri/t27b/tuple_local_plan.rs"] #[allow(dead_code, unused_parens)] +mod tl; // t27c gen-rust of specs/tri/t27b/tuple_local_plan.t27: tuples, and an untyped list local printed as one +#[path = "../../../gen/rust/tri/t27b/coerce_plan.rs"] #[allow(dead_code, unused_parens)] +mod cp; // t27c gen-rust of specs/tri/t27b/coerce_plan.t27: a value of one numeric type where Zig takes another +#[path = "../../../gen/rust/tri/t27b/void_bind_plan.rs"] #[allow(dead_code, unused_parens)] +mod vb; // t27c gen-rust of specs/tri/t27b/void_bind_plan.t27: a local bound to a void fn's result +#[path = "../../../gen/rust/tri/t27b/scaffold_plan.rs"] #[allow(dead_code, unused_parens)] +mod sc; // t27c gen-rust of specs/tri/t27b/scaffold_plan.t27: `x = default_input()`, which the reference never calls +#[path = "../../../gen/rust/tri/t27b/empty_lit_plan.rs"] #[allow(dead_code, unused_parens)] +mod el; // t27c gen-rust of specs/tri/t27b/empty_lit_plan.t27: `.{}` by its result type +#[path = "../../../gen/rust/tri/t27b/frame_store_plan.rs"] #[allow(dead_code, unused_parens)] +mod fsp; // t27c gen-rust of specs/tri/t27b/frame_store_plan.t27: this frame's address stored where the caller reads it +#[path = "../../../gen/rust/tri/t27b/undefined_arg_plan.rs"] #[allow(dead_code, unused_parens)] +mod ua; // t27c gen-rust of specs/tri/t27b/undefined_arg_plan.t27: `f(undefined)` for a parameter nobody reads +#[path = "../../../gen/rust/tri/t27b/optional_compare_plan.rs"] #[allow(dead_code, unused_parens)] +mod oc; // t27c gen-rust of specs/tri/t27b/optional_compare_plan.t27: `?T == v`, by value or by tag +#[path = "../../../gen/rust/tri/t27b/const_div_plan.rs"] #[allow(dead_code, unused_parens)] +mod dv; // t27c gen-rust of specs/tri/t27b/const_div_plan.t27: `/` and `%` of two integer constants, folded +#[path = "../../../gen/rust/tri/t27b/bit_cast_plan.rs"] #[allow(dead_code, unused_parens)] +mod bc; // t27c gen-rust of specs/tri/t27b/bit_cast_plan.t27: `@bitCast` of a scalar, `@intFromBool` +#[path = "../../../gen/rust/tri/t27b/literal_plan.rs"] #[allow(dead_code, unused_parens)] +mod lp; // t27c gen-rust of specs/tri/t27b/literal_plan.t27: a literal's text as the t27c parser keeps it +#[path = "../../../gen/rust/tri/t27b/discard_plan.rs"] #[allow(dead_code, unused_parens)] +mod dp; // t27c gen-rust of specs/tri/t27b/discard_plan.t27: `_ = e;`, deleted where the reference deletes it +#[path = "../../../gen/rust/tri/t27b/lazy_sig_plan.rs"] #[allow(dead_code, unused_parens)] +mod ls; // t27c gen-rust of specs/tri/t27b/lazy_sig_plan.t27: `anytype`, `[*]T` on a fn nothing analyzed reaches +#[path = "../../../gen/rust/tri/t27b/any_param_plan.rs"] #[allow(dead_code, unused_parens)] +mod ap; // t27c gen-rust of specs/tri/t27b/any_param_plan.t27: an `anytype` parameter the body never names +#[path = "../../../gen/rust/tri/t27b/type_text.rs"] #[allow(dead_code, unused_parens)] +mod tt; // t27c gen-rust of specs/tri/t27b/type_text.t27: a type's text, read without the file's declarations +#[path = "../../../gen/rust/tri/t27b/source_text.rs"] #[allow(dead_code, unused_parens)] +mod st; // t27c gen-rust of specs/tri/t27b/source_text.t27: literal text, header lines, prose labels mod refvars; mod tuple; +#[path = "../../../gen/rust/tri/t27b/ast_walk.rs"] #[allow(dead_code, unused_parens)] +mod aw; // t27c gen-rust of specs/tri/t27b/ast_walk.t27: walks of a list of nodes, read from `flat`'s bytes +#[path = "../../../gen/rust/tri/t27b/ast_scan.rs"] #[allow(dead_code, unused_parens, unused_variables)] +mod ax; // t27c gen-rust of specs/tri/t27b/ast_scan.t27: the nodes a scan of a list collects, as marks /// A construct outside the supported subset (or a type error inside it). #[derive(Clone, Debug)] @@ -270,8 +323,23 @@ struct Lower<'a> { leaky: HashMap, /// Each module-level `var` that lowered: its writable place. mod_vars: HashMap, + /// Module `var` names a top-level local of this body may take (`shadow_names`). + shadow_ok: HashSet, /// Initial bytes of each module-level `var` (`Program::globals`). globals_init: Vec>, + /// The global of each array type and value a `slice_lit` interned. + statics: HashMap<(String, Vec), u32>, + /// Fn declarations by name; this body's W585 locals (`sc`): consumer's type, read elsewhere, read by a callee. + fns: HashMap, + scaffold: HashMap, + /// Module memory whose initial value holds a string's address, which has no image before the + /// program is loaded: every test, invariant and bench starts by writing it (`block_body`). + str_globals: Vec<(Place, Val)>, + /// Set while `lvalue` builds a place to store to or take the address + /// of: a slice element it reaches is a write (`slice_write`, #7765). + writing: bool, + /// The write check's log: (STATIC or WRITE, element type, line). + lit_log: Vec<(u8, String, u32)>, /// Lowering what t27c's Zig backend evaluates at compile time (an /// `invariant`, which it emits as a `comptime` block, or a module-level /// initializer): a module-level `var` is not visible there. @@ -315,6 +383,8 @@ struct Lower<'a> { /// with that type. t27c's Zig backend writes the local as an anonymous /// `.{ ... }` (any `[N]T` prefix dropped), which coerces at each call. tuple_locals: HashMap, + /// Untyped list locals `tuple_array_local` took: a Zig tuple each (#8050). + tuple_names: HashSet, /// Untyped `const` locals bound to an array literal of plain literals /// and never mentioned again: the reference's `.{ ... }` plus /// `_ = x; // dead after const-inlining`, which does nothing at all. @@ -392,6 +462,9 @@ struct Lower<'a> { /// `*` expressions (by address) that t27c's strength reduction may rewrite /// as `<<` (`strength_reduced`); a float `x * 2^k` among them is refused. shifted_muls: HashSet, + /// The statement being lowered is the last of its block (`stmts`): a `@panic` must be (builtin_plan.t27). + last_stmt: bool, + lit_consts: HashSet, // this fn's locals t27c's optimizer replaces by their literal (bit_cast_plan.t27) } /// Lower a parsed module. All rejected constructs are returned (at most one per @@ -446,7 +519,13 @@ fn lower_mode<'a>( var_nodes: Vec::new(), leaky: HashMap::new(), mod_vars: HashMap::new(), + shadow_ok: HashSet::new(), globals_init: Vec::new(), + statics: HashMap::new(), + fns: HashMap::new(), scaffold: HashMap::new(), + str_globals: Vec::new(), + writing: false, + lit_log: Vec::new(), comptime: false, struct_nodes: HashMap::new(), structs: Vec::new(), @@ -468,6 +547,7 @@ fn lower_mode<'a>( ref_vars: HashSet::new(), slice_locals: HashMap::new(), tuple_locals: HashMap::new(), + tuple_names: HashSet::new(), dead_lits: HashSet::new(), discards: HashMap::new(), sret: None, @@ -497,17 +577,28 @@ fn lower_mode<'a>( tail_returns: HashSet::new(), misprinted_if: HashSet::new(), shifted_muls: HashSet::new(), + last_stmt: false, + lit_consts: HashSet::new(), }; let module = if ast.kind == NodeKind::Module { ast.name.clone() } else { String::new() }; - let items: Vec<&Node> = if ast.kind == NodeKind::Module { + let mut items: Vec<&Node> = if ast.kind == NodeKind::Module { ast.children.iter().collect() } else { vec![ast] }; + // A builtin of libm_plan.t27 calls its routine in libm.t27, spliced in under t27b's reserved prefix. + static LIBM: std::sync::OnceLock = std::sync::OnceLock::new(); + let mut named = HashSet::new(); + names_in(std::slice::from_ref(ast), &mut named); + if xp::BUILTINS.split(' ').any(|b| named.contains(b)) { + let libm = || include_str!("../../../specs/tri/t27b/libm.t27").replace(xp::PORT, xp::HELPER); + let m = LIBM.get_or_init(|| crate::compiler::Compiler::parse_ast(&libm()).unwrap_or_default()); + items.extend(m.children.iter().filter(|c| c.name.starts_with(xp::HELPER))); + } // Struct declarations are laid out on first use, like Zig's lazy // analysis: an unused struct with an unsupported member rejects nothing. @@ -518,6 +609,7 @@ fn lower_mode<'a>( if item.kind == NodeKind::EnumDecl && !item.name.is_empty() { l.enum_nodes.insert(item.name.clone(), item); } + if item.kind == NodeKind::FnDecl { l.fns.entry(item.name.clone()).or_insert(item); } // Constants too, before any signature: a top-level Zig declaration // is visible above its own line, and a length like `[N]T` in a // signature may name a constant `use` spliced in after it. @@ -527,12 +619,13 @@ fn lower_mode<'a>( } l.analyzed = analyzed_fns(&items); + l.analyzed.extend(items.iter().filter(|c| c.name.starts_with(xp::HELPER)).map(|c| c.name.clone())); l.float_field_names(&items); for item in &items { if item.kind == NodeKind::FnDecl && !item.name.is_empty() && item.extra_return_type.trim() == "bool" { l.bool_fns.insert(item.name.clone()); } - if item.kind == NodeKind::FnDecl && !item.name.is_empty() && returns_value(&item.extra_return_type) { + if item.kind == NodeKind::FnDecl && !item.name.is_empty() && tt::returns_value(item.extra_return_type.as_bytes()) { l.value_fns.insert(item.name.clone()); } } @@ -656,7 +749,7 @@ fn lower_mode<'a>( let mut const_names: Vec = l.const_nodes.keys().cloned().collect(); const_names.sort(); for name in const_names { - if l.unreferenced_tuple_const(&items, &name) || l.alias_target(&name).is_some() { + if l.unreferenced_tuple_const(&items, &name) || l.alias_target(&name).is_some() || wp::is_wide(l.const_nodes[&name].extra_type.trim().as_bytes()) { continue; } let _ = l.global(&name); @@ -731,6 +824,7 @@ fn lower_mode<'a>( _ => {} } } + l.literal_writes(); if !l.errors.is_empty() { return Err(l.errors); } @@ -780,18 +874,7 @@ fn lower_mode<'a>( /// Line (1-based) of the first ` ` header in `src`, the name /// optionally quoted. fn header_line(src: &str, keyword: &str, name: &str) -> Option { - for (i, line) in src.lines().enumerate() { - let Some(rest) = line.trim_start().strip_prefix(keyword) else { continue }; - let Some(rest) = rest.strip_prefix(|c: char| c == ' ' || c == '\t') else { continue }; - let rest = rest.trim_start(); - let rest = rest.strip_prefix('"').unwrap_or(rest); - if let Some(after) = rest.strip_prefix(name) { - if !after.starts_with(|c: char| c.is_ascii_alphanumeric() || c == '_') { - return Some(i as u32 + 1); - } - } - } - None + Some(st::header_line(src.as_bytes(), keyword.as_bytes(), name.as_bytes())).filter(|l| *l != st::NO_LINE) } /// Line (1-based) of the declaration of `name`: `const`, `pub const`, @@ -832,23 +915,8 @@ fn kind_name(n: &Node) -> String { /// ("invalid escape character") and a raw control byte, so neither has a /// reference result to agree with. fn char_literal(s: &str) -> Result { - let inner = s - .strip_prefix('\'') - .and_then(|r| r.strip_suffix('\'')) - .ok_or("ExprLiteral(char literal)")?; - let b = inner.as_bytes(); - match b { - [b'\\', e] => match e { - b'n' => Ok(10), - b'r' => Ok(13), - b't' => Ok(9), - b'\\' | b'\'' | b'"' => Ok(*e as i128), - _ => Err("ExprLiteral(char escape)"), - }, - [c] if (0x20..0x7f).contains(c) => Ok(*c as i128), - [_] => Err("ExprLiteral(char byte)"), - _ => Err("ExprLiteral(char literal)"), - } + let v = st::char_value(s.as_bytes()); + if v >= 0 { Ok(v as i128) } else { Err(st::char_error(v)) } } /// `n` is a char literal (`'a'`, `'\n'`): an untyped comptime_int in Zig that @@ -858,24 +926,7 @@ fn is_char_literal(n: &Node) -> bool { } fn parse_int(s: &str) -> Option { - let t: String = s.chars().filter(|c| *c != '_').collect(); - let (digits, radix) = if let Some(r) = t.strip_prefix("0x").or_else(|| t.strip_prefix("0X")) { - (r.to_string(), 16) - } else if let Some(r) = t.strip_prefix("0o") { - (r.to_string(), 8) - } else if let Some(r) = t.strip_prefix("0b") { - (r.to_string(), 2) - } else { - (t.clone(), 10) - }; - if digits.is_empty() { - return None; - } - let v = u128::from_str_radix(&digits, radix).ok()?; - if v > i128::MAX as u128 { - return None; - } - Some(v as i128) + Some(st::parse_int(s.as_bytes())).filter(|v| *v != st::NO_INT) } /// The width t27c's Zig backend pins on an untyped `var` set to a bare @@ -888,19 +939,8 @@ fn int_lit_width(n: &Node) -> Option<&'static str> { if n.kind != NodeKind::ExprLiteral || n.extra_kind == "string" { return None; } - const SUFFIXES: [&str; 10] = ["u8", "u16", "u32", "u64", "usize", "i8", "i16", "i32", "i64", "isize"]; - if let Some(s) = SUFFIXES.iter().find(|s| **s == n.extra_type) { - return Some(s); - } - let v = n.value.trim(); - if v.starts_with("0o") { - return None; - } - match parse_int(v)? { - x if x <= u32::MAX as i128 => Some("u32"), - x if x <= u64::MAX as i128 => Some("u64"), - _ => None, - } + let k = st::lit_width(n.extra_type.as_bytes(), n.value.as_bytes()); + (k != st::WIDTH_NONE).then(|| st::WIDTHS[k as usize]) } /// `n` is an integer literal that is a power of two above 1: what t27c's @@ -984,32 +1024,6 @@ impl<'a> Lower<'a> { } } } - NodeKind::TestBlock => { - let mut locals: HashSet<&str> = HashSet::new(); - let mut bound: HashSet<&str> = HashSet::new(); - for s in &item.children { - if s.kind == NodeKind::StmtLocal && !s.name.is_empty() { - locals.insert(s.name.as_str()); - } - if s.kind == NodeKind::StmtAssign - && s.children.len() >= 2 - && s.children[0].kind == NodeKind::ExprIdentifier - && !s.children[0].name.is_empty() - { - let name = s.children[0].name.as_str(); - if bound.insert(name) && locals.contains(name) { - found.push(( - if s.line != 0 { s.line } else { item.line }, - "StmtAssign(reference redeclares)", - format!( - "test `{}`: the first top-level assignment to the local `{}` is emitted by t27c's Zig backend as a fresh `const {} = ..`, a redeclaration", - item.name, name, name - ), - )); - } - } - } - } _ => {} } } @@ -1060,30 +1074,10 @@ impl<'a> Lower<'a> { /// shape share a name (`type [N]T`, `type []T`, `type (struct)`), so the /// count says how many files need that shape; the detail names the type. fn type_construct(&self, t: &str) -> (String, String) { - let shape = if let Some(k) = self.type_decls.get(t) { - format!("type ({})", k) - } else if t.starts_with("[]") { - "type []T".to_string() - } else if t.starts_with('[') { - "type [N]T".to_string() - } else if t.starts_with('(') { - "type (tuple)".to_string() - } else if t.starts_with('?') { - "type ?T".to_string() - } else if t.starts_with('*') { - "type *T".to_string() - } else if t.contains('!') { - "type E!T".to_string() - } else if t.starts_with("struct") { - "type (anonymous struct)".to_string() - } else if t.contains('(') { - "type (generic)".to_string() - } else if t.starts_with(|c: char| c.is_ascii_uppercase()) && !matches!(t, "Result" | "Option") { - // Declared nowhere this file can see: an import `use` did not - // splice, or a type of a sibling spec. - "type (undeclared)".to_string() - } else { - return (format!("type {}", t), String::new()); + let shape = match (self.type_decls.get(t), tt::shape(t.as_bytes())) { + (Some(k), _) => format!("type ({})", k), + (None, tt::SHAPE_PLAIN) => return (format!("type {}", t), String::new()), + (None, k) => tt::shape_name(k).to_string(), }; (shape, format!("`{}`", t)) } @@ -1132,14 +1126,18 @@ impl<'a> Lower<'a> { self.reject("FnDecl(comptime param)", format!("parameter `{}` of `{}`", pname, n.name)) } else if pty.is_empty() { self.reject("FnDecl(untyped param)", format!("parameter `{}` of `{}`", pname, n.name)) + } else if unread_any(n, pname, pty) { + Ok(LTy::Struct(self.void_struct())) } else { self.lty(pty) }; + self.layout_err |= r.is_err() && self.lazy_sig(pty, true); self.sig_layout_only &= r.is_ok() || self.layout_err; match r { Ok(t) => params.push(t), - // Recovery mode reports every parameter and the return type. - Err(()) if self.recover => bad = true, + // Recovery mode reports every parameter and the return type, and so does an unreached fn + // until a refusal `unresolved_sig` cannot withdraw. + Err(()) if self.recover || (self.layout_err && !self.analyzed.contains(&n.name)) => bad = true, Err(()) => return Err(()), } } @@ -1151,6 +1149,7 @@ impl<'a> Lower<'a> { } else { self.layout_err = false; let r = self.ret_lty(rt); + self.layout_err |= r.is_err() && self.lazy_sig(rt, false); self.sig_layout_only &= r.is_ok() || self.layout_err; Some(r?) }; @@ -1296,28 +1295,35 @@ impl<'a> Lower<'a> { let Some(init) = node.children.first() else { return self.reject("VarDecl(module)", format!("module-level var `{}` has no value", name)); }; - if is_undefined(init) { - return self.reject( - "VarDecl(module, undefined)", - format!("module-level var `{}` = undefined", name), - ); - } let t = self.lty(ann)?; - match &t { - LTy::S(_) | LTy::Enum(..) | LTy::Struct(_) | LTy::Arr(..) if !self.holds_str(&t)? => {} + let with_str = match &t { + LTy::Str => true, + LTy::S(_) | LTy::Enum(..) | LTy::Struct(_) | LTy::Arr(..) => self.holds_str(&t)?, + LTy::Opt(_) if self.is_null(init) => false, _ => { let d = self.type_name(&t); return self.reject( - "VarDecl(module, pointer/str/slice)", + "VarDecl(module, pointer/slice)", format!("module-level var `{}` of type {}", name, d), ); } - } + }; let (size, _) = self.size_align(&t)?; let mut buf = vec![0u8; size as usize]; let saved_scopes = std::mem::take(&mut self.scopes); let saved_ct = std::mem::replace(&mut self.comptime, true); + let mut init_val = None; let r = match &t { + _ if with_str => { + let v = if t == LTy::Str { self.const_elem(init, &t) } else { self.const_agg(init, &t) }; + v.map(|v| init_val = Some(v)) + } + // Reading a container-level `undefined` before a write has no portable Zig verdict; t27b gives 0xAA. + _ if is_undefined(init) => { + buf.fill(0xAA); + Ok(()) + } + LTy::Opt(_) => Ok(()), // `= null` (#7910): zero bytes, a null flag; no payload is read before a write LTy::S(ty) => { let ty = *ty; let mut f = || -> R<()> { @@ -1344,15 +1350,19 @@ impl<'a> Lower<'a> { self.globals_init.push(buf); let k = (self.globals_init.len() - 1) as u32; let addr = Expr { ty: Ty::Ptr, kind: ExprKind::Global(k) }; - self.mod_vars.insert(name, Place { addr, off: 0, ty: t, mutable: true, temp: None }); + let place = Place { addr, off: 0, ty: t, mutable: true, temp: None }; + if let Some(v) = init_val { + self.str_globals.push((place.clone(), v)); + } + self.mod_vars.insert(name, place); Ok(()) } /// A local, assigned parameter or capture with the name of a module-level - /// var. In a test the reference's Zig refuses it ("local variable shadows - /// declaration"); in a fn it renames the local to `_lv` for every - /// mention in the fn, including the ones meant for the module var. Either - /// way there is no reference verdict to match, so t27b refuses it. + /// var. The reference renames it to `_lv` in every mention in the + /// body (W736, #6295); `local` lets through the cases where that agrees + /// with t27 scoping (`shadow_names`). Otherwise there is no reference + /// verdict to match, so t27b refuses it. fn no_var_shadow(&mut self, name: &str) -> R<()> { if self.mod_vars.contains_key(name) { return self.reject( @@ -1517,8 +1527,10 @@ impl<'a> Lower<'a> { self.collect_ref_vars(body); self.slice_locals.clear(); self.tuple_locals.clear(); + self.tuple_names.clear(); self.dead_lits.clear(); self.discards.clear(); + self.shadow_ok = shadow_names(body, &self.mod_vars); let mut arrays = HashSet::new(); array_locals(body, &mut arrays); if !arrays.is_empty() { @@ -1585,6 +1597,25 @@ impl<'a> Lower<'a> { } } } + // W585: a name bound to a helper with no arguments and passed bare to a declared fn. + self.scaffold.clear(); + let helper = |d: &&Node| d.children.first().is_some_and(|x| x.kind == NodeKind::ExprCall && x.children.is_empty() && sc::HELPERS.split(' ').any(|h| h == x.name)); + let decls = |n: &str| { let mut d = Vec::new(); decls_of(body, n, &mut d); d }; + let (mut calls, mut found) = (Vec::new(), Vec::new()); + calls_in(body, &mut calls); + for c in &calls { + let (Some(sig), Some(f)) = (self.sigs.get(&c.name), self.fns.get(&c.name)) else { continue }; + for ((a, t), (p, _)) in c.children.iter().zip(&sig.params).zip(&f.params) { + if a.kind == NodeKind::ExprIdentifier && decls(&a.name).iter().any(helper) { + found.push((a.name.clone(), t.clone(), name_mentions(&f.children, p) > 0)); + } + } + } + for (name, t, read) in &found { + let uses = decls(name).len() + found.iter().filter(|f| f.0 == *name).count(); + let e = self.scaffold.entry(name.clone()).or_insert((t.clone(), name_mentions(body, name) > uses, false)); + e.2 |= *read; + } self.addr_lit_locals(body); self.scopes.clear(); self.scopes.push(HashMap::new()); @@ -1597,6 +1628,8 @@ impl<'a> Lower<'a> { self.enter_float_names(n); self.in_test = false; self.unanalyzed_fn = !self.analyzed.contains(&n.name); + let lits = n.children.iter().filter(|s| s.kind == NodeKind::StmtLocal && !s.extra_mutable && s.children.len() == 1); + self.lit_consts = lits.filter(|s| s.children[0].kind == NodeKind::ExprLiteral && bc::reads_as_int(s.children[0].value.trim().as_bytes())).map(|s| s.name.clone()).collect(); let (params, ret, poisoned) = { let s = &self.sigs[&n.name]; (s.params.clone(), s.ret.clone(), s.poisoned) @@ -1621,6 +1654,7 @@ impl<'a> Lower<'a> { } let nparams = self.vars.len(); let mut body = Vec::new(); + n.params.iter().for_each(|(p, _)| { self.shadow_ok.remove(p); }); for (pname, _) in n.params.iter() { // The reference renames a parameter that shadows a module-level // declaration (`x_arg`), except one the body assigns: that one @@ -1656,7 +1690,7 @@ impl<'a> Lower<'a> { // #6315: the reference returns a non-void fn's tail expression // (`fn f(v: u32) -> u32 { v + 1 }`). In a fn nothing analyzed // reaches, Zig never sees the body and the statement keeps its stub. - if !self.unanalyzed_fn && returns_value(&n.extra_return_type) { + if !self.unanalyzed_fn && tt::returns_value(n.extra_return_type.as_bytes()) { mark_tail_returns(&n.children, &mut self.tail_returns); } let lowered = self.stmts(&n.children); @@ -1776,7 +1810,17 @@ impl<'a> Lower<'a> { self.invariant_preds.clear(); self.in_test = false; self.comptime = false; - let body = body?; + // Built after the body, so it covers what the body added (fns are lowered before any entry). + let mut pre = Vec::new(); + for (p, v) in self.str_globals.clone() { + match v { + Val::S(k, len) => self.store_str(&p, k, len, &mut pre), + Val::A(_, elems) => self.store_const(&p, &elems, &mut pre)?, + _ => return self.reject("VarDecl(module)", "internal: a string-holding initial value".into()), + } + } + pre.append(&mut body?); + let body = pre; Ok(Func { name: n.name.clone(), nparams: 0, @@ -1831,7 +1875,8 @@ impl<'a> Lower<'a> { fn stmts(&mut self, ns: &[Node]) -> R> { let mut out = Vec::new(); - for n in ns { + for (i, n) in ns.iter().enumerate() { + self.last_stmt = i + 1 == ns.len(); if self.stmt(n, &mut out).is_err() { if !self.recover { return Err(()); @@ -2198,7 +2243,9 @@ impl<'a> Lower<'a> { if name.is_empty() || name.contains(|c: char| !(c.is_ascii_alphanumeric() || c == '_')) { return self.reject("StmtLocal", format!("binding `{}`", name)); } - self.no_var_shadow(&name)?; + if !(self.scopes.len() == 1 && !self.comptime && self.shadow_ok.contains(&name)) { + self.no_var_shadow(&name)?; + } let ann = n.extra_type.trim().to_string(); // The Zig backend's `zig_declared_int_type`: only these spellings // pin `1 << n` in the initializer (not an alias that resolves to one). @@ -2240,13 +2287,6 @@ impl<'a> Lower<'a> { /// is a `[N]T` built once, here. fn tuple_local(&mut self, init: &Node, name: String, t: LTy, out: &mut Vec) -> R<()> { self.see(init); - if init.children.is_empty() && init.extra_type.trim().is_empty() && init.extra_size.contains(';') { - // The reference pastes `v;n` between the braces of `.{ ... }`. - return self.reject( - "ExprArrayLiteral(repeat)", - format!("`{}` = `[{}]` is passed where an array is declared", name, init.extra_size.trim()), - ); - } let k = self.new_slot(&t)?; let dst = Place { addr: slot_expr(k), off: 0, ty: t, mutable: false, temp: None }; self.init(init, dst.clone(), true, out)?; @@ -2257,6 +2297,29 @@ impl<'a> Lower<'a> { fn local_with(&mut self, n: &Node, name: String, ann: String, out: &mut Vec) -> R<()> { let mutable = n.extra_mutable; let init = n.children.first().filter(|i| !is_undefined(i)); + let helper = init.is_some_and(|i| i.kind == NodeKind::ExprCall && sc::HELPERS.split(' ').any(|h| h == i.name)); + let s = self.scaffold.get(&name).cloned(); + let act = sc::plan(helper, s.is_some(), mutable, !ann.is_empty(), s.as_ref().is_some_and(|s| s.1), s.as_ref().is_some_and(|s| s.2)); + if sc::refuses(act) { + self.see(init.unwrap()); + return self.reject(sc::what(act), format!("`{}`: {}", name, sc::why(act))); + } + if let Some((t, ..)) = s.filter(|_| act == sc::SCAFFOLD) { + let k = self.new_slot(&t)?; + if let Some(ty) = reg_ty(&t) { out.push(Stmt::Store { addr: slot_expr(k), off: 0, value: Expr { ty, kind: ExprKind::Const(0) } }); } + self.bind(&name, Binding::Mem(Place { addr: slot_expr(k), off: 0, ty: t, mutable: false, temp: None })); + return Ok(()); + } + // `const r = f(x);` with `f` void (specs/tri/t27b/void_bind_plan.t27): the call, then void's value. + let void_call = init.is_some_and(|i| i.kind == NodeKind::ExprCall && self.sigs.get(&i.name).is_some_and(|s| s.ret.is_none() && !s.poisoned)); + if vb::bind(void_call, !ann.is_empty()) == vb::BIND { + let (call, _, _) = self.call(init.unwrap(), None)?; + out.push(Stmt::Eval(call)); + let t = LTy::Struct(self.void_struct()); + let k = self.new_slot(&t)?; + self.bind(&name, Binding::Mem(Place { addr: slot_expr(k), off: 0, ty: t, mutable, temp: None })); + return Ok(()); + } let ann = match init.filter(|_| mutable && ann.is_empty()).and_then(int_lit_width) { Some(w) => w.to_string(), None => ann, @@ -2328,6 +2391,9 @@ impl<'a> Lower<'a> { if let Some(t) = self.tuple_locals.get(&name).filter(|_| !mutable).cloned() { return self.tuple_local(init, name, t, out); } + if !mutable && self.tuple_array_local(init, &name)?.is_some() { + return Ok(()); + } } if init.kind == NodeKind::ExprTuple && !mutable { return self.tuple_value_local(init, &name, out); @@ -2429,6 +2495,11 @@ impl<'a> Lower<'a> { let target = &n.children[0]; let op = n.extra_op.as_str(); if matches!(target.kind, NodeKind::ExprFieldAccess | NodeKind::ExprIndex) { + // #7735: this frame's address, stored where the caller reads it after the return. + let x = self.frame_addr(&n.children[1]); + if fsp::refuses(self.in_test, !self.unanalyzed_fn, x.is_some(), self.param_root(target)) { + return self.reject(fsp::what(), format!("the address of `{}`, {}", x.unwrap_or_default(), fsp::why())); + } let dst = self.lvalue(target)?; return self.store(dst, op, &n.children[1], out); } @@ -2464,6 +2535,16 @@ impl<'a> Lower<'a> { return Ok(()); } } + // `_ = e;`, e not a bare name (specs/tri/t27b/discard_plan.t27): deleted where the reference deletes it, else e runs. + if name == "_" && (op.is_empty() || op == "=") { + let (mut calls, top) = (Vec::new(), self.scopes.len() == 1); + calls_in(std::slice::from_ref(rhs), &mut calls); + match dp::plan(rhs.kind == NodeKind::ExprIdentifier, self.in_test && top, !self.in_test && top, !calls.is_empty()) { + dp::DELETED => return Ok(()), + dp::EVALUATE => return self.discard_value(rhs, out), + _ => {} + } + } // A module-level var written at the top of a test is a write to // module state, as in a fn body: since #6295 the reference no longer // binds it as a fresh `const` (`block_fresh_binding`), see #6911. @@ -2488,7 +2569,7 @@ impl<'a> Lower<'a> { return self.reject("StmtAssign", format!("assignment to constant `{}`", name)); } let ty = self.vars[id as usize].ty; - let conv = |c: &Node| c.kind == NodeKind::ExprCall && matches!(c.name.as_str(), "@floatFromInt" | "@intFromFloat" | "@floatCast"); + let conv = |c: &Node| c.kind == NodeKind::ExprCall && matches!(c.name.as_str(), "@floatFromInt" | "@intFromFloat" | "@floatCast" | "@bitCast"); let rhs = if (op.is_empty() || op == "=") && conv(&n.children[1]) { self.expr_as(&n.children[1], <y::S(ty))? } else { @@ -2552,6 +2633,23 @@ impl<'a> Lower<'a> { } } + /// `_ = e;` that runs (discard_plan.t27's EVALUATE): e is evaluated for its effects and traps, its value dropped. + fn discard_value(&mut self, e: &Node, out: &mut Vec) -> R<()> { + self.see(e); + if e.kind == NodeKind::ExprCall && self.sigs.contains_key(&e.name) { + let (call, _, _) = self.call(e, None)?; + out.push(Stmt::Eval(call)); + return Ok(()); + } + match self.expr(e)? { + Val::Poison => return Err(()), + Val::E(x) | Val::P(x, _) => out.push(Stmt::Eval(x)), + Val::M(p) if !pure_addr(&p.addr) => out.push(Stmt::Eval(p.addr)), + _ => {} + } + Ok(()) + } + /// `undefined;`, the body stub a port leaves where plumbing was. t27c's /// Zig backend emits it as is, and Zig rejects it ("value of type /// '@TypeOf(undefined)' ignored") only in a fn it analyzes, i.e. one @@ -2750,6 +2848,15 @@ impl<'a> Lower<'a> { out.push(Stmt::Assert { cond: Expr { ty: Ty::Bool, kind: ExprKind::Const(0) }, site }); return Ok(()); } + // In a void fn `undefined` is the one `void` value, so the + // statement is a plain `return;`. Not in a test: its Zig result + // is an error union, and an undefined one is no value t27b can + // name. + if self.ret.is_none() && !self.ret_poison && !self.in_test { + self.see(c); + out.push(Stmt::Return(None)); + return Ok(()); + } if self.ret.as_ref().is_some_and(|t| !is_agg(t)) && !self.ret_poison { self.see(c); return self.reject( @@ -2765,13 +2872,21 @@ impl<'a> Lower<'a> { } return Ok(()); } + // #7550: the address of a local of this fn's frame dangles once the fn + // returns. Zig returns it all the same, and a test reading through it + // passes only while nothing reuses the dead frame: the interpreter + // faults on that read and the JIT reads stale stack. So t27b refuses. + if let Some(x) = v.filter(|_| !self.unanalyzed_fn).and_then(|c| self.frame_addr(c)) { + let why = format!("returns the address of `{}`, a local of this fn's frame, which ends at the return", x); + return self.reject("ExprReturn(frame address)", why); + } match (self.ret.clone(), v) { (None, None) => out.push(Stmt::Return(None)), (Some(t), Some(c)) if is_agg(&t) => { // Build the result in the caller's memory. let sret = Expr { ty: Ty::Ptr, kind: ExprKind::Var(self.sret.unwrap()) }; let dst = Place { addr: sret.clone(), off: 0, ty: t, mutable: true, temp: None }; - if !self.slice_literal_return(c, &dst, out)? { + if !self.slice_lit(sl::AT_RETURN, true, c, &dst, out)? { self.init(c, dst, true, out)?; } out.push(Stmt::Return(Some(sret))); @@ -2791,6 +2906,38 @@ impl<'a> Lower<'a> { Ok(()) } + /// The local in this fn's frame whose address the returned value `n` + /// holds: `&x`, `x[a..b]` or `x[a..]` of a local array with elements, + /// or a struct literal field that is one (#7550). A slice of a str or + /// slice local points where that one does, not into the frame. + fn frame_addr(&self, n: &Node) -> Option { + if n.kind == NodeKind::ExprStructLit { + return n.children.iter().filter_map(|f| f.children.first()).find_map(|c| self.frame_addr(c)); + } + let range = n.children.get(1).is_some_and(|r| r.kind == NodeKind::ExprBinary && r.extra_op == ".."); + let addr = match n.kind { + NodeKind::ExprUnary => n.extra_op == "&", + NodeKind::ExprIndex => matches!(n.extra_op.as_str(), "slice" | "slice_open") || n.extra_op.is_empty() && range, + _ => false, + }; + let b = n.children.first().filter(|b| addr && b.kind == NodeKind::ExprIdentifier)?; + let Some(Binding::Mem(p)) = self.lookup(&b.name) else { return None }; + let held = n.kind == NodeKind::ExprUnary || matches!(p.ty, LTy::Arr(_, len) if len > 0); + (held && matches!(p.addr.kind, ExprKind::Slot(_))).then(|| b.name.clone()) + } + + /// Whether assignment target `t` is reached through a parameter of pointer or slice type (#7735). + fn param_root(&self, mut t: &Node) -> bool { + while matches!(t.kind, NodeKind::ExprFieldAccess | NodeKind::ExprIndex) && !t.children.is_empty() { + t = &t.children[0]; + } + t.kind == NodeKind::ExprIdentifier && self.discards.contains_key(&t.name) && match self.lookup(&t.name) { + Some(Binding::Var { id, .. }) => matches!(self.ltys[id as usize], LTy::Ptr(..)), + Some(Binding::Mem(p)) => matches!(p.ty, LTy::Ptr(..) | LTy::Slice(..)), + _ => false, + } + } + /// An expression statement whose value nothing uses, and which is /// neither a tail the reference returns (`tail_returns`) nor a brace /// invariant's predicate (`invariant_preds`): a bare comparison, a value @@ -2862,6 +3009,48 @@ impl<'a> Lower<'a> { out.push(Stmt::Assert { cond, site }); Ok(()) } + // `@setEvalBranchQuota(n);` raises the backward-branch budget of + // Zig's compile-time evaluation and does nothing at run time. t27b + // does not model that budget, so a higher one opens no gap: the + // statement lowers to nothing. Zig wants a compile-time `u32` + // operand; anything else is refused. + "@setEvalBranchQuota" => { + if c.children.len() != 1 { + return self.reject( + "ExprCall(@setEvalBranchQuota)", + format!("with {} arguments", c.children.len()), + ); + } + let arg = &c.children[0]; + let v = self.expr(arg)?; + let n = match &v { + Val::Poison => return Err(()), + Val::Ct(n) => Some(*n), + Val::E(Expr { ty, kind: ExprKind::Const(n) }) if ty.is_int() => { + Some(*n) + } + _ => None, + }; + match n { + Some(n) if (0..=u32::MAX as i128).contains(&n) => Ok(()), + Some(n) => self.reject("ExprCall(@setEvalBranchQuota)", format!("of {}, outside u32", n)), + None => { + let d = self.val_desc(&v); + self.reject("ExprCall(@setEvalBranchQuota)", format!("of {}, not a compile-time integer", d)) + } + } + } + // `@panic("m");` the reference does not return (builtin_plan.t27): a trap that always fires. + "@panic" => { + let lit = c.children.first().is_some_and(|m| m.kind == NodeKind::ExprLiteral && m.extra_kind == "string"); + let act = bp::panic_stmt(c.children.len(), lit, self.last_stmt); + if act != bp::P_TRAP { + return self.reject(bp::panic_what(act), format!("`@panic`: {}", bp::panic_why(act))); + } + let site = self.site(TrapKind::Assert, "@panic".into(), Ty::Bool); + out.push(Stmt::Assert { cond: Expr { ty: Ty::Bool, kind: ExprKind::Const(0) }, site }); + Ok(()) + } "assert_eq" => { if c.children.len() != 2 { return self.reject( @@ -2991,7 +3180,9 @@ impl<'a> Lower<'a> { } let mut args = Vec::new(); for (i, a) in c.children.iter().enumerate() { - let v = self.arg_as(a, ¶ms[i])?; + let v = if self.fns.get(&c.name).and_then(|f| f.params.get(i).map(|p| unread_any(f, &p.0, &p.1))) == Some(true) { + self.any_arg(c, a, ¶ms[i])? + } else if is_undefined(a) && !self.is_void(¶ms[i]) { self.undefined_arg(c, i, a, ¶ms[i])? } else { self.arg_as(a, ¶ms[i])? }; args.push(match v { // By reference; the callee never writes it. Val::M(p) => addr_of(&p), @@ -3018,6 +3209,37 @@ impl<'a> Lower<'a> { Ok((Expr { ty, kind: ExprKind::Call { func: id, args } }, ret, temp)) } + /// `f(undefined)` for a parameter that is not `void` (specs/tri/t27b/undefined_arg_plan.t27): the call runs and + /// the argument is a value of the parameter's type that nobody reads, or the plan's refusal. + fn undefined_arg(&mut self, c: &Node, i: usize, a: &Node, t: <y) -> R { + let p = self.fns.get(&c.name).and_then(|f| f.params.get(i).map(|(p, _)| (p.clone(), name_mentions(&f.children, p) > 0))); + let act = ua::plan(p.is_some(), p.as_ref().is_some_and(|p| p.1), is_agg(t)); + if !ua::takes(act) && !ua::refuses(act) { + return self.arg_as(a, t); + } + self.see(a); + if ua::refuses(act) { + return self.reject(ua::what(act), format!("`{}` of `{}`: {}", p.map_or(String::new(), |p| p.0), c.name, ua::why(act))); + } + if act == ua::UNREAD_MEMORY { + let k = self.new_slot(t)?; + return Ok(Val::M(Place { addr: slot_expr(k), off: 0, ty: t.clone(), mutable: false, temp: None })); + } + Ok(val_of(Expr { ty: reg_ty(t).unwrap_or(Ty::Ptr), kind: ExprKind::Const(0) }, t)) + } + + /// The argument for an `anytype` parameter the body never names (specs/tri/t27b/any_param_plan.t27): void's value + /// when evaluating it runs nothing, else the plan's refusal. + fn any_arg(&mut self, c: &Node, a: &Node, t: <y) -> R { + let pure = self.is_null(a) || matches!(self.expr(a)?, Val::S(..) | Val::Ct(_)); + if ap::arg(pure) == ap::REFUSE { + self.see(a); + return self.reject(ap::what(), format!("call to `{}`: {}", c.name, ap::why())); + } + let k = self.new_slot(t)?; + Ok(Val::M(Place { addr: slot_expr(k), off: 0, ty: t.clone(), mutable: false, temp: None })) + } + // ----------------------------------------------------------- expressions fn cond(&mut self, n: &Node) -> R { @@ -3091,17 +3313,16 @@ impl<'a> Lower<'a> { if to == Ty::F64 && e.ty == Ty::F32 { return Ok(float::float_cast(e, to)); } - if to.can_widen_from(e.ty) { - if let ExprKind::Const(c) = e.kind { - return Ok(Expr { - ty: to, - kind: ExprKind::Const(c), - }); - } - return Ok(Expr { - ty: to, - kind: ExprKind::Widen(Box::new(e)), - }); + // specs/tri/t27b/coerce_plan.t27: a widening, a constant that fits, an integer a float holds exactly. + let c = match e.kind { ExprKind::Const(c) => Some(c), _ => None }; + if e.ty.is_int() && to.is_float() && cp::int_to_float(e.ty.bits(), e.ty.signed(), to.bits(), c.is_some(), c.map_or(0, |c| c.unsigned_abs() as u64)) == cp::CONVERT { + return match self.int_to_float(Val::E(e), to, "type mismatch")? { Val::E(f) => Ok(f), _ => Err(()) }; + } + let act = if e.ty.is_int() && to.is_int() { cp::int_to_int(e.ty.bits(), e.ty.signed(), to.bits(), to.signed(), c.is_some(), c.is_some_and(|c| to.fits(c))) } else { cp::REFUSE }; + match (act, c) { + (cp::INT_WIDEN | cp::INT_FOLD, Some(c)) => return Ok(Expr { ty: to, kind: ExprKind::Const(c) }), + (cp::INT_WIDEN, None) => return Ok(Expr { ty: to, kind: ExprKind::Widen(Box::new(e)) }), + _ => {} } self.reject( "type mismatch", @@ -3149,20 +3370,14 @@ impl<'a> Lower<'a> { if x.ty == Ty::F32 && y.ty == Ty::F64 { return Ok((float::float_cast(x, Ty::F64), y)); } - if x.ty.can_widen_from(y.ty) { - let t = x.ty; - let y = self.coerce(Val::E(y), t)?; - return Ok((x, y)); - } - if y.ty.can_widen_from(x.ty) { - let t = y.ty; - let x = self.coerce(Val::E(x), t)?; - return Ok((x, y)); - } - self.reject( - "type mismatch", - format!("`{}` on {} and {}", what, x.ty.name(), y.ty.name()), - ) + // specs/tri/t27b/coerce_plan.t27: the integer type with more bits (the first on a tie), or the float. + let t = match (x.ty.is_int(), y.ty.is_int()) { + (true, true) => if cp::peer_is_first(x.ty.bits(), y.ty.bits()) { x.ty } else { y.ty }, + (false, true) if x.ty.is_float() => x.ty, + (true, false) if y.ty.is_float() => y.ty, + _ => return self.reject("type mismatch", format!("`{}` on {} and {}", what, x.ty.name(), y.ty.name())), + }; + Ok((self.coerce(Val::E(x), t)?, self.coerce(Val::E(y), t)?)) } (Val::E(x), v @ Val::Cf(..)) => { let t = x.ty; @@ -3253,10 +3468,20 @@ impl<'a> Lower<'a> { if (op == "==" || op == "!=") && (self.is_null(&n.children[0]) || self.is_null(&n.children[1])) { return self.null_compare(&op, n); } + if let Some(u) = n.children.iter().position(is_undefined).filter(|_| op == "==" || op == "!=") { + let v = &n.children[1 - u]; + let void_name = v.kind == NodeKind::ExprIdentifier && matches!(self.lookup(&v.name), Some(Binding::Mem(p)) if self.is_void(&p.ty)); + let act = vb::compare(op == "==", op == "!=", void_name); + if act != vb::NOT_MINE { + return Ok(Val::E(Expr { ty: Ty::Bool, kind: ExprKind::Const(vb::folded(act) as i128) })); + } + } + if let Some(v) = self.wide_fold(n, None)? { return Ok(v); } let (x, y) = (&n.children[0], &n.children[1]); let lit = |n: &Node| n.kind == NodeKind::ExprEnumValue; let ordered = (self.names_variant(x) || self.names_variant(y)) && !lit(x) && !lit(y); let (a, b) = self.operands(x, y)?; + if let Some(v) = self.ptr_compare(&op, &a, &b)? { return Ok(v); } if let Some(v) = self.opt_compare(&op, &a, &b)? { return Ok(v); } @@ -3314,6 +3539,7 @@ impl<'a> Lower<'a> { self.unary(&op, v) } NodeKind::ExprCall if n.name == "@intFromEnum" => self.int_from_enum(n, TagUse::Value), + NodeKind::ExprCall if n.name == "@intFromBool" => self.bit_cast(n, Ty::UN(1)), NodeKind::ExprCall if n.name == "@floatFromInt" || n.name == "@intFromFloat" || n.name == "@floatCast" => { self.reject(&format!("ExprCall({})", n.name), "with no result type".into()) } @@ -3334,6 +3560,8 @@ impl<'a> Lower<'a> { self.reject("ExprCall(@sqrt)", format!("of {}, not a run-time float", d)) } }, + NodeKind::ExprCall if matches!(n.name.as_str(), "@abs" | "@max" | "@min" | "@divTrunc") => self.builtin_plan(n), + NodeKind::ExprCall if xp::BUILTINS.split(' ').any(|b| b == n.name) => self.libm_call(n), // `@as(T, x)`: `x` coerced to `T`. NodeKind::ExprCall if n.name == "@as" && n.children.len() == 2 && n.children[0].kind == NodeKind::ExprIdentifier => { // An identifier is printed as a value (`gf16.GF16`), not @@ -3368,6 +3596,7 @@ impl<'a> Lower<'a> { if n.children.len() != 1 { return self.reject("ExprCast", "unexpected shape".into()); } + if let Some(v) = self.wide_fold(&n.children[0], Some(n.extra_type.trim()))? { return Ok(v); } // The operand first, so that in recovery mode an unsupported // operand and an unsupported target type are both named. let v = self.expr(&n.children[0])?; @@ -3387,6 +3616,7 @@ impl<'a> Lower<'a> { return Ok(Val::E(Expr { ty: Ty::U64, kind: ExprKind::Const(len as i128) })); } } + if let Some(v) = self.std_math_const(n) { return Ok(v); } match self.member(n)? { Ok(p) => self.place_value(p), Err(v) => Ok(v), @@ -3507,6 +3737,155 @@ impl<'a> Lower<'a> { Ok(Val::E(Expr { ty: to, kind: ExprKind::Cast { arg: Box::new(e), site } })) } + /// `@ptrFromInt(x)` for an optional pointer: the address, null when it is 0 (plan `opaque_plan.t27`, #7737). + fn ptr_from_int(&mut self, n: &Node, want: <y) -> R> { + let (w, t) = match want { + LTy::Opt(o) if matches!(**o, LTy::Ptr(..)) => (oq::W_OPT_PTR, &**o), + LTy::Ptr(..) => (oq::W_PTR, want), + _ => return Ok(None), + }; + let LTy::Ptr(p, _) = t else { return Ok(None) }; + let opaque = matches!(**p, LTy::Struct(id) if self.structs[id as usize].name == "anyopaque"); + let act = oq::from_int(w, if opaque { 1 } else { self.size_align(p)?.1 }, n.children.len()); + if act == oq::NOT_MINE { return Ok(None); } + self.see(n); + if oq::refuses(act) { return self.reject(oq::what(act), oq::why(act).into()); } + let x = self.expr_as(&n.children[0], <y::S(Ty::U64))?; + let k = self.new_slot(want)?; + let at = Box::new(Expr { ty: Ty::U64, kind: ExprKind::Load { addr: Box::new(slot_expr(k)), off: 0 } }); + let zero = Box::new(Expr { ty: Ty::U64, kind: ExprKind::Const(0) }); + let flag = Expr { ty: Ty::Bool, kind: ExprKind::Cmp { op: CmpOp::Ne, lhs: at, rhs: zero } }; + let stmts = vec![Stmt::Store { addr: slot_expr(k), off: 0, value: self.reg(x)? }, Stmt::Store { addr: slot_expr(k), off: 8, value: flag }]; + let addr = Expr { ty: Ty::Ptr, kind: ExprKind::Seq { stmts, value: Box::new(slot_expr(k)) } }; + Ok(Some(Val::M(Place { addr, off: 0, ty: want.clone(), mutable: false, temp: Some(k) }))) + } + + /// `@intCast(x)` with integer result type `ty` from the context (`@as`, a typed binding, a parameter, a + /// return). What is refused and what the rest lowers to: specs/tri/t27b/int_cast_plan.t27. + fn int_cast(&mut self, n: &Node, ty: Ty) -> R { + self.see(n); + let shape = ic::shape(n.children.len(), ty.is_int()); + let v = if shape == ic::GO { self.expr(&n.children[0])? } else { Val::Poison }; + let (k, from, c) = match &v { + Val::Poison if shape == ic::GO => return Err(()), + Val::E(e) if e.ty.is_int() => (ic::K_INT, e.ty, if let ExprKind::Const(c) = e.kind { Some(c) } else { None }), + Val::Ct(c) => (ic::K_CT, ty, Some(*c)), + _ => (ic::K_OTHER, ty, None), + }; + let (fits, wrap) = (c.is_some_and(|c| ty.fits(c)), self.mode == OverflowMode::Wrap); + let plan = |k| ic::plan(k, from.bits(), from.signed(), ty.bits(), ty.signed(), c.is_some(), fits, wrap); + let kind = match (if shape == ic::GO { plan(k) } else { shape }, v) { + (ic::KEEP, v) => return Ok(v), + (ic::FOLD | ic::FOLD_WRAP, _) => ExprKind::Const(ty.wrap(c.unwrap())), // a FOLD fits `ty`: wrap keeps it + (ic::WIDEN, Val::E(e)) => ExprKind::Widen(Box::new(e)), + (a, Val::E(e)) if ic::is_cast(a) => { + let what = format!("{} {} to {}", ic::SITE, from.name(), ty.name()); + ExprKind::Cast { arg: Box::new(e), site: if ic::traps(a) { self.site(TrapKind::Cast, what, ty) } else { 0 } } + } + (a, v) => { + let d = match &v { Val::E(e) => e.ty.name().into(), Val::Ct(c) => c.to_string(), _ => self.val_desc(&v) }; + let d = if v.is_poison() { format!("{} operands", n.children.len()) } else { d }; + return self.reject(ic::WHAT, format!("`@intCast` of {} to {}: {}", d, ty.name(), ic::why(a))); + } + }; + Ok(Val::E(Expr { ty, kind })) + } + + /// An index or a slice bound, whose result type in Zig is `ic::INDEX_TYPE`: an `@intCast` there converts to it. + fn usize_operand(&mut self, n: &Node) -> R { + if n.kind == NodeKind::ExprCall && n.name == ic::SITE { self.int_cast(n, Ty::from_name(ic::INDEX_TYPE).unwrap_or(Ty::U64)) } else { self.expr(n) } + } + + /// `n` folded as Zig folds an expression that names a module constant of an integer type wider than 64 bits: + /// integer literals, such constants and the operators between them (specs/tri/t27b/wide_plan.t27). + fn wide(&mut self, n: &Node) -> wp::WideFold { + let k: Vec = n.children.iter().map(|c| self.wide(c)).collect(); + let c = self.const_nodes.get(n.name.as_str()).copied().filter(|c| wp::is_wide(c.extra_type.trim().as_bytes())); + match (&n.kind, c) { + (NodeKind::ExprLiteral, _) => wp::literal(n.value.trim().as_bytes(), n.extra_type.trim().as_bytes(), n.extra_kind == "string"), + (NodeKind::ExprIdentifier, Some(c)) if self.lookup(&n.name).is_none() && self.resolving.insert(n.name.clone()) => { + let v = c.children.first().map_or_else(wp::other, |i| self.wide(i)); + self.resolving.remove(&n.name); + wp::constant(v, c.extra_type.trim().as_bytes()) + } + (NodeKind::ExprBinary | NodeKind::ExprUnary, _) if !k.is_empty() => wp::apply(n.extra_op.trim().as_bytes(), k[0], k[k.len() - 1], k.len()), + _ => wp::other(), + } + } + + /// A comparison (`to` None), or an `as` to `to`, of an expression that names a wide constant: the constant `wide` + /// folds it to, or the plan's refusal under that constant's type. None when it names none. + fn wide_fold(&mut self, n: &Node, to: Option<&str>) -> R> { + let v = self.wide(n); + if !wp::folds(v) { + return Ok(None); + } + let ty = match to { Some(t) => self.ty(t)?, None => Ty::Bool }; + match wp::verdict(v, to.is_some(), ty.is_int(), ty.bits(), ty.signed()) { + wp::OK => Ok(Some(Val::E(Expr { ty, kind: ExprKind::Const(ty.wrap(wp::low64(v) as i128)) }))), + r => self.reject(&format!("type {}{}", wp::letter(v), v.named), wp::why(r).into()), + } + } + + /// A builtin of libm_plan.t27 (`@exp`, `@log`): a call of its routine from specs/tri/t27b/libm.t27, compiler_rt's + /// algorithm, so the bits are the reference's, folded or not. What is refused instead is the plan's. + fn libm_call(&mut self, n: &Node) -> R { + self.see(n); + let b = xp::BUILTINS.split(' ').position(|s| s == n.name).unwrap_or(0) as u8; + let ok = n.children.len() == xp::arity(b); + let t = xp::takes_type(b) && ok; // `std.math.nan(f32)`: the first operand names the type, which no argument carries + let at = xp::operand(b); // `std.math.log(T, base, x)`: the value is the third + let v = if ok && !t { self.expr(&n.children[at])? } else { Val::Poison }; + let k = match &v { + _ if t => match n.children[0].name.as_str() { "f64" => xp::K_F64, "f32" => xp::K_F32, _ => xp::K_OTHER }, + Val::Poison if ok => return Err(()), + Val::E(e) if e.ty == Ty::F64 => xp::K_F64, + Val::E(e) if e.ty == Ty::F32 => xp::K_F32, + Val::Cf(..) | Val::Ct(_) => xp::K_LITERAL, + _ => xp::K_OTHER, + }; + let named = if k == xp::K_F64 { "f64" } else { "f32" }; + let base_e = n.children.get(1).filter(|c| c.name == "e").is_some_and(|c| self.std_math_const(c).is_some()); + let a = xp::with_base(b, xp::plan(b, n.children.len(), k), base_e, n.children.first().is_some_and(|c| c.name == named)); + match (v, self.sigs.get(xp::routine(b, a)).filter(|s| !s.poisoned).map(|s| (s.id, s.ret.clone()))) { + (v, Some((func, Some(LTy::S(ty))))) if t || matches!(v, Val::E(_)) => { + let mut args = if t { vec![] } else { vec![self.reg(v)?] }; + for c in &n.children[at + 1..] { + let r = self.expr_as(c, <y::S(if k == xp::K_F64 { Ty::F64 } else { Ty::F32 }))?; // `@rem(x, 2.0)`: the first one's type + args.push(self.reg(r)?); + } + Ok(Val::E(Expr { ty, kind: ExprKind::Call { func, args } })) + } + _ => self.reject(xp::what(b), format!("`{}`: {}", n.name, xp::why(a))), + } + } + + /// `@bitCast(x)` with scalar result type `ty`, and `@intFromBool(x)` (`ty` u1), as specs/tri/t27b/bit_cast_plan.t27 says. + fn bit_cast(&mut self, n: &Node, ty: Ty) -> R { + self.see(n); + let v = if n.children.len() == 1 { self.expr(&n.children[0])? } else { Val::Poison }; + let code = |t: Ty| bc::code(t == Ty::Bool, t.is_float(), t.signed()); + let (from, bits, c) = match &v { + Val::Poison if n.children.len() == 1 => return Err(()), + Val::E(e) => (code(e.ty), e.ty.bits(), if let ExprKind::Const(c) = e.kind { Some(c) } else { None }), + v => (if matches!(v, Val::Ct(_) | Val::Cf(..)) { bc::T_LITERAL } else { bc::T_OTHER }, 0, None), + }; + let inl = !self.in_test && n.children.first().is_some_and(|c| c.kind == NodeKind::ExprIdentifier && self.lit_consts.contains(&c.name)); + let a = bc::plan(n.name == "@intFromBool", n.children.len(), from, bits, code(ty), ty.bits(), c.is_some(), inl); + let slot = if a == bc::VIA_SLOT { self.new_slot(<y::S(ty))? } else { 0 }; + let d = if let Val::E(e) = &v { e.ty.name().to_string() } else { self.val_desc(&v) }; + let kind = match (a, v) { + (bc::KEEP, v) => return Ok(v), + (bc::FOLD, _) => ExprKind::Const(ty.wrap(c.unwrap_or(0))), + (bc::WIDEN, Val::E(e)) => ExprKind::Widen(Box::new(e)), + (bc::WRAP, Val::E(e)) => ExprKind::Cast { arg: Box::new(e), site: 0 }, + (bc::VIA_SLOT, Val::E(e)) => ExprKind::Seq { stmts: vec![Stmt::Store { addr: slot_expr(slot), off: 0, value: e }], + value: Box::new(Expr { ty, kind: ExprKind::Load { addr: Box::new(slot_expr(slot)), off: 0 } }) }, + (a, _) => return self.reject(bc::what(n.name == "@intFromBool"), format!("`{}` of {} to {}: {}", n.name, d, ty.name(), bc::why(a))), + }; + Ok(Val::E(Expr { ty, kind })) + } + /// A module-level `var` named where t27c's Zig backend needs a /// compile-time value: Zig cannot read or write a container-level `var` /// in a `comptime` block or in a module-level initializer. @@ -3579,7 +3958,10 @@ impl<'a> Lower<'a> { Err(what) => self.reject(what, format!("`{}`", s)), }; } else if s.contains('.') || (s.contains(['e', 'E']) && !s.starts_with("0x")) { - match float::Q::parse(s) { + // A minus the parser folded in front is Zig's negation of the literal after it (`lp`). + let (b, neg) = (s.as_bytes(), lp::FLOAT_NEGATED); + let sign = lp::float_sign(b[0], b.get(1).copied().unwrap_or(0), b.len()); + match float::Q::parse(&s[lp::skip(sign)..]).map(|q| if sign == neg { q.neg() } else { q }) { Ok(q) => { let suffix = n.extra_type.trim(); if suffix.is_empty() { @@ -3742,6 +4124,13 @@ impl<'a> Lower<'a> { if !ty.is_int() && !bitwise { return self.reject(&format!("ExprBinary({})", op), "on bool".into()); } + // Two typed constants fold as Zig folds them where the plan says so (specs/tri/t27b/coerce_plan.t27). + if let (ExprKind::Const(p), ExprKind::Const(q), true) = (&x.kind, &y.kind, ty.is_int()) { + let r = match aop { ArithOp::Add | ArithOp::AddW => p.checked_add(*q), ArithOp::Sub | ArithOp::SubW => p.checked_sub(*q), ArithOp::Mul | ArithOp::MulW => p.checked_mul(*q), ArithOp::And => Some(p & q), ArithOp::Or => Some(p | q), ArithOp::Xor => Some(p ^ q), ArithOp::Div | ArithOp::DivW => p.checked_div(*q), ArithOp::Rem => p.checked_rem(*q), _ => None }; + let b = op.as_bytes(); + // `/` and `%` fold where specs/tri/t27b/const_div_plan.t27 says so, as Zig folds them at compile time. + if let Some(r) = r.filter(|r| cp::folds(b[0], b.get(1).copied().unwrap_or(0), b.len(), ty.fits(*r)) || dv::div_folds(b[0], b.len(), ty.signed(), *q == 0, ty.fits(*r))) { return Ok(Val::E(Expr { ty, kind: ExprKind::Const(ty.wrap(r)) })); } + } let site = match aop { ArithOp::Add | ArithOp::Sub | ArithOp::Mul => { self.site(TrapKind::Overflow, format!("{} on {}", op, ty.name()), ty) @@ -3926,6 +4315,14 @@ impl<'a> Lower<'a> { if !y.ty.is_int() { return self.reject("ExprBinary(<< >>)", "bool shift amount".into()); } + if ty.is_odd() && matches!(op, ArithOp::ShlW | ArithOp::ShrW) { + // Wrap mode masks the amount with `bits - 1`, + // which is no mask for an odd width. + return self.reject( + "ExprBinary(<< >>)", + format!("runtime wrap-mode shift of {}", ty.name()), + ); + } let site = if matches!(op, ArithOp::Shl | ArithOp::Shr) { self.site(TrapKind::ShiftRange, format!("{} on {}", op.symbol(), ty.name()), ty) } else { @@ -4030,6 +4427,17 @@ impl<'a> Lower<'a> { }, })); } + // Two integers of different types compare by value (specs/tri/t27b/coerce_plan.t27). + let k = |e: &Expr| match e.kind { ExprKind::Const(c) => Some(c), _ => None }; + let ints = match (&a, &b) { (Val::E(x), Val::E(y)) if x.ty.is_int() && y.ty.is_int() && x.ty != y.ty => Some((x.ty, y.ty, k(x), k(y))), _ => None }; + if let Some((sx, sy, cx, cy)) = ints { + let t = match cp::compare_in(sx.bits(), sx.signed(), cx.is_some_and(|c| sy.fits(c)), sy.bits(), sy.signed(), cy.is_some_and(|c| sx.fits(c))) { + cp::IN_A => sx, cp::IN_B => sy, cp::IN_I64 => Ty::I64, + r => return self.reject("type mismatch", format!("`{}` on {} and {}: {}", op.symbol(), sx.name(), sy.name(), cp::compare_why(r))), + }; + let (x, y) = (self.coerce(a, t)?, self.coerce(b, t)?); + return Ok(Val::E(Expr { ty: Ty::Bool, kind: ExprKind::Cmp { op, lhs: Box::new(x), rhs: Box::new(y) } })); + } let (x, y) = self.peer(a, b, op.symbol())?; if x.ty == Ty::Bool && !matches!(op, CmpOp::Eq | CmpOp::Ne) { return self.reject(&format!("ExprBinary({})", op.symbol()), "ordering on bool".into()); @@ -4051,6 +4459,19 @@ impl<'a> Lower<'a> { /// pointer is only named, so a struct may point to itself. fn lty_in(&mut self, name: &str, by_value: bool) -> R { let t = name.trim(); + // #7415: t27 also spells an optional after the type, `str?`, `Foo?`. + // t27c's type mapper writes `T?` as Zig's `?T` whenever `T` is not + // empty and does not itself start with `?`; read it the same way. + // (The parser keeps the suffix only on a struct field's type.) + if let Some(inner) = t.strip_suffix('?') { + let inner = inner.trim(); + if !inner.is_empty() && !inner.starts_with('?') { + if inner.ends_with('?') { + return self.reject("type ?T(??T)", format!("`{}`: an optional of an optional", t)); + } + return self.lty_in(&format!("?{}", inner), by_value); + } + } if let Some(rest) = t.strip_prefix('?') { let inner = self.lty_in(rest, by_value)?; if matches!(inner, LTy::Opt(_)) { @@ -4091,7 +4512,7 @@ impl<'a> Lower<'a> { // type mapper writes a path whose last segment it maps on its own as // that mapping: `gf16::GF16` is `u16`, as a bare `GF16` is, in a field, // a parameter, a result and a local's annotation. - if is_scoped_gf16(t) { + if tt::scoped_gf16(t.as_bytes()) { return Ok(LTy::S(Ty::U16)); } // t27c's Zig backend spells all four `[]const u8`. @@ -4133,7 +4554,7 @@ impl<'a> Lower<'a> { // bracket pair around the whole type, no `;` -- is the mutable slice // `[]T`. if let Some(inner) = t.strip_prefix('[').and_then(|r| r.strip_suffix(']')) { - if close_of_open(t) == Some(t.len() - 1) { + if tt::close_in(t.as_bytes(), 0, t.len()) == t.len() as i64 - 1 { let inner = inner.trim(); if inner == "*" || inner.starts_with('*') { return self.reject("type [*]T", format!("`{}`: a many-item pointer", t)); @@ -4165,6 +4586,17 @@ impl<'a> Lower<'a> { return Ok(LTy::Arr(Box::new(inner), n)); } } + // `anyopaque` names no layout: only a pointer to it (plan `opaque_plan.t27`, #7737). + if t == "anyopaque" && !oq::refuses(oq::opaque_type(by_value)) { + let id = *self.struct_ids.entry(t.into()).or_insert(self.structs.len() as u32); + if id as usize == self.structs.len() { + let (what, why) = (oq::what(oq::REFUSE_BY_VALUE).into(), oq::why(oq::REFUSE_BY_VALUE).into()); + let fail = Some(Reject { construct: what, line: self.line, detail: why }); + self.structs.push(StructDef { name: t.into(), fields: Vec::new(), size: None, align: 1, fail }); + } + return Ok(LTy::Struct(id)); + } + self.layout_err |= wp::is_wide(t.as_bytes()); // Zig resolves a wide type only where it is used (`unresolved_sig`) let (construct, detail) = self.type_construct(t); self.reject(&construct, detail) } @@ -4841,6 +5273,9 @@ impl<'a> Lower<'a> { r => r, }; } + if n.kind == NodeKind::ExprCall && n.name == "@ptrFromInt" { + if let Some(v) = self.ptr_from_int(n, want)? { return Ok(v); } + } if let LTy::Opt(inner) = want { if self.is_null(n) { self.see(n); @@ -4865,6 +5300,10 @@ impl<'a> Lower<'a> { if let (NodeKind::ExprCall, "@floatCast", LTy::S(ty)) = (&n.kind, n.name.as_str(), want) { return self.float_cast_call(n, *ty); } + if let (NodeKind::ExprCall, "@intCast", LTy::S(ty)) = (&n.kind, n.name.as_str(), want) { + return self.int_cast(n, *ty); + } + if let (NodeKind::ExprCall, "@bitCast", LTy::S(ty)) = (&n.kind, n.name.as_str(), want) { return self.bit_cast(n, *ty); } if let (NodeKind::ExprCall, "@intFromEnum", LTy::S(ty)) = (&n.kind, n.name.as_str(), want) { let v = self.int_from_enum(n, TagUse::Want(*ty))?; return self.coerce_to(v, want); @@ -4903,6 +5342,16 @@ impl<'a> Lower<'a> { return self.slice_of(addr_of(&arr), len, want.clone()); } } + // `&.{}` where a slice is wanted: a zero-length one (plan `empty_lit_plan.t27`, #7735). + if let (NodeKind::ExprUnary, "&", [c]) = (&n.kind, n.extra_op.as_str(), &n.children[..]) { + let w = if matches!(want, LTy::Slice(..) | LTy::Str) { el::WANT_SLICE } else { el::WANT_OTHER }; + if c.kind == NodeKind::ExprTuple && el::plan(w, true, c.children.len()) == el::EMPTY_SLICE { + self.see(n); + let elem = if let LTy::Slice(e, _) = want { (**e).clone() } else { LTy::S(Ty::U8) }; + let Val::M(arr) = self.struct_temp(c, LTy::Arr(Box::new(elem), 0))? else { return Err(()) }; + return self.slice_of(addr_of(&arr), 0, want.clone()); + } + } // `&[_]T{ ... } ** n` where a slice is wanted: t27c prints // `&.{ ... } ** n`, which Zig reads as `(&.{ ... }) ** n`, a pointer // to a tuple, and refuses once it analyzes it ("expected indexable"). @@ -5068,6 +5517,31 @@ impl<'a> Lower<'a> { } } + /// Builtin `b`'s plan (builtin_plan.t27) in IR: slots `zero`, the operands evaluated once, the rows. + fn plan_rows(&mut self, b: u8, ty: Ty, zero: Val, vals: Vec) -> R { + let (mut slots, mut stmts) = (vec![zero], Vec::new()); + for v in vals { + let e = self.coerce(v, ty)?; + let e = if matches!(e.kind, ExprKind::Const(_) | ExprKind::Var(_)) { e } else { + let k = self.new_slot(<y::S(ty))?; + stmts.push(Stmt::Store { addr: slot_expr(k), off: 0, value: e }); + Expr { ty, kind: ExprKind::Load { addr: Box::new(slot_expr(k)), off: 0 } } + }; + slots.push(Val::E(e)); + } + for i in 0..bp::rows(b, ty.is_float()) { + let (op, f) = (bp::row_op(b, i), |k| slots[bp::row_field(b, i, k)].clone()); + let mut v = self.binary(bp::op_text(op), f(bp::F_L), f(bp::F_R))?; + if bp::op_selects(op) { + let c = self.coerce(v, Ty::Bool)?; + v = self.select_vals(c, f(bp::F_THEN), f(bp::F_ELSE), Some(<y::S(ty)), "", "")?; + } + slots.push(v); + } + let Some(Val::E(v)) = slots.pop() else { unreachable!() }; + Ok(Val::E(if stmts.is_empty() { v } else { Expr { ty, kind: ExprKind::Seq { stmts, value: Box::new(v) } } })) + } + fn if_arm(&mut self, n: &Node, want: Option<<y>) -> R { match want { Some(t) => self.expr_as(n, t), @@ -5327,6 +5801,10 @@ impl<'a> Lower<'a> { fn int_to_float(&mut self, v: Val, to: Ty, what: &str) -> R { let e = match v { Val::Poison => return Err(()), + // A comptime_int rounds as below, inside 64 bits (coerce_plan.t27 `float_from_int_literal`). + Val::Ct(c) if cp::float_from_int_literal(i64::try_from(c).is_ok() || u64::try_from(c).is_ok(), to.bits()) == cp::ROUND => { + Expr { ty: Ty::I64, kind: ExprKind::Const(c) } + } Val::Ct(c) => return Ok(Val::E(self.coerce(Val::Ct(c), to)?)), Val::E(e) if e.ty.is_int() => e, v => { @@ -5464,7 +5942,43 @@ impl<'a> Lower<'a> { Ok(Val::E(e)) } - /// `x == v` / `x != v` with `x` a `?T` (`T` a scalar) and `v` a `T`, + /// `a == b` / `a != b` between pointers and optional pointers: their addresses, null being 0, each operand + /// pinned once in source order (plan `ptr_eq_plan.t27`, #7742). None where the plan leaves it alone. + fn ptr_compare(&mut self, op: &str, a: &Val, b: &Val) -> R> { + let kind = |v: &Val| match v { + Val::P(_, LTy::Ptr(t, _)) => (pe::K_PTR, Some(t.clone())), + Val::M(Place { ty: LTy::Opt(o), .. }) => match &**o { + LTy::Ptr(t, _) => (pe::K_OPT_PTR, Some(t.clone())), + _ => (pe::K_OTHER, None), + }, + _ => (pe::K_OTHER, None), + }; + let ((ka, ta), (kb, tb)) = (kind(a), kind(b)); + if !pe::compares(op == "==" || op == "!=", ka, kb, ta == tb) { return Ok(None); } + let mut stmts = Vec::new(); + let (x, y) = (self.ptr_word(a, &mut stmts)?, self.ptr_word(b, &mut stmts)?); + let cmp = Expr { ty: Ty::Bool, kind: ExprKind::Cmp { op: if op == "==" { CmpOp::Eq } else { CmpOp::Ne }, lhs: Box::new(x), rhs: Box::new(y) } }; + Ok(Some(Val::E(Expr { ty: Ty::Bool, kind: ExprKind::Seq { stmts, value: Box::new(cmp) } }))) + } + + /// The address pointer or optional pointer `v` holds (0 for null), stored in a fresh slot by `stmts`. + fn ptr_word(&mut self, v: &Val, stmts: &mut Vec) -> R { + let k = self.new_slot(<y::S(Ty::U64))?; + let load = |addr: Expr, ty, off| Expr { ty, kind: ExprKind::Load { addr: Box::new(addr), off } }; + let value = match v { + Val::P(e, _) => e.clone(), + Val::M(p) => { + stmts.push(Stmt::Store { addr: slot_expr(k), off: 0, value: addr_of(p) }); + let (flag, word) = (load(load(slot_expr(k), Ty::Ptr, 0), Ty::Bool, 8), load(load(slot_expr(k), Ty::Ptr, 0), Ty::Ptr, 0)); + Expr { ty: Ty::Ptr, kind: ExprKind::Select { cond: Box::new(flag), then: Box::new(word), els: Box::new(Expr { ty: Ty::Ptr, kind: ExprKind::Const(0) }) } } + } + _ => return Err(()), + }; + stmts.push(Stmt::Store { addr: slot_expr(k), off: 0, value }); + Ok(load(slot_expr(k), Ty::Ptr, 0)) + } + + /// `x == v` / `x != v` with `x` a `?T` (`T` a scalar or an enum: optional_compare_plan.t27) and `v` a `T`, /// either way round: Zig's comparison of an optional with a payload, /// equal only when `x` holds a value equal to `v`. None when neither /// operand is an optional. @@ -5492,7 +6006,8 @@ impl<'a> Lower<'a> { _ => return self.reject(what, "an optional compared with a value that has effects".into()), } let LTy::Opt(inner) = p.ty.clone() else { unreachable!() }; - if !matches!(*inner, LTy::S(_)) { + let by = oc::payload(match *inner { LTy::S(_) => oc::K_SCALAR, LTy::Enum(..) => oc::K_ENUM, _ => oc::K_OTHER }); + if oc::refuses(by) { let t = self.type_name(&p.ty); return self.reject(what, format!("`{}` on {}", op, t)); } @@ -5508,7 +6023,7 @@ impl<'a> Lower<'a> { let flag = Expr { ty: Ty::Bool, kind: ExprKind::Load { addr: Box::new(addr.clone()), off: off + s } }; let payload = self.place_value(Place { addr, off, ty: *inner, mutable: false, temp: None })?; let (l, r) = if left { (payload, other) } else { (other, payload) }; - let cmp = self.binary(op, l, r)?; + let cmp = if by == oc::BY_TAG { self.enum_compare(op, &l, &r, false)?.ok_or(())? } else { self.binary(op, l, r)? }; let cmp = self.coerce(cmp, Ty::Bool)?; let els = Expr { ty: Ty::Bool, kind: ExprKind::Const((op == "!=") as i128) }; let e = Expr { ty: Ty::Bool, kind: ExprKind::Select { cond: Box::new(flag), then: Box::new(cmp), els: Box::new(els) } }; @@ -5961,7 +6476,7 @@ impl<'a> Lower<'a> { let sub = field_place(dst, &fields[i]); let v = &c.children[0]; if v.kind == NodeKind::ExprArrayLiteral && matches!(fields[i].ty, LTy::Str | LTy::Slice(..)) { - self.slice_field(n, &sname, v, sub, out)?; + self.slice_lit(sl::AT_FIELD, n.name == sname, v, &sub, out)?; continue; } self.init(v, sub, true, out)?; @@ -5982,45 +6497,6 @@ impl<'a> Lower<'a> { Ok(()) } - /// An array literal for slice field `dst` of struct literal `n`. t27c's - /// Zig backend writes `@constCast(&[_]T{ ... })` when the literal names - /// its struct (otherwise `.{ ... }`, which Zig refuses for a slice). - /// Only the empty literal is taken: its slice has length zero, so where - /// it points is never read. A non-empty one points at a constant in the - /// reference, which outlives any frame t27b could build it in. - fn slice_field(&mut self, n: &Node, sname: &str, v: &Node, dst: Place, out: &mut Vec) -> R<()> { - self.see(v); - if n.name != sname { - return self.reject( - "ExprArrayLiteral(to slice)", - "an array literal for a slice field of an anonymous struct literal (the reference writes `.{ ... }`)".into(), - ); - } - let elem = match &dst.ty { - LTy::Slice(elem, _) => (**elem).clone(), - _ => LTy::S(Ty::U8), - }; - if !(elem == LTy::Str || !has_brackets(&elem)) { - return self.reject( - "ExprArrayLiteral(to slice)", - "an array literal for a slice-of-arrays field (the reference writes `.{ ... }`)".into(), - ); - } - if !v.children.is_empty() || !v.extra_size.trim().is_empty() || !v.extra_type.trim().is_empty() { - return self.reject( - "ExprArrayLiteral(to slice field)", - "a non-empty array literal for a slice field (the reference points into a constant)".into(), - ); - } - let Val::M(arr) = self.struct_temp(v, LTy::Arr(Box::new(elem), 0))? else { - return Err(()); - }; - let Val::M(src) = self.slice_of(addr_of(&arr), 0, dst.ty.clone())? else { - return Err(()); - }; - self.copy(&dst, src, out) - } - /// `dst = src` for a struct: one copy. Both addresses are evaluated, dst /// first, even when there is nothing to copy. fn copy(&mut self, dst: &Place, src: Place, out: &mut Vec) -> R<()> { @@ -6056,6 +6532,14 @@ impl<'a> Lower<'a> { /// The memory an expression names: a variable in memory, a field, or /// `p.*`. fn lvalue(&mut self, n: &Node) -> R { + let was = std::mem::replace(&mut self.writing, true); + let p = self.place_at(n); + self.writing = was; + p + } + + /// `lvalue` once `writing` is set. + fn place_at(&mut self, n: &Node) -> R { self.see(n); match n.kind { NodeKind::ExprIdentifier => match self.lookup(&n.name) { @@ -6112,10 +6596,14 @@ impl<'a> Lower<'a> { (op, _) => return self.reject(&format!("ExprIndex({})", op), "unexpected shape".into()), } let base = self.expr(&n.children[0])?; - let idx = self.expr(&n.children[1])?; + let idx = self.usize_operand(&n.children[1])?; if base.is_poison() || idx.is_poison() { return Err(()); } + if let (NodeKind::ExprIdentifier, true) = (&n.children[0].kind, self.tuple_names.contains(&n.children[0].name)) { + let constant = matches!(&idx, Val::Ct(_) | Val::E(Expr { kind: ExprKind::Const(_), .. })); + if tl::refuses_index(constant, self.comptime, self.unanalyzed_fn) { return self.tuple_refuse(tl::R_LOCAL_INDEX, &[]); } + } // A string literal at a constant index is a constant. if let Val::S(k, len) = base { let c = match &idx { @@ -6206,6 +6694,7 @@ impl<'a> Lower<'a> { /// checked against its length when evaluated, and traps out of range. fn slice_index(&mut self, p: Place, idx: Val) -> R { let (elem, m) = Self::slice_elem(&p.ty); + self.slice_write(&elem, m); let (esize, _) = self.size_align(&elem)?; let mut pin = Vec::new(); let (hdr, off) = self.pin_header(&p, &mut pin)?; @@ -6277,7 +6766,7 @@ impl<'a> Lower<'a> { None }; // S1: the start. - let i = self.expr(start)?; + let i = self.usize_operand(start)?; let i = self.coerce(i, Ty::U64)?; let ci = if let ExprKind::Const(c) = i.kind { Some(c) } else { None }; stmts.push(Stmt::Store { addr: slot_expr(scr), off: 0, value: i }); @@ -6289,7 +6778,7 @@ impl<'a> Lower<'a> { // S2: the end, checked against the length, becomes the length. let mut cj = alen.map(|l| l as i128); if let Some(end) = end { - let j = self.expr(end)?; + let j = self.usize_operand(end)?; let j = self.coerce(j, Ty::U64)?; cj = if let ExprKind::Const(c) = j.kind { Some(c) } else { None }; if let (Some(c), Some(l)) = (cj, alen) { @@ -6458,13 +6947,11 @@ impl<'a> Lower<'a> { /// A module-level struct constant: its bytes in read-only data. fn rodata(&mut self, n: &Node, t: LTy) -> R { - if let Some(lit) = self.expand_repeat(n, &t)? { - return self.rodata(&lit, t); - } // An optional is filled by `const_fill`, which also copies another - // optional constant. + // optional constant, and so is an array repeat. let opt = matches!(t, LTy::Opt(_)); - if !opt && n.kind != NodeKind::ExprStructLit && n.kind != NodeKind::ExprArrayLiteral { + let repeat = is_repeat_op(n) && matches!(t, LTy::Arr(..)); + if !opt && !repeat && n.kind != NodeKind::ExprStructLit && n.kind != NodeKind::ExprArrayLiteral { let v = self.expr_as(n, &t)?; return match v { Val::M(p) if matches!(p.addr.kind, ExprKind::Data(_)) => Ok(Val::M(p)), @@ -6674,28 +7161,13 @@ impl<'a> Lower<'a> { if txt.contains('{') || txt.contains("][") { return self.reject("ExprArrayLiteral(text form)", format!("`[{}]`: elements kept as text", txt)); } - let mut parts = Vec::new(); - let (mut depth, mut cur) = (0i32, String::new()); - for ch in txt.chars() { - match ch { - '(' | '[' => depth += 1, - ')' | ']' => depth -= 1, - _ => {} - } - if ch == ',' && depth == 0 { - parts.push(std::mem::take(&mut cur)); - } else { - cur.push(ch); - } - } - if !cur.trim().is_empty() { - parts.push(cur); - } - let mut lit = Node::new(NodeKind::ExprArrayLiteral); + let (mut lit, mut at) = (Node::new(NodeKind::ExprArrayLiteral), 0); lit.line = n.line; - for p in parts { - let e = self.text_elem(p.trim(), txt)?; - lit.children.push(e); + while at <= txt.len() { + let end = st::part_end(txt.as_bytes(), at); + let p = txt[at..end].trim(); + if end < txt.len() || !p.is_empty() { lit.children.push(self.text_elem(p, txt)?); } + at = end + 1; } Ok(Some(lit)) } @@ -6757,8 +7229,8 @@ impl<'a> Lower<'a> { Ok(()) } - /// The literal `n` for array type `t` with a repeat written out, for the - /// compile-time paths, which evaluate every element anyway. + /// The literal `n` for array type `t` with a repeat written out, for + /// `const_agg`, which keeps one value per element anyway. fn expand_repeat(&mut self, n: &Node, t: <y) -> R> { if !matches!(t, LTy::Arr(..)) { return Ok(None); @@ -6780,8 +7252,23 @@ impl<'a> Lower<'a> { fn const_fill(&mut self, n: &Node, t: <y, buf: &mut [u8], off: usize) -> R<()> { self.see(n); - if let Some(lit) = self.expand_repeat(n, t)? { - return self.const_fill(&lit, t, buf, off); + if let LTy::Arr(elem, _) = t { + if let Some(lit) = self.text_lit(n)? { + return self.const_fill(&lit, t, buf, off); + } + // A repeat: its elements once, then those bytes copied over the + // rest, so a module var of any size needs no expanded node list. + if let Some((elems, count)) = self.repeat_lit(n, t)? { + let (esize, _) = self.size_align(elem)?; + for (i, c) in elems.iter().enumerate() { + self.const_fill(c, elem, buf, off + i * esize as usize)?; + } + let period = elems.len() * esize as usize; + for k in 1..count as usize { + buf.copy_within(off..off + period, off + k * period); + } + return Ok(()); + } } if is_undefined(n) { return Ok(()); @@ -6889,25 +7376,6 @@ impl<'a> Lower<'a> { } } -/// The register type of a scalar or pointer; None for a struct. -/// The byte index of the `]` that closes the `[` at index 0 of `t`. -fn close_of_open(t: &str) -> Option { - let mut depth = 0i32; - for (i, c) in t.char_indices() { - match c { - '[' => depth += 1, - ']' => { - depth -= 1; - if depth == 0 { - return Some(i); - } - } - _ => {} - } - } - None -} - /// Whether `t` spells a `[` in Zig: an array, a slice, a string, or a /// pointer to one. fn has_brackets(t: <y) -> bool { @@ -6918,7 +7386,9 @@ fn has_brackets(t: <y) -> bool { } } -/// Elements a constant repeat may expand to. +/// Elements a constant repeat may expand to as a node list (`const_agg`, +/// constants holding strings). Byte-filled constants and module vars +/// (`const_fill`) copy the repeated bytes instead and have no such limit. const MAX_CONST_REPEAT: u64 = 1 << 16; /// `[_]T{ ... } ** n`, which the parser builds as a `**` binary node. @@ -7031,75 +7501,59 @@ fn zero_lines(n: &mut Node) { /// Names a statement list binds to an array literal (`collect_array_locals` /// in t27c). fn array_locals(ns: &[Node], out: &mut HashSet) { - for n in ns { - if matches!(n.kind, NodeKind::StmtLocal | NodeKind::StmtAssign) - && !n.name.is_empty() - && n.children.first().is_some_and(|c| c.kind == NodeKind::ExprArrayLiteral) - { - out.insert(n.name.clone()); - } - array_locals(&n.children, out); - } + out.extend(marked(ns, ax::array_locals).map(|n| n.name.clone())); } /// The local declarations of `name` under `ns`, at every nesting level. fn decls_of<'n>(ns: &'n [Node], name: &str, out: &mut Vec<&'n Node>) { - for n in ns { - if matches!(n.kind, NodeKind::StmtLocal | NodeKind::StmtAssign) && n.name == name { - out.push(n); - } - decls_of(&n.children, name, out); - } + out.extend(marked(ns, |a, t, m| ax::decls_of(a, t, name.as_bytes(), m))); +} + +/// `ns` as specs/tri/t27b/ast_walk.t27 reads it: a record per node in preorder, then the fields' text. +fn flat(ns: &[Node]) -> (Vec, Vec) { + fn put(n: &Node, a: &mut Vec, t: &mut Vec) { + let at = a.len(); + a.extend_from_slice(&[n.kind.clone() as u8, 0, 0, 0, 0, 0, 0, 0]); + for f in [&n.name, &n.value, &n.extra_type, &n.extra_field, &n.extra_size, &n.extra_kind, &n.extra_op, &n.extra_return_type] { + a.extend_from_slice(&(t.len() as u32).to_le_bytes()); + t.extend_from_slice(f.as_bytes()); + a.extend_from_slice(&(t.len() as u32).to_le_bytes()); + } + n.children.iter().for_each(|c| put(c, a, t)); + let end = (a.len() / aw::REC) as u32; + a[at + 4..at + 8].copy_from_slice(&end.to_le_bytes()); + } + let (mut a, mut t) = (Vec::new(), Vec::new()); + ns.iter().for_each(|n| put(n, &mut a, &mut t)); + (a, t) +} +const _: () = assert!(NodeKind::StmtExpr as u8 == aw::K_STMT_EXPR && NodeKind::ExprRange as u8 == aw::K_EXPR_RANGE); +/// The nodes of `ns` in preorder that `scan`, a fn of specs/tri/t27b/ast_scan.t27, marks. +fn marked<'n>(ns: &'n [Node], scan: impl Fn(&[u8], &[u8], &mut [u8])) -> impl Iterator { + fn pre<'n>(ns: &'n [Node], v: &mut Vec<&'n Node>) { ns.iter().for_each(|n| { v.push(n); pre(&n.children, v) }) } + let ((a, t), mut v) = (flat(ns), Vec::new()); + let mut m = vec![0u8; a.len() / aw::REC]; + scan(&a, &t, &mut m); + pre(ns, &mut v); + v.into_iter().zip(m).filter(|p| p.1 == ax::MARK).map(|p| p.0) } /// How many nodes under `ns` carry `name` (or a dotted path starting with /// it) as their name, of any kind: an over-count of its uses. fn name_count(ns: &[Node], name: &str) -> usize { - ns.iter() - .map(|n| { - let hit = n.name == name || n.name.strip_prefix(name).is_some_and(|r| r.starts_with('.')); - hit as usize + name_count(&n.children, name) - }) - .sum() + let (a, t) = flat(ns); aw::name_count(&a, &t, name.as_bytes()) } /// `name_count`, plus each node whose type or size text names `name` as a /// word (array literal elements and array sizes are kept as text): an /// over-count of its mentions. fn name_mentions(ns: &[Node], name: &str) -> usize { - fn word_in(text: &str, name: &str) -> bool { - let b = text.as_bytes(); - let id = |c: u8| c.is_ascii_alphanumeric() || c == b'_'; - text.match_indices(name).any(|(i, _)| { - let e = i + name.len(); - (i == 0 || !id(b[i - 1])) && (e >= b.len() || !id(b[e])) - }) - } - ns.iter() - .map(|n| { - let hit = n.name == name || n.name.strip_prefix(name).is_some_and(|r| r.starts_with('.')); - let text = [&n.extra_size, &n.extra_type, &n.extra_field, &n.extra_return_type] - .iter() - .any(|t| word_in(t, name)); - hit as usize + text as usize + name_mentions(&n.children, name) - }) - .sum() + let (a, t) = flat(ns); aw::name_mentions(&a, &t, name.as_bytes()) } /// How many `_ = name;` statements lie under `ns`, at any depth. fn discard_count(ns: &[Node], name: &str) -> usize { - ns.iter() - .map(|n| { - let hit = n.kind == NodeKind::StmtAssign - && matches!(n.extra_op.as_str(), "" | "=") - && n.children.len() == 2 - && n.children[0].kind == NodeKind::ExprIdentifier - && n.children[0].name == "_" - && n.children[1].kind == NodeKind::ExprIdentifier - && n.children[1].name == name; - hit as usize + discard_count(&n.children, name) - }) - .sum() + let (a, t) = flat(ns); aw::discard_count(&a, &t, name.as_bytes()) } /// An array literal whose elements are all plain literals (a negated one @@ -7121,12 +7575,7 @@ fn plain_lit(n: &Node) -> bool { } fn calls_in<'n>(ns: &'n [Node], out: &mut Vec<&'n Node>) { - for n in ns { - if n.kind == NodeKind::ExprCall { - out.push(n); - } - calls_in(&n.children, out); - } + out.extend(marked(ns, ax::calls)); } fn reg_ty(t: <y) -> Option { @@ -7230,6 +7679,17 @@ fn val_of(e: Expr, t: <y) -> Val { } } +/// A lowered operand of `@abs` / `@max` / `@min`, as builtin_plan.t27's `type_from` takes it. +fn operand_kind(v: Option<&Val>) -> u8 { + match v { + Some(Val::E(e)) if e.ty.is_float() => bp::K_FLOAT, + Some(Val::E(e)) if e.ty.is_int() => bp::K_INT, + Some(Val::Cf(_)) => bp::K_CF, + Some(Val::Ct(_)) => bp::K_CT, + _ => bp::K_OTHER, + } +} + fn slot_expr(k: u32) -> Expr { Expr { ty: Ty::Ptr, kind: ExprKind::Slot(k) } } @@ -7262,16 +7722,7 @@ fn is_undefined(n: &Node) -> bool { /// Names whose address is taken (`&name`) anywhere in a body. fn scan_addr_taken(ns: &[Node], out: &mut HashSet) { - for n in ns { - if n.kind == NodeKind::ExprUnary && n.extra_op == "&" { - if let Some(c) = n.children.first() { - if c.kind == NodeKind::ExprIdentifier { - out.insert(c.name.clone()); - } - } - } - scan_addr_taken(&n.children, out); - } + out.extend(marked(ns, ax::addr_taken).map(|n| n.name.clone())); } /// Count plain assignments per identifier in a test body (all nesting levels). @@ -7280,12 +7731,7 @@ fn scan_addr_taken(ns: &[Node], out: &mut HashSet) { /// over-approximation of what it references, so a fn left out of /// `analyzed_fns` is one Zig cannot reach. fn names_in(ns: &[Node], out: &mut HashSet) { - for n in ns { - if !n.name.is_empty() { - out.insert(n.name.clone()); - } - names_in(&n.children, out); - } + out.extend(marked(ns, ax::named).map(|n| n.name.clone())); } /// Collect the `if` expressions the reference prints unparenthesized where the @@ -7296,55 +7742,13 @@ fn names_in(ns: &[Node], out: &mut HashSet) { /// `ExprFieldAccess` named `f` holding the value, printed as `.f = ,`, /// and the comma ends the `if`. fn misprinted_ifs(n: &Node, out: &mut HashSet) { - if matches!(n.kind, NodeKind::ExprBinary | NodeKind::ExprFieldAccess | NodeKind::ExprIndex) { - if let Some(c) = n.children.first() { - if c.kind == NodeKind::ExprIf { - out.insert(c as *const Node as usize); - } - } - } - for c in &n.children { - if n.kind == NodeKind::ExprStructLit && c.kind == NodeKind::ExprFieldAccess { - for v in &c.children { - misprinted_ifs(v, out); - } - } else { - misprinted_ifs(c, out); - } - } -} - -/// `m::GF16` / `a::b::gf16`: a module path whose last segment is GF16. -fn is_scoped_gf16(t: &str) -> bool { - let segs: Vec<&str> = t.split("::").collect(); - segs.len() > 1 - && matches!(segs[segs.len() - 1], "GF16" | "gf16") - && segs.iter().all(|s| { - s.chars().next().is_some_and(|c| c.is_ascii_alphabetic() || c == '_') - && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') - }) + out.extend(marked(std::slice::from_ref(n), ax::misprinted_ifs).map(|c| c as *const Node as usize)); } /// The node kinds t27c's `gen_expr` prints anything for; every other kind (a /// statement) renders as the empty string. fn zig_renders(k: &NodeKind) -> bool { - matches!( - k, - NodeKind::ExprLiteral - | NodeKind::ExprIdentifier - | NodeKind::ExprEnumValue - | NodeKind::ExprCall - | NodeKind::ExprBinary - | NodeKind::ExprUnary - | NodeKind::ExprFieldAccess - | NodeKind::ExprIndex - | NodeKind::ExprSwitch - | NodeKind::ExprIf - | NodeKind::ExprArrayLiteral - | NodeKind::ExprStructLit - | NodeKind::ExprCast - | NodeKind::ExprTuple - ) + aw::renders(k.clone() as u8) } /// Collect the `*` expressions t27c's strength reduction rewrites as `<<` @@ -7409,93 +7813,61 @@ fn analyzed_fns(items: &[&Node]) -> HashSet { reached } -/// A return type that is a value (t27c `call_returns_value` and the test -/// in `gen_fn_decl` before `zig_tail_returns`): anything but none, `void`, -/// `noreturn` and `()`. -fn returns_value(rt: &str) -> bool { - !matches!(rt.trim(), "" | "void" | "noreturn" | "()") -} - /// #6315, t27c `zig_tail_returns`: the reference turns the last statement of /// a non-void fn body into a `return` when it is an expression statement /// other than `return` and the action calls `assert`, `assert_eq`, `panic`, /// `unreachable`, `print` and `println`, and through an if/else that is last, /// the last statement of each branch. Marks those statements by address. fn mark_tail_returns(ns: &[Node], out: &mut HashSet) { - let Some(last) = ns.last() else { return }; - match last.kind { - NodeKind::StmtExpr if last.children.len() == 1 => { - let e = &last.children[0]; - let action = match e.kind { - NodeKind::ExprReturn => true, - NodeKind::ExprCall => { - matches!(e.name.as_str(), "assert" | "assert_eq" | "panic" | "unreachable" | "print" | "println") - } - _ => false, - }; - if !action { - out.insert(last as *const Node as usize); - } - } - NodeKind::StmtIf if last.children.len() == 3 => { - mark_tail_returns(&last.children[1].children, out); - mark_tail_returns(&last.children[2].children, out); - } - _ => {} - } + out.extend(marked(ns, ax::tail_returns).map(|c| c as *const Node as usize)); } /// An expression whose value Zig refuses to drop when it is a statement /// (`value of type ... ignored`). Calls, `return`, `try`, `if`, `switch` and /// `undefined` have their own rules and are not in this set. fn is_value_stmt(c: &Node) -> bool { - match c.kind { - NodeKind::ExprBinary - | NodeKind::ExprLiteral - | NodeKind::ExprCast - | NodeKind::ExprFieldAccess - | NodeKind::ExprIndex - | NodeKind::ExprStructLit - | NodeKind::ExprArrayLiteral => true, - NodeKind::ExprIdentifier => c.name != "undefined", - _ => false, - } + aw::value_stmt(c.kind.clone() as u8, c.name.as_bytes()) +} + +/// Parameter `p: t` of fn `f` is `anytype` and `f`'s body never names it (specs/tri/t27b/any_param_plan.t27). +fn unread_any(f: &Node, p: &str, t: &str) -> bool { + ap::param(ls::is_anytype(t.trim().as_bytes()), name_mentions(&f.children, p.trim()) > 0) == ap::VOID_PARAM } fn mentions(ns: &[Node], name: &str) -> bool { - ns.iter().any(|n| (n.kind == NodeKind::ExprIdentifier && n.name == name) || mentions(&n.children, name)) + let (a, t) = flat(ns); aw::mentions(&a, &t, name.as_bytes()) +} + +/// The module `var`s a top-level local of `body` may shadow: the reference's +/// `_lv` rename of every mention in the body agrees with t27 scoping +/// when the declaration is top-level, the body's only one of the name, and +/// nothing before it (its own initializer included) mentions the name. +fn shadow_names(body: &[Node], mod_vars: &HashMap) -> HashSet { + fn decls(ns: &[Node], name: &str) -> usize { + let (a, t) = flat(ns); aw::decl_count(&a, &t, name.as_bytes()) + } + let mut ok = HashSet::new(); + for (i, s) in body.iter().enumerate() { + if s.kind == NodeKind::StmtLocal + && mod_vars.contains_key(&s.name) + && !mentions(&body[..i], &s.name) + && !mentions(&s.children, &s.name) + && decls(body, &s.name) == 1 + { + ok.insert(s.name.clone()); + } + } + ok } /// The reference's `collect_mutable_names`: is `name` the target (or the base /// of an indexed or field target) of an assignment in `ns`? fn mutated(ns: &[Node], name: &str) -> bool { - ns.iter().any(|n| { - if n.kind == NodeKind::StmtAssign { - if let Some(t) = n.children.first() { - let base = match t.kind { - NodeKind::ExprIndex | NodeKind::ExprFieldAccess => t.children.first(), - _ => Some(t), - }; - if base.is_some_and(|b| b.kind == NodeKind::ExprIdentifier && b.name == name) { - return true; - } - } - } - mutated(&n.children, name) - }) + let (a, t) = flat(ns); aw::mutated(&a, &t, name.as_bytes()) } fn count_assigns(ns: &[Node], counts: &mut HashMap) { - for n in ns { - if n.kind == NodeKind::StmtAssign { - if let Some(t) = n.children.first() { - if t.kind == NodeKind::ExprIdentifier { - *counts.entry(t.name.clone()).or_insert(0) += 1; - } - } - } - count_assigns(&n.children, counts); - } + marked(ns, ax::assign_targets).for_each(|n| *counts.entry(n.name.clone()).or_insert(0) += 1); } /// A clause the front-end kept only as verbatim text: a childless StmtExpr @@ -7503,9 +7875,7 @@ fn count_assigns(ns: &[Node], counts: &mut HashMap) { fn is_prose_clause(n: &Node) -> bool { n.kind == NodeKind::StmtExpr && n.children.is_empty() - && n.name.len() > 1 - && n.name.ends_with(':') - && n.name[..n.name.len() - 1].chars().all(|c| c.is_ascii_alphanumeric() || c == '_') + && st::prose_label(n.name.as_bytes()) } // ------------------------------------------------- reference-path defects @@ -7516,78 +7886,9 @@ fn is_prose_clause(n: &Node) -> bool { /// declaration. Returns the offending base name. Anything else (dotted or /// scoped paths, `@This()`, function types) is left alone. fn undeclared_field_type(ty: &str, declared: &HashSet<&str>) -> Option { - let base = type_base(ty)?; - if base.is_empty() { - return None; - } - if base.contains('<') { - return Some(base.to_string()); - } - let ident = base.chars().next().is_some_and(|c| c.is_ascii_alphabetic() || c == '_') - && base.chars().all(|c| c.is_ascii_alphanumeric() || c == '_'); - if !ident || declared.contains(base) || zig_type_name(base) { - return None; - } - if matches!(base, "str" | "string" | "float" | "double" | "int" | "uint" | "GF16" | "gf16") { - return None; - } - Some(base.to_string()) -} - -/// The element name under `?`, `&`, `*`, `const`, and the array and slice -/// forms of both t27 (`[T]`, `[T; N]`) and Zig (`[]T`, `[N]T`). `None` for a -/// map type `[K:V]`, which is not a name. -fn type_base(ty: &str) -> Option<&str> { - let t = ty.trim(); - if let Some(r) = t.strip_prefix('?').or_else(|| t.strip_prefix('&')).or_else(|| t.strip_prefix('*')) { - return type_base(r); - } - if let Some(r) = t.strip_prefix("const ") { - return type_base(r); - } - if t.starts_with('[') { - let mut depth = 0i32; - let mut close = None; - for (i, c) in t.char_indices() { - match c { - '[' => depth += 1, - ']' => { - depth -= 1; - if depth == 0 { - close = Some(i); - break; - } - } - _ => {} - } - } - let close = close?; - if close == t.len() - 1 { - let inner = &t[1..close]; - if inner.contains(':') { - return None; - } - let elem = match inner.rfind(';') { - Some(s) => &inner[..s], - None => inner, - }; - return type_base(elem); - } - return type_base(&t[close + 1..]); - } - Some(t) -} - -/// A type name Zig declares itself. -fn zig_type_name(n: &str) -> bool { - matches!( - n, - "bool" | "void" | "type" | "anyerror" | "anyframe" | "anyopaque" | "noreturn" | "usize" | "isize" - | "comptime_int" | "comptime_float" | "c_char" | "c_short" | "c_ushort" | "c_int" | "c_uint" - | "c_long" | "c_ulong" | "c_longlong" | "c_ulonglong" | "c_longdouble" - ) || (n.len() >= 2 - && (n.starts_with('u') || n.starts_with('i') || n.starts_with('f')) - && n[1..].chars().all(|c| c.is_ascii_digit())) + let r = tt::type_base(ty.as_bytes()); + let base = (r >= 0).then(|| &ty[(r / tt::HALF) as usize..(r % tt::HALF) as usize])?; + tt::undeclared(base.as_bytes(), declared.contains(base)).then(|| base.to_string()) } /// t27c's Zig backend writes every `_cse*` temporary the optimizer made at @@ -7627,56 +7928,14 @@ fn cse_hoist_defect(f: &Node) -> Option { /// are a name, or whose immediate base (index or field) is one, looking into /// `if`/`while`/`for` bodies and nowhere else. fn ref_mutable_names(ns: &[Node], out: &mut HashSet) { - for n in ns { - match n.kind { - NodeKind::StmtAssign if !n.children.is_empty() => { - let t = &n.children[0]; - if t.kind == NodeKind::ExprIdentifier { - out.insert(t.name.clone()); - } - if matches!(t.kind, NodeKind::ExprIndex | NodeKind::ExprFieldAccess) { - if let Some(b) = t.children.first() { - if b.kind == NodeKind::ExprIdentifier { - out.insert(b.name.clone()); - } - } - } - } - NodeKind::StmtIf | NodeKind::StmtWhile | NodeKind::StmtFor | NodeKind::StmtForRange => { - for c in &n.children { - if c.kind == NodeKind::Module { - ref_mutable_names(&c.children, out); - } else { - ref_mutable_names(std::slice::from_ref(c), out); - } - } - } - _ => {} - } - } + out.extend(marked(ns, ax::mutable_names).map(|n| n.name.clone())); } /// Does Zig count `var name` as mutated anywhere in `ns`? An assignment whose /// target reaches `name` through fields and indexes but no `.*`, `&` of such /// a path, or a method call on it. Errs toward yes: a yes refuses nothing. fn zig_mutates(ns: &[Node], name: &str) -> bool { - fn rooted(t: &Node, name: &str) -> bool { - match t.kind { - NodeKind::ExprIdentifier => t.name == name, - NodeKind::ExprFieldAccess if t.name == "*" => false, - NodeKind::ExprFieldAccess | NodeKind::ExprIndex => t.children.first().is_some_and(|b| rooted(b, name)), - _ => false, - } - } - ns.iter().any(|n| { - let hit = match n.kind { - NodeKind::StmtAssign => n.children.first().is_some_and(|t| rooted(t, name)), - NodeKind::ExprUnary if n.extra_op == "&" => n.children.first().is_some_and(|t| rooted(t, name)), - NodeKind::ExprCall => n.name.split('.').next() == Some(name) && n.name.contains('.'), - _ => false, - }; - hit || zig_mutates(&n.children, name) - }) + let (a, t) = flat(ns); aw::zig_mutates(&a, &t, name.as_bytes()) } /// Syntax the reference prints that Zig cannot parse: a childless typed @@ -7707,3 +7966,28 @@ fn zig_syntax_defects(ns: &[Node], line: u32, found: &mut Vec<(u32, &'static str zig_syntax_defects(&n.children, at, found); } } + +/// `x.len()` and `len(x)` lower as the length FIELD, as t27c's Zig backend +/// prints both (W570; Zig has no `len` method on a slice or an array). Which +/// call stands for which receiver is decided by the `lencall` module above; +/// this only builds the field access it names. +impl<'a> Lower<'a> { + fn len_call(&mut self, c: &Node) -> R> { + let declared = self.sigs.contains_key("len") || self.poison_names.contains("len"); + let recv = match lencall::receiver(c.extra_kind == "method", c.children.len(), c.name.as_bytes().to_vec(), declared) { + lencall::RECV_CHILD => c.children[0].clone(), + lencall::RECV_PATH => { + let mut segs = c.name[..c.name.len() - 4].split('.'); + let first = segs.next().unwrap_or_default(); + let mut n = Node { kind: NodeKind::ExprIdentifier, name: first.into(), line: c.line, ..Node::default() }; + for s in segs { + n = Node { kind: NodeKind::ExprFieldAccess, name: s.into(), line: c.line, children: vec![n], ..Node::default() }; + } + n + } + _ => return Ok(None), + }; + let field = Node { kind: NodeKind::ExprFieldAccess, name: "len".into(), line: c.line, children: vec![recv], ..Node::default() }; + self.expr(&field).map(Some) + } +} diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index abe3812d2b..200691a74d 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -2,9 +2,9 @@ "schema_version": 1, "generated_by": "tri t27b ratchet --bless (scripts/tri_loop/t27b.py), #6115", "source": { - "commit": "606611ced01f3970553dced70e1a2547ab8fb383", + "commit": "285512a21d361f18ff88412af017869dd64c65c1", "ref": "master", - "finished": "2026-10-10T02:49:52Z", + "finished": "2026-10-10T08:10:15Z", "asserts_counted": true }, "reasons": { @@ -12,7 +12,7 @@ "reference-bug": "the reference passes it for the wrong reason; t27b is right not to", "n/a": "outside what t27b is for (say why in the PR that sets it)" }, - "max_not_pass": 22, + "max_not_pass": 23, "entries": [ {"path": "specs/a/b_c.t27", "t27b": "pass_vacuous"}, {"path": "specs/a_b/c.t27", "t27b": "pass_vacuous"}, @@ -38,11 +38,11 @@ {"path": "specs/agents/t.t27", "t27b": "pass"}, {"path": "specs/agents/ti.t27", "t27b": "pass"}, {"path": "specs/agents/u.t27", "t27b": "pass"}, - {"path": "specs/agents/v.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/w.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/x.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/y.t27", "t27b": "pass_vacuous"}, - {"path": "specs/agents/z.t27", "t27b": "pass_vacuous"}, + {"path": "specs/agents/v.t27", "t27b": "pass"}, + {"path": "specs/agents/w.t27", "t27b": "pass"}, + {"path": "specs/agents/x.t27", "t27b": "pass"}, + {"path": "specs/agents/y.t27", "t27b": "pass"}, + {"path": "specs/agents/z.t27", "t27b": "pass"}, {"path": "specs/api/c_abi.t27", "t27b": "pass"}, {"path": "specs/api/tri_api_context.t27", "t27b": "pass"}, {"path": "specs/api/tri_api_loop.t27", "t27b": "pass"}, @@ -259,7 +259,7 @@ {"path": "specs/docs/chapters/queen.t27", "t27b": "pass"}, {"path": "specs/docs/chapters/rules.t27", "t27b": "pass"}, {"path": "specs/docs/chapters/tooling.t27", "t27b": "pass"}, - {"path": "specs/docs/system.t27", "t27b": "pass_vacuous"}, + {"path": "specs/docs/system.t27", "t27b": "pass"}, {"path": "specs/fpga/adapter.t27", "t27b": "pass"}, {"path": "specs/fpga/assembler.t27", "t27b": "pass"}, {"path": "specs/fpga/boards/arty_a7_integration.t27", "t27b": "pass"}, @@ -759,6 +759,7 @@ {"path": "specs/port/trios/crates/trios-bridge/src/main.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-01/src/key_package_expiry_guard.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-02/src/epoch_rollover_wraparound_guard.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-03/src/ratchet_tree_resolution_guard.t27", "t27b": "blocked", "blocker": "ExprArrayLiteral", "reason": "unimplemented"}, {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_decoy_ratio_governor.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-LAWS/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/agent.t27", "t27b": "pass"}, diff --git a/tools/policy/foreign-exceptions.txt b/tools/policy/foreign-exceptions.txt index ddb175476e..b44a7efa2f 100644 --- a/tools/policy/foreign-exceptions.txt +++ b/tools/policy/foreign-exceptions.txt @@ -30,6 +30,7 @@ cli/t27b/src/codegen.rs # The fixture is specs/tri/t27b/conformance/shadow_module_var.t27. cli/t27b/src/lower.rs cli/t27b/tests/source.rs + # owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), epic #6063, # issue #7368: t27b coverage lane 3 -- integer types of every width 1..31 (`type u1`, i2, u4, u21) are held # like a u8 and checked against their own range. Conformance spec first: @@ -425,7 +426,6 @@ tools/queen/criteria_backfill.py # (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. cli/t27b/src/lower.rs cli/t27b/tests/source.rs -======= # owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7415: # t27b reads the postfix optional `T?` as t27c's type mapper writes it, `?T` (the parser keeps the suffix only # on a struct field's type). The behaviour is pinned by specs/tri/t27b/conformance/postfix_optional.t27. From 5d0fa6b97dc5178c6efacd5fe9553d10ef336f41 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sat, 10 Oct 2026 18:41:52 +0700 Subject: [PATCH 08/10] sync: move the lane's source.rs tests and exception block off master's append points Both files are appended to by master at the same tail the lane added to, which is what makes update-branch refuse. The lane's additions move into regions master has not touched since the merge base, so the server-side merge combines them cleanly. Content is unchanged, only position. Co-Authored-By: Claude Opus 5.5 (1M context) --- cli/t27b/tests/source.rs | 198 ++++++++++++++-------------- tools/policy/foreign-exceptions.txt | 15 +-- 2 files changed, 107 insertions(+), 106 deletions(-) diff --git a/cli/t27b/tests/source.rs b/cli/t27b/tests/source.rs index 164f4b5fe9..882ced5640 100644 --- a/cli/t27b/tests/source.rs +++ b/cli/t27b/tests/source.rs @@ -2953,6 +2953,106 @@ fn parameter_discard_rejections() { } } +// ------------------------------------------------------------ array length expressions + +/// An array length spelled as an expression (`[W+1]u8`, `[(W+1)*2]u16`) is +/// folded at compile time, as Zig folds the text t27c prints: an untyped +/// constant is a comptime_int, a typed one keeps its type. +#[test] +fn array_length_expression_folds() { + let src = "module a; + +const W = 4; +const H: u32 = 3; +const AREA = W * H; + +fn total(xs: [W * H]u32) -> u32 { + var s: u32 = 0; + for (xs) |x| { + s = s + x; + } + return s; +} + +test ok { + var a: [W + 1]u8 = undefined; + a[0] = 1; + assert(a.len == 5); + var c: [(W + 1) * 2]u16 = undefined; + c[9] = 3; + assert(c.len == 10); + var d: [H * 2]u64 = undefined; + d[5] = 1; + assert(d.len == 6); + var b: [AREA - 2]u8 = undefined; + b[0] = 1; + assert(b.len == 10); + var r: [W * H]u32 = undefined; + for (0..r.len) |i| { + r[i] = 2; + } + assert(total(r) == 24); +} + +test fails { + var a: [W - 1]u8 = undefined; + a[0] = 1; + assert(a.len == 4); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("ok", false, true), ("fails", false, false)]); +} + +/// A length that is negative, reads a run-time value or calls a fn is +/// refused as `type [N]T`; one that overflows its typed constant is refused +/// by the fold. Zig refuses all but the call. +#[test] +fn array_length_expression_rejections() { + let cases: &[(&str, bool)] = &[ + ("const W = 4;\nfn f() -> u32 {\n var a: [W - 5]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), + ("fn f() -> u32 {\n var n: u32 = 3;\n n = n + 1;\n var a: [n + 1]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), + ("fn g(x: u32) -> u32 {\n return x;\n}\nfn f() -> u32 {\n var a: [g(2) + 1]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), + ("const H: u8 = 200;\nfn f() -> u32 {\n var a: [H + 100]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", false), + ]; + for (body, len) in cases { + let m = rejected(&format!("module a;\n\n{}\ntest t {{\n assert(f() == 1);\n}}\n", body)); + let want = if *len { "t27b: unsupported construct type [N]T at line" } else { "t27b: unsupported construct" }; + assert!(m.starts_with(want), "{}: {}", body, m); + } +} + +/// A module const built from typed constants is folded as Zig folds it at +/// compile time: a checked step out of range is refused, `+%` wraps. +#[test] +fn typed_constant_arithmetic_folds() { + let src = "module a; + +const H: u32 = 3; +const A = H * 5; +const Q: u8 = 250; +const R = Q +% 10; + +fn next() -> u32 { + var x: u32 = A; + x = x + 1; + return x; +} + +test ok { + assert(next() == 16); + assert(R == 4); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("ok", false, true)]); + let m = rejected("module a;\n\nconst B: u8 = 200;\nconst OV = B + 100;\n\ntest t {\n assert(OV == 44);\n}\n"); + assert!(m.starts_with("t27b: unsupported construct ConstDecl at line"), "{}", m); + assert!(m.contains("`OV` overflows u8"), "{}", m); +} + + + // ------------------------------------------------------------- type alias /// `const Name = T;` with no annotation, where `T` spells a type, is a Zig @@ -3092,104 +3192,6 @@ fn bare_abs_rejections() { } } -// ------------------------------------------------------------ array length expressions - -/// An array length spelled as an expression (`[W+1]u8`, `[(W+1)*2]u16`) is -/// folded at compile time, as Zig folds the text t27c prints: an untyped -/// constant is a comptime_int, a typed one keeps its type. -#[test] -fn array_length_expression_folds() { - let src = "module a; - -const W = 4; -const H: u32 = 3; -const AREA = W * H; - -fn total(xs: [W * H]u32) -> u32 { - var s: u32 = 0; - for (xs) |x| { - s = s + x; - } - return s; -} - -test ok { - var a: [W + 1]u8 = undefined; - a[0] = 1; - assert(a.len == 5); - var c: [(W + 1) * 2]u16 = undefined; - c[9] = 3; - assert(c.len == 10); - var d: [H * 2]u64 = undefined; - d[5] = 1; - assert(d.len == 6); - var b: [AREA - 2]u8 = undefined; - b[0] = 1; - assert(b.len == 10); - var r: [W * H]u32 = undefined; - for (0..r.len) |i| { - r[i] = 2; - } - assert(total(r) == 24); -} - -test fails { - var a: [W - 1]u8 = undefined; - a[0] = 1; - assert(a.len == 4); -} -"; - let r = run(src); - assert_eq!(names_ok(&r), vec![("ok", false, true), ("fails", false, false)]); -} - -/// A length that is negative, reads a run-time value or calls a fn is -/// refused as `type [N]T`; one that overflows its typed constant is refused -/// by the fold. Zig refuses all but the call. -#[test] -fn array_length_expression_rejections() { - let cases: &[(&str, bool)] = &[ - ("const W = 4;\nfn f() -> u32 {\n var a: [W - 5]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), - ("fn f() -> u32 {\n var n: u32 = 3;\n n = n + 1;\n var a: [n + 1]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), - ("fn g(x: u32) -> u32 {\n return x;\n}\nfn f() -> u32 {\n var a: [g(2) + 1]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", true), - ("const H: u8 = 200;\nfn f() -> u32 {\n var a: [H + 100]u8 = undefined;\n a[0] = 1;\n return 1;\n}\n", false), - ]; - for (body, len) in cases { - let m = rejected(&format!("module a;\n\n{}\ntest t {{\n assert(f() == 1);\n}}\n", body)); - let want = if *len { "t27b: unsupported construct type [N]T at line" } else { "t27b: unsupported construct" }; - assert!(m.starts_with(want), "{}: {}", body, m); - } -} - -/// A module const built from typed constants is folded as Zig folds it at -/// compile time: a checked step out of range is refused, `+%` wraps. -#[test] -fn typed_constant_arithmetic_folds() { - let src = "module a; - -const H: u32 = 3; -const A = H * 5; -const Q: u8 = 250; -const R = Q +% 10; - -fn next() -> u32 { - var x: u32 = A; - x = x + 1; - return x; -} - -test ok { - assert(next() == 16); - assert(R == 4); -} -"; - let r = run(src); - assert_eq!(names_ok(&r), vec![("ok", false, true)]); - let m = rejected("module a;\n\nconst B: u8 = 200;\nconst OV = B + 100;\n\ntest t {\n assert(OV == 44);\n}\n"); - assert!(m.starts_with("t27b: unsupported construct ConstDecl at line"), "{}", m); - assert!(m.contains("`OV` overflows u8"), "{}", m); -} - /// `return undefined;` in a void fn is a plain `return;`: the work before it /// is kept, the work after it skipped. In a test block it stays refused. #[test] diff --git a/tools/policy/foreign-exceptions.txt b/tools/policy/foreign-exceptions.txt index b44a7efa2f..15cfece079 100644 --- a/tools/policy/foreign-exceptions.txt +++ b/tools/policy/foreign-exceptions.txt @@ -254,6 +254,13 @@ fpga/verilog/eth_beacon_top.xdc # plus its unit tests; the card is specs/tools/tri/mutate.t27. Debt #5980. cli/tri/src/mutate.rs +# owner 2026-10-06, epic #6063 (label owner-approved-foreign on #6063; "add the label yourself and do the +# work", translated): t27b coverage lane 1, issue #7347 -- an array length that is a compile-time expression +# (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. +cli/t27b/src/lower.rs +cli/t27b/tests/source.rs + + # owner 2026-10-06, label owner-approved-foreign on epic #6063 and on issue #6961 ("add the label yourself and # do the work", translated): t27b lowers std.mem.eql / indexOf on bytes in a buffer ([]u8, *[N]u8). # Conformance spec first: specs/tri/t27b/conformance/std_mem_byte_slice.t27. Remove these five lines once that PR has merged. @@ -419,14 +426,6 @@ tools/bees/merger_gate_selftest.py # discount_holds); reviewer.py mirrors it with a pointer and has no rule of its own. criteria_backfill.py comes # with it unchanged from #5777: the reviewer imports it to run an issue's criteria, and its self-test needs it. tools/bees/reviewer.py -tools/queen/criteria_backfill.py - -# owner 2026-10-06, epic #6063 (label owner-approved-foreign on #6063; "add the label yourself and do the -# work", translated): t27b coverage lane 1, issue #7347 -- an array length that is a compile-time expression -# (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. -cli/t27b/src/lower.rs -cli/t27b/tests/source.rs -# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7415: # t27b reads the postfix optional `T?` as t27c's type mapper writes it, `?T` (the parser keeps the suffix only # on a struct field's type). The behaviour is pinned by specs/tri/t27b/conformance/postfix_optional.t27. cli/t27b/src/lower.rs From f3ca917c6256d31927296046f150c568f2d90c70 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sat, 10 Oct 2026 18:46:56 +0700 Subject: [PATCH 09/10] sync: park the lane's exception block deeper in the untouched region The spot after cli/tri/src/mutate.rs sits against master's newest hunk context; one more stable region down the two appends no longer touch. Co-Authored-By: Claude Opus 5.5 (1M context) --- tools/policy/foreign-exceptions.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/policy/foreign-exceptions.txt b/tools/policy/foreign-exceptions.txt index 15cfece079..f42b6e8ca2 100644 --- a/tools/policy/foreign-exceptions.txt +++ b/tools/policy/foreign-exceptions.txt @@ -254,12 +254,6 @@ fpga/verilog/eth_beacon_top.xdc # plus its unit tests; the card is specs/tools/tri/mutate.t27. Debt #5980. cli/tri/src/mutate.rs -# owner 2026-10-06, epic #6063 (label owner-approved-foreign on #6063; "add the label yourself and do the -# work", translated): t27b coverage lane 1, issue #7347 -- an array length that is a compile-time expression -# (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. -cli/t27b/src/lower.rs -cli/t27b/tests/source.rs - # owner 2026-10-06, label owner-approved-foreign on epic #6063 and on issue #6961 ("add the label yourself and # do the work", translated): t27b lowers std.mem.eql / indexOf on bytes in a buffer ([]u8, *[N]u8). @@ -337,6 +331,12 @@ bootstrap/stage0/FROZEN_HASH # first: specs/tri/t27b/conformance/const_optional.t27. cli/t27b/src/lower.rs cli/t27b/tests/source.rs +# owner 2026-10-06, epic #6063 (label owner-approved-foreign on #6063; "add the label yourself and do the +# work", translated): t27b coverage lane 1, issue #7347 -- an array length that is a compile-time expression +# (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. +cli/t27b/src/lower.rs +cli/t27b/tests/source.rs + # owner 2026-10-06, label owner-approved-foreign on epic #6063 and on issues #7175 / #7179 ("add the label # yourself and do the work", translated): t27b coverage lane 2 -- a fn no test reaches may name a struct From 7d73bf0fcae8857dafe65ce09ec4b2be5563e8e5 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sat, 10 Oct 2026 18:50:59 +0700 Subject: [PATCH 10/10] sync: rebuild the two shared files as master's content plus the lane's additions The incremental resolutions had drifted (a lost blank, a dropped criteria_backfill.py line). source.rs and foreign-exceptions.txt are now byte-identical to master outside one insertion each, parked in regions master has not touched since the merge base, so update-branch merges without a conflict. Co-Authored-By: Claude Opus 5.5 (1M context) --- cli/t27b/tests/source.rs | 74 ++++++++++++++--------------- tools/policy/foreign-exceptions.txt | 7 +-- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/cli/t27b/tests/source.rs b/cli/t27b/tests/source.rs index 882ced5640..7ee29ba826 100644 --- a/cli/t27b/tests/source.rs +++ b/cli/t27b/tests/source.rs @@ -2915,44 +2915,6 @@ fn only_discards(x: u32, K: u32, y: u32) -> u32 { return y; } -test ok { - assert(triple_first(5, 100) == 15); - assert(seven(3, 4) == 7); - assert(twice(-4, 1) == -8); - assert(only_discards(1, 2, 5) == 5); - assert(only_discards(1, 2, 0) == 0); -} - -test fails { - assert(triple_first(5, 100) == 500); -} -"; - let r = run(src); - assert_eq!(names_ok(&r), vec![("ok", false, true), ("fails", false, false)]); - assert_eq!(r[1].2, Err((TrapKind::Assert, line_of(src, "== 500")))); -} - -/// The nested discards the reference cannot compile: Zig's AstGen refuses -/// a discard of a parameter the body also uses, in every fn. A parameter -/// that shares a module declaration's name is refused the same way, since -/// gen-zig renames it. A discard of a local stays unsupported. -#[test] -fn parameter_discard_rejections() { - let head = "module a;\n\nconst K: u32 = 3;\n\nfn k2() -> u32 {\n return 2;\n}\n\n"; - let cases: &[(&str, &str, &str)] = &[ - ("fn f(x: u32) -> u32 { if (x > 1) { _ = x; } return 1; }", "StmtAssign(discard)", "`_ = x;`"), - ("fn f(x: u32, y: u32) -> u32 { if (y > 1) { _ = x; _ = x; } return x; }", "StmtAssign(discard)", "`_ = x;`"), - ("fn f(x: u32, y: u32) -> u32 { _ = x; if (y > 1) { _ = x; } return y + x; }", "StmtAssign(discard)", "`_ = x;`"), - ("fn f(K: u32, y: u32) -> u32 { if (y > 1) { _ = K; } return y + K; }", "StmtAssign(discard)", "`_ = K;`"), - ("fn f(x: u32) -> u32 { var y: u32 = x; _ = y; return 1; }", "StmtAssign(undeclared)", "`_`"), - ]; - for (body, construct, detail) in cases { - let m = rejected(&format!("{}{}\n", head, body)); - assert!(m.starts_with(&format!("t27b: unsupported construct {} at line", construct)), "{}: {}", body, m); - assert!(m.contains(detail), "{}: {}", body, m); - } -} - // ------------------------------------------------------------ array length expressions /// An array length spelled as an expression (`[W+1]u8`, `[(W+1)*2]u16`) is @@ -3051,7 +3013,43 @@ test ok { assert!(m.contains("`OV` overflows u8"), "{}", m); } +test ok { + assert(triple_first(5, 100) == 15); + assert(seven(3, 4) == 7); + assert(twice(-4, 1) == -8); + assert(only_discards(1, 2, 5) == 5); + assert(only_discards(1, 2, 0) == 0); +} +test fails { + assert(triple_first(5, 100) == 500); +} +"; + let r = run(src); + assert_eq!(names_ok(&r), vec![("ok", false, true), ("fails", false, false)]); + assert_eq!(r[1].2, Err((TrapKind::Assert, line_of(src, "== 500")))); +} + +/// The nested discards the reference cannot compile: Zig's AstGen refuses +/// a discard of a parameter the body also uses, in every fn. A parameter +/// that shares a module declaration's name is refused the same way, since +/// gen-zig renames it. A discard of a local stays unsupported. +#[test] +fn parameter_discard_rejections() { + let head = "module a;\n\nconst K: u32 = 3;\n\nfn k2() -> u32 {\n return 2;\n}\n\n"; + let cases: &[(&str, &str, &str)] = &[ + ("fn f(x: u32) -> u32 { if (x > 1) { _ = x; } return 1; }", "StmtAssign(discard)", "`_ = x;`"), + ("fn f(x: u32, y: u32) -> u32 { if (y > 1) { _ = x; _ = x; } return x; }", "StmtAssign(discard)", "`_ = x;`"), + ("fn f(x: u32, y: u32) -> u32 { _ = x; if (y > 1) { _ = x; } return y + x; }", "StmtAssign(discard)", "`_ = x;`"), + ("fn f(K: u32, y: u32) -> u32 { if (y > 1) { _ = K; } return y + K; }", "StmtAssign(discard)", "`_ = K;`"), + ("fn f(x: u32) -> u32 { var y: u32 = x; _ = y; return 1; }", "StmtAssign(undeclared)", "`_`"), + ]; + for (body, construct, detail) in cases { + let m = rejected(&format!("{}{}\n", head, body)); + assert!(m.starts_with(&format!("t27b: unsupported construct {} at line", construct)), "{}: {}", body, m); + assert!(m.contains(detail), "{}: {}", body, m); + } +} // ------------------------------------------------------------- type alias diff --git a/tools/policy/foreign-exceptions.txt b/tools/policy/foreign-exceptions.txt index f42b6e8ca2..57fe388a64 100644 --- a/tools/policy/foreign-exceptions.txt +++ b/tools/policy/foreign-exceptions.txt @@ -30,7 +30,6 @@ cli/t27b/src/codegen.rs # The fixture is specs/tri/t27b/conformance/shadow_module_var.t27. cli/t27b/src/lower.rs cli/t27b/tests/source.rs - # owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), epic #6063, # issue #7368: t27b coverage lane 3 -- integer types of every width 1..31 (`type u1`, i2, u4, u21) are held # like a u8 and checked against their own range. Conformance spec first: @@ -254,7 +253,6 @@ fpga/verilog/eth_beacon_top.xdc # plus its unit tests; the card is specs/tools/tri/mutate.t27. Debt #5980. cli/tri/src/mutate.rs - # owner 2026-10-06, label owner-approved-foreign on epic #6063 and on issue #6961 ("add the label yourself and # do the work", translated): t27b lowers std.mem.eql / indexOf on bytes in a buffer ([]u8, *[N]u8). # Conformance spec first: specs/tri/t27b/conformance/std_mem_byte_slice.t27. Remove these five lines once that PR has merged. @@ -331,13 +329,13 @@ bootstrap/stage0/FROZEN_HASH # first: specs/tri/t27b/conformance/const_optional.t27. cli/t27b/src/lower.rs cli/t27b/tests/source.rs + # owner 2026-10-06, epic #6063 (label owner-approved-foreign on #6063; "add the label yourself and do the # work", translated): t27b coverage lane 1, issue #7347 -- an array length that is a compile-time expression # (`[N + 1]T`) is folded as Zig folds it. Conformance spec first: specs/tri/t27b/conformance/array_len_expr.t27. cli/t27b/src/lower.rs cli/t27b/tests/source.rs - # owner 2026-10-06, label owner-approved-foreign on epic #6063 and on issues #7175 / #7179 ("add the label # yourself and do the work", translated): t27b coverage lane 2 -- a fn no test reaches may name a struct # t27b cannot lay out (Zig never resolves its signature), and `x as T` with a float operand spelled as one @@ -426,6 +424,9 @@ tools/bees/merger_gate_selftest.py # discount_holds); reviewer.py mirrors it with a pointer and has no rule of its own. criteria_backfill.py comes # with it unchanged from #5777: the reviewer imports it to run an issue's criteria, and its self-test needs it. tools/bees/reviewer.py +tools/queen/criteria_backfill.py + +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), issue #7415: # t27b reads the postfix optional `T?` as t27c's type mapper writes it, `?T` (the parser keeps the suffix only # on a struct field's type). The behaviour is pinned by specs/tri/t27b/conformance/postfix_optional.t27. cli/t27b/src/lower.rs