Skip to content

gen (Zig): signed and float % emits plain %, which Zig refuses to compile #5973

Description

@gHashTag

Summary

t27c gen (Zig backend) emits a plain % for a remainder whose operands are signed integers (or floats). Zig refuses that at compile time, so any spec that takes % of an i32 parameter does not compile under zig test at all.

Found by the t27b differential test. Part of #5905.

Reproducer

module Sem;

fn inc(x: i32) -> i32 {
    return x + 1;
}

fn shr(x: i32, n: i32) -> i32 {
    return x >> n;
}

fn rem(a: i32, b: i32) -> i32 {
    return a % b;
}

test inc_max { assert_eq(inc(2147483647), 0 - 2147483647 - 1); }
test shr_big { assert_eq(shr(1024, 40), 0); }
test rem_neg { assert_eq(rem(0 - 7, 2), 0 - 1); }

endmodule

t27c gen sem.t27 > sem.zig && zig test sem.zig

Observed

error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod

The whole file fails to compile, so inc_max and shr_big are never run either.

Expected

a % b on signed operands lowers to @rem(a, b): the truncated remainder, rem(-7, 2) == -1, which is what C, Rust and t27b compute. Unsigned % stays %.

/ already has this repair (W593 emits @divTrunc when an operand is known signed); % was never given the same rule. Zig refuses runtime float % with the same message, so floats need @rem too.

No activity

Activity on this issue will appear here.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-boundaryNo '## Boundary' section, so the Queen can reserve nothing for it and no bee can take it

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions