Skip to content

gen-c: a numeric a ** b is lowered as an array repeat, /* repeat: a ** b */ {0} #7427

Closed as not planned

Description

@gHashTag

Part of #5980 (self-host P1: the core must refuse what gen-c gets wrong, so gen-c should stop getting it wrong).

What happens

t27c gen-c treats every ** as the array repeat operator. A numeric power is written as a comment and an empty initializer, and gen-c exits 0:

module m;
fn p(a: u32, b: u32) -> u32 { return a ** b; }
fn q(x: f64) -> f64 { return x ** 2.0; }
return /* repeat: a ** b */ {0};

cc rejects return {0}; in a scalar function, so these functions never compile. The language's own compiler specs define ** on numbers as the power operator: specs/compiler/typechecker.t27 lists it in is_arithmetic_op, and specs/compiler/optimizer.t27 folds 2 ** 10 to 1024 in eval_binary_const. Two corpus specs use it: specs/provider/adapters.t27:357 and specs/portable/relay_observer.t27:198.

Expected

A ** whose left operand is not an array literal is a numeric power. gen-c writes it as a call that C can compile: pow/powf/powl for a float operand and an exact integer power for an integer operand. The array repeat [_]T{v} ** n keeps its current lowering.

Check

cargo build --release -p t27c
printf 'module m;\nfn p(a: u32, b: u32) -> u32 { return a ** b; }\ntest t { assert(p(2, 10) == 1024); assert(p(3, 0) == 1); }\n' > /tmp/p.t27
./target/release/t27c gen-c /tmp/p.t27 > /tmp/p.c && cc -std=gnu11 -DT27_TEST_MAIN /tmp/p.c -o /tmp/p -lm && /tmp/p

Today the cc step fails. After the fix the test passes. The regression test is bootstrap/tests/genc_nested_repeat.rs, shared with #7353 because both defects are in the same ** lowering.

Boundary

  • specs/compiler/optimizer.t27
  • specs/compiler/typechecker.t27
  • specs/portable/relay_observer.t27
  • specs/provider/adapters.t27
  • bootstrap/tests/genc_nested_repeat.rs

User Scenarios

  • Given a T27 module with a function returning a ** b where both operands are integer scalars, when t27c gen-c compiles it, then the generated C uses an integer power implementation (not an array repeat) and the resulting binary passes assert(p(2, 10) == 1024).
  • Given a T27 module with a function returning x ** 2.0 where the left operand is a float scalar, when t27c gen-c compiles it, then the generated C calls pow/powf/powl and the resulting binary executes without compile errors.

Requirements

  • FR-001: The gen-c lowering MUST distinguish numeric ** from array repeat by inspecting whether the left operand is an array literal.
  • FR-002: For integer operands, gen-c MUST emit an exact integer power computation (e.g., loop or builtin) that evaluates at runtime without linking -lm.
  • FR-003: For floating-point operands, gen-c MUST emit a call to pow, powf, or powl matching the operand width and link with -lm.
  • FR-004: The array repeat form [_]T{v} ** n MUST continue to lower to the current repeat initializer.
  • FR-005: The typechecker and optimizer specs MUST continue to treat ** as an arithmetic operator on numbers (no spec change required).

Success Criteria

  • cargo build --release -p t27c exits 0
  • printf 'module m;\nfn p(a: u32, b: u32) -> u32 { return a ** b; }\ntest t { assert(p(2, 10) == 1024); assert(p(3, 0) == 1); }\n' > /tmp/p.t27 && ./target/release/t27c gen-c /tmp/p.t27 > /tmp/p.c && cc -std=gnu11 -DT27_TEST_MAIN /tmp/p.c -o /tmp/p -lm && /tmp/p exits 0
  • printf 'module m;\nfn q(x: f64) -> f64 { return x ** 2.0; }\ntest t { assert(q(3.0) == 9.0); }\n' > /tmp/q.t27 && ./target/release/t27c gen-c /tmp/q.t27 > /tmp/q.c && cc -std=gnu11 -DT27_TEST_MAIN /tmp/q.c -o /tmp/q -lm && /tmp/q exits 0
  • cargo test --test genc_nested_repeat exits 0 (5 tests)

Activity

  1. gHashTag commented on Oct 7, 2026

    @gHashTag
    OwnerAuthor

    A fix is on branch genc-repeat-pow (head db2c58f), but no PR is open because it is over the foreign-line budget (#7371). On top of #7406 it adds compiler.rs +292 and tests +304, against limits of 40 per file and 80 per PR, and #7406 is parked for the same reason.

    What the branch does:

    • A nested ** repeat is written as one comment, with the rows kept.
    • A single element becomes a GNU range. Several elements with a literal count are unrolled.
    • An element shape it cannot write is refused by name, not zeroed.
    • A numeric a ** b becomes t27_pow / t27_ipow.

    On the t27c lab, 11/11 tests pass with the fix and 10/11 fail with it reverted.

    The corpus diff on the previous head showed 16 specs change C, about 11 of them sealed. The branch is not resealed yet. Landing it needs the lowering written in .t27 or an owner decision.

  2. added
    needs-boundaryNo '## Boundary' section, so the Queen can reserve nothing for it and no bee can take it
    and removed
    needs-boundaryNo '## Boundary' section, so the Queen can reserve nothing for it and no bee can take it
    on Oct 7, 2026
  3. gHashTag commented on Oct 7, 2026

    @gHashTag
    OwnerAuthor

    Reopened 2026-10-07: the bulk close of issues without a ## Boundary section was reverted by the owner. Nothing to do here; this comment replaces the earlier close notice.

  4. added
    needs-shapeIssue lacks Boundary/Scenarios/Requirements/Success criteria
    on Oct 7, 2026
  5. removed
    needs-shapeIssue lacks Boundary/Scenarios/Requirements/Success criteria
    on Oct 7, 2026
  6. github-actions commented on Oct 17, 2026

    @github-actions
    Contributor

    Re-filed as #9885.

    An attempt claimed this issue on 2026-10-08 and left an empty branch. A dispatch row that has spent its retry ceiling is released once and then keeps its issue for good, which is the right rule for a third identical failure and the wrong outcome for an issue nobody ever attempted twice. The new issue carries the same work, the same boundary, and today's brief.

    Closing this one so the swarm can take the work again.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions