Skip to content

feat(t27b): str as []const u8 -- literals, .len, ==/!= (75 files pass, 0 mismatch) - #6229

Merged
gHashTag merged 4 commits into
masterfrom
claude/t27b-strings
Oct 4, 2026
Merged

gHashTag merged 4 commits into
masterfrom
claude/t27b-strings

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Closes #6183
Refs #6063

What

t27b lowers str, &str, string and []const u8 as Zig's []const u8: a 16-byte (ptr, len) aggregate (ptr @0, len u64 @8, align 8) that is handled like a struct. It is passed by address, returned through sret, and copied on assignment.

  • String literals are compile-time values (Val::S). Their bytes, plus a trailing NUL, are deduplicated in read-only data. A str place is only materialized where one is needed.
  • .len folds for literals and string constants. Otherwise it reads the u64 at offset 8.
  • == / != compare contents like std.mem.eql. Two literals fold. Anything else calls one synthesized IR function, __t27b_str_eql, which compares the lengths and then loops over the bytes. It is only emitted when used.
  • Module-level str consts must be string literals. Anything else is rejected with a precise reason.
  • Precise rejections (no silent fallback): s[i], slicing, .ptr (ExprFieldAccess(str)), ordering and arithmetic on strings (ExprBinary(op) "on a string"), and str fields in module-level struct constants (ConstDecl(str field)).

Unit tests in cli/t27b/tests/source.rs:

  • strings_literals_params_fields_and_equality: params, struct fields, sret returns, equality, and a failing-assert trap line.
  • string_rejections_are_precise: 7 cases.

The blockers.rs fixture now uses a char literal, because string literals are no longer a blocker.

Corpus (t27b corpus specs, 1212 files, both binaries built from master 0011bb0 vs this branch)

before (master) after (branch)
supported, all tests pass 46 (338 tests) 75 (674 tests)
pass_vacuous 38 38
a test fails 1 (fpga/verification/build_verify.t27, pre-existing) 1 (same)
rejected 1087 1058
front-end error 40 40
JIT/interpreter mismatch 0 0
crash / timeout 0 / 0 0 / 0
  • +29 files pass and none were lost. type str is no longer a first blocker.
  • Reference check: all 29 newly passing files also pass the reference path (t27c gen + zig test): 29/29 compile, every test passes.
  • The full --reference run shows reference 675 pass.

Ratchet ledger: not blessed here

tri t27b ratchet --run <branch run> reports the 29 newly passing files as UNEXPECTED PASS. That is the expected signal for this change.

I did not bless docs/reports/t27b_expectations.json in this PR, because the same run also reports findings that already exist on master and are unrelated to strings:

  • UNLISTED: specs/crons/mac-trios-* and others
  • STALE: queen-rehearsal.t27
  • VACUITY MEASURED

A bless here would fold those findings in. A steward re-bless after merge (tri t27b ratchet --bless from a lab run, as for #6188) records the 29 files as pass.

Environment

  • Builds used CARGO_BUILD_JOBS=4 --target-dir /tmp/memory-target.
  • Load average during the work was between 42 and 210. At push time it was 121.79 / 152.71 / 149.28.

🤖 Generated with Claude Code

gHashTag and others added 4 commits October 5, 2026 00:33
str, &str, string and []const u8 lower to Zig's []const u8: a 16-byte
(ptr, len) aggregate passed by address, returned through sret and copied
like a struct. String literals are compile-time values whose bytes sit in
read-only data. .len reads the length; == and != compare contents like
std.mem.eql (two literals fold, otherwise one synthesized IR helper,
__t27b_str_eql).

t27b corpus specs: 70 -> 99 files pass (223 -> 555 tests), 0 mismatch.
The 29 new files also pass the reference path (t27c gen + zig test).

Refs #6063

Closes #6183

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: lower.rs (peek_string beside the new cast(); cast() rejects a
string), blockers.rs fixture (ExprCast(to bool) and a char literal).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Closes #6183

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-04 18:08:53 UTC

Summary

Status Count
Total Open PRs 43
PRs with Failing Checks 30
PRs with All Checks Green 13
READY 12
FAILING 30
PENDING 0
NO CHECKS YET 0

These columns do not partition: 12 + 30 + 0 + 0 = 42, and there are 43 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=8597b6ded596 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t27b: str and string literals as []const u8 (len, ==, !=)

1 participant