Skip to content

t27c gen-rust: local bound to a bool-returning call is emitted as if (b) != 0 #5607

Description

@gHashTag

What happens

t27c gen-rust emits if (b) != 0 when b is a local bound to the result of a bool-returning function, and rustc rejects it. The Zig backend (t27c gen) compiles the same spec.

Repro (rust_bool.t27):

module repro_rust_bool;
pub fn is_odd(x: u32) bool { return (x & 1) == 1; }
pub fn half_if_even(x: u32) u32 {
    const odd = is_odd(x);
    if (odd) { return x; }
    return x / 2;
}

t27c gen-rust rust_bool.t27 emits:

let odd = is_odd(x);
if (odd) != 0 {

and rustc fails with error[E0308]: mismatched types ... expected bool, found integer.

Where

bootstrap/src/compiler.rs on master 6111696:

  • fn expr_is_bool_syntactically (line 23416) recognises comparisons, ! / not and bool literals, but has no ExprCall arm.
  • So collect_bool_locals (line 23428, called at 26202) does not mark const odd = is_odd(x) as a bool local.
  • expr_to_rust_cond (around 27146) then treats odd as an integer and wraps it as ({}) != 0.

The method expr_is_bool already handles ExprCall through self.bool_fns.contains(...); only the syntactic helper used for locals lacks it.

Suggested fix

Let the local inference consult bool_fns, for example by passing &self.bool_fns into collect_bool_locals / expr_is_bool_syntactically and treating ExprCall of a name in that set as bool. The repro should then compile with rustc --crate-type lib.

Workaround in use

Call the function inline in the condition: if (is_odd(x)) { ... }. Hit while writing specs/xilinx7/packets.t27.

Boundary

  • specs/xilinx7/packets.t27
  • bootstrap/src/compiler.rs

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions