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
What happens
t27c gen-rustemitsif (b) != 0whenbis a local bound to the result of abool-returning function, andrustcrejects it. The Zig backend (t27c gen) compiles the same spec.Repro (
rust_bool.t27):t27c gen-rust rust_bool.t27emits:and
rustcfails witherror[E0308]: mismatched types ... expected bool, found integer.Where
bootstrap/src/compiler.rson master 6111696:fn expr_is_bool_syntactically(line 23416) recognises comparisons,!/notand bool literals, but has noExprCallarm.collect_bool_locals(line 23428, called at 26202) does not markconst odd = is_odd(x)as a bool local.expr_to_rust_cond(around 27146) then treatsoddas an integer and wraps it as({}) != 0.The method
expr_is_boolalready handlesExprCallthroughself.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_fnsintocollect_bool_locals/expr_is_bool_syntacticallyand treatingExprCallof a name in that set as bool. The repro should then compile withrustc --crate-type lib.Workaround in use
Call the function inline in the condition:
if (is_odd(x)) { ... }. Hit while writingspecs/xilinx7/packets.t27.Boundary
specs/xilinx7/packets.t27bootstrap/src/compiler.rs