Skip to content

compiler: assert (a & b) == c parses as assert(a & b) followed by == c #5593

Closed

Description

@gHashTag

assert (a & b) == c is parsed as assert(a & b) followed by == c.

Reproduction

module m;
pub const A : u32 = 4;
pub const B : u32 = 7;
test t {
    assert (A & B) == A;
    assert (A < B) and (B > A);
}

t27c gen on master (d04bf14) emits:

    if (!(A & B)) @panic("assertion failed") == A;
    if (!(A < B)) __t27_assert_fail("...", .{ A, B }) and (B > A);
  • The AST is ExprBinary(==, ExprCall assert(A & B), A): the parenthesised operand became the call's argument, and the comparison took the call as its operand.
  • Typecheck reports ok. Only zig test notices, with "unreachable code" or "expected type 'bool', found 'u32'".

Cause

bootstrap/src/compiler.rs, the bare-assert path of statement parsing, requires self.peek.kind != TokenKind::LParen. So every assert ( takes the call path, even when the parenthesis only opens the first operand of a longer condition.

Scope in the corpus

13 lines in 8 specs have the shape assert (...) <binary op> .... Among them:

  • specs/fpga/fifo.t27:339
  • specs/fpga/uart.t27:202
  • specs/numeric/e8m0.t27:233
  • specs/math/radix_economy.t27:270
  • specs/cloud/railway_deploy.t27 (4 lines)
  • specs/compiler/mod_structure.t27:133
  • specs/port/fpga/verilog/mvp_ternary_classifier_jtag_noport.t27 (3 lines)
  • specs/port/conformance/witness/gf48_fp64/gf_decode_param_fp64.t27:610

Found by

A t27 spec for the CLK_PERF / PHSR_PERFCLK segbits rows of openXC7/prjxray-db#30. It had to work around the bug with an is_subset(a, b) helper.

Proposed fix

Add a lookahead. When the token after the ) that matches assert ( is a binary operator on the same line, parse the bare form. assert(x); and assert(x, "msg") keep their AST.

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

    area/compilerHIR/IR/codegen/optimizerbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions