Conversation
…ld fails
name_local derives the C local from the Bend-level name plus a counter and
no prefix, so a generated binder named `ts` emits `u32 ts_32 = r34;` -- and
on macOS `ts_32` is a macro in <mach/arm/thread_status.h>:
mach/arm/thread_status.h:199:18: note: expanded from macro 'ts_32'
199 | #define ts_32 uts.ts_32
The native build then fails with "expected ';' at end of declaration" on a
program that checks and runs on the JS lane. The name is reachable from Base
itself: base.bend:1459 declares U32.divmod.go.shl(..., ts: Bool & Word(32n)),
and compiling it mints ts_0 through ts_32.
The strip first is required for the case measured: seg_open re-opens names it
already minted, so without it this repro emits `bend_b_0`, `bend_bend_b_0`,
`bend_bend_bend_b_0` -- 12 doubled occurrences, 5 distinct, longest 18
characters; with it, 0 and 11. That closes the observed path, not a general
idempotence property.
comp.ts 64840 -> 64852 ttok, a whole-file delta of 12 against the 65000 cap.
VictorTaelin
pushed a commit
that referenced
this pull request
Sep 21, 2026
…ot capture it name_local mints _<name>_<n>: macOS's <mach/arm/thread_status.h> defines ts_32 and ts_64, which Base's U32.divmod reaches with its 33 ts locals, and the native build failed. A name is stripped of a leading _ first, since seg_open feeds minted names back through name_local. Emitted C grows 1-5%. (PR #926, with a one-character prefix)
Contributor
|
Merged into 2.0.25 under your authorship, thank you, with one trim: the prefix is a single Note: this reply was written by an AI after it reported the issue to me and I made the decision. If anything here is wrong, reply and I will review it myself. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
bend prog.bend -o progfails on macOS arm64 for a program that checks and runs on the JSlane.
name_local(bend2/comp.ts:648) builds every generated C local from the Bend-levelname plus a counter, with no prefix:
so a generated local can land on a macro the platform headers already define. On macOS one
does:
ts_32is#define ts_32 uts.ts_32in<mach/arm/thread_status.h>, and it is reachablefrom
Baseitself —bend2/base.bend:1459declaresU32.divmod.go.shl(..., ts: Bool & Word(32n)), and compiling it mintsts_0…ts_32.Repro (12 lines)
The change
function name_local(fl: File, k: Bend.Name): string { - const base = name_clean(k); + const base = name_clean(k).replace(/^bend_/, ""); const n = fl.fresh.get(base) ?? 0; fl.fresh.set(base, n + 1); - return base + "_" + n; + return "bend_" + base + "_" + n; }The strip is required for the case measured, not cosmetic:
seg_open(comp.ts:1640) feedsnames it has already minted back through
name_local, so a plain prefix accumulates — thisrepro, without the strip, emits
bend_b_0,bend_bend_b_0,bend_bend_bend_b_0(12 doubledoccurrences, 5 distinct, longest identifier 18 characters; with the strip, 0 and 11). It closes
the observed path; it is not a general idempotence property.
name_localis shared with the JS emitter, so generated JS identifiers move as well as the Cones. The JS output is unchanged here:
0on this repro before and after, and no per-testdifference in the sampled differential below.
Scope: the names
name_localmints — locals, parameters, continuations, and the fixed names(
sp,fb,fv,o,x,k,v). Top-level/def naming is untouched, andCID_/FID_arealready prefixed.
Cost
bend2/comp.ts64840 → 64852 ttok — a whole-file delta of 12 — against the repo gate's65000 cap (headroom 160 → 148). I left out a comment line to keep it there; this message carries
the explanation instead.
bun gates/repo.ts: PASS 46/46.The emitted C is larger, because every generated local reference gains 5 characters: 140864 →
153104 bytes (+8.7%) on this 12-line repro. I have not measured that ratio on a large program.
What I checked
rc=1,expected ';' at end of declaration/rc=0, binary prints0--check-only) and the JS lane, before / afterAll terms check.and0, both timests_Nlocalsbend_ts_Nafter)tests/corpusmaincomptime/unsafe.bend, the interpreter-only unsafe banner;gfx/window.bend, which needs a display)bun gates/repo.tsgates/test.tsandgates/perf.tsneed the SSH cluster andgates/ping.tscannot run outside thesite project. None ran here, and the local differential above is not a substitute for them.
Not a duplicate
Searching the 920-item issue and PR snapshot, I found no direct duplicate about the C emitter's
generated locals meeting a host macro. The closest items use different mechanisms or layers:
#478 / PR #487 reserves
__for generated function names; #790, #799, #800 and #875 concerndifferent JS, FFI, or compiler-sentinel naming mechanisms; #904/#908 concern JS import-path
identifiers; and #905/#922 concern checker/parser name collisions.
What this does not claim
bend_is an ordinary C identifier prefix and aforeign header could still define
bend_x_0. A reserved prefix would be stronger; this is asmall change that removes the reproduced failure.
tests/, the compiled lanes are sampled.ts_32is the only such name on any SDK: it is the one reachable fromBaseon thishost, and the change addresses the class while claiming only the observed instance.
Found by an agent working for @blockbrain_labs