vercel-labs / vercel-labs/native

Template-literal interpolation of a string emits `{d}`; the generated Zig does not compile

Open
#249 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Zig
Stars
7.7k
Forks
314
Avg merge
5h
Merged PRs (30d)
13

Description

Summary

A template literal that interpolates a string emits a {d} format specifier, so the
generated Zig does not compile. The subset checker passes; the failure surfaces as
invalid format string 'd' for type '*const [N:0]u8' in code the author never wrote.

Reproduced against v0.7.1 (19519dd5), macOS, Zig 0.16.0, node 24.15.0.

Reproduction

import { asciiBytes } from "@native-sdk/core";
const PAD = "abc";
export interface Model { readonly out: Uint8Array }
export function initialModel(): Model { return { out: new Uint8Array(0) } }
export type Msg = { readonly kind: "a" } | { readonly kind: "b" };
export function update(model: Model, msg: Msg): Model {
  switch (msg.kind) {
    case "a": { const local = "xyz"; return { ...model, out: asciiBytes(`${local}-1`) }; }
    case "b": return { ...model, out: asciiBytes(`${PAD}-2`) };
  }
}
node build/ts_run.mjs packages/core/src/cli.ts core.ts -o core.zig

Emits:

const text = std.fmt.bufPrint(buf, "{d}-1", .{ local }) catch unreachable;
const text_2 = std.fmt.bufPrint(buf_2, "{d}-2", .{ PAD }) catch unreachable;

Both should be {s}. Local const and module-level const reproduce identically; the
transpile itself reports no diagnostic.

Why it matters beyond the wrong character

This is the failure shape the eject story implies an author will not hit: a compile error
in generated code, against a subset check that passed. The author's next move is to read
emitted Zig to find out that their string interpolation was typed as a number.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run the reproduction through build/ts_run.mjs with packages/core/src/cli.ts and compare the generated core.zig for local and module-level string constants. Trace the template-literal interpolation path; done when both string cases emit {s} and the generated Zig compiles.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript, zig
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.