authorgravatar for wander4096@gmail.comtison <wander4096@gmail.com> 2023-05-24 08:01:48+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-24 00:01:48+00:00
logbfe02ff61a8861c269524c60668a3969cb053720
tree92c6a412b5f25101c60217e9db80a53394c223bb
parentdcc1b4fd1532ccfe028fe9f68c0d19fc28800191
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

make `@boolToInt` always return a u1

Signed-off-by: tison <wander4096@gmail.com>

6 files changed, 19 insertions(+), 13 deletions(-)

doc/langref.html.in-4
...@@ -7850,10 +7850,6 @@ comptime {...@@ -7850,10 +7850,6 @@ comptime {
7850 Converts {#syntax#}true{#endsyntax#} to {#syntax#}@as(u1, 1){#endsyntax#} and {#syntax#}false{#endsyntax#} to7850 Converts {#syntax#}true{#endsyntax#} to {#syntax#}@as(u1, 1){#endsyntax#} and {#syntax#}false{#endsyntax#} to
7851 {#syntax#}@as(u1, 0){#endsyntax#}.7851 {#syntax#}@as(u1, 0){#endsyntax#}.
7852 </p>7852 </p>
7853 <p>
7854 If the value is known at compile-time, the return type is {#syntax#}comptime_int{#endsyntax#}
7855 instead of {#syntax#}u1{#endsyntax#}.
7856 </p>
7857 {#header_close#}7853 {#header_close#}
78587854
7859 {#header_open|@bitSizeOf#}7855 {#header_open|@bitSizeOf#}
lib/std/math.zig+1-1
...@@ -1684,7 +1684,7 @@ pub fn break_f80(x: f80) F80 {...@@ -1684,7 +1684,7 @@ pub fn break_f80(x: f80) F80 {
1684pub inline fn sign(i: anytype) @TypeOf(i) {1684pub inline fn sign(i: anytype) @TypeOf(i) {
1685 const T = @TypeOf(i);1685 const T = @TypeOf(i);
1686 return switch (@typeInfo(T)) {1686 return switch (@typeInfo(T)) {
1687 .Int, .ComptimeInt => @as(T, @boolToInt(i > 0)) - @boolToInt(i < 0),1687 .Int, .ComptimeInt => @as(T, @boolToInt(i > 0)) - @as(T, @boolToInt(i < 0)),
1688 .Float, .ComptimeFloat => @intToFloat(T, @boolToInt(i > 0)) - @intToFloat(T, @boolToInt(i < 0)),1688 .Float, .ComptimeFloat => @intToFloat(T, @boolToInt(i > 0)) - @intToFloat(T, @boolToInt(i < 0)),
1689 .Vector => |vinfo| blk: {1689 .Vector => |vinfo| blk: {
1690 switch (@typeInfo(vinfo.child)) {1690 switch (@typeInfo(vinfo.child)) {
lib/std/math/ilogb.zig+1-1
...@@ -48,7 +48,7 @@ fn ilogbX(comptime T: type, x: T) i32 {...@@ -48,7 +48,7 @@ fn ilogbX(comptime T: type, x: T) i32 {
48 }48 }
4949
50 // offset sign bit, exponent bits, and integer bit (if present) + bias50 // offset sign bit, exponent bits, and integer bit (if present) + bias
51 const offset = 1 + exponentBits + @boolToInt(T == f80) - exponentBias;51 const offset = 1 + exponentBits + @as(comptime_int, @boolToInt(T == f80)) - exponentBias;
52 return offset - @intCast(i32, @clz(u));52 return offset - @intCast(i32, @clz(u));
53 }53 }
5454
src/Sema.zig+3-3
...@@ -18445,9 +18445,9 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -18445,9 +18445,9 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
18445 const inst_data = sema.code.instructions.items(.data)[inst].un_node;18445 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
18446 const operand = try sema.resolveInst(inst_data.operand);18446 const operand = try sema.resolveInst(inst_data.operand);
18447 if (try sema.resolveMaybeUndefVal(operand)) |val| {18447 if (try sema.resolveMaybeUndefVal(operand)) |val| {
18448 if (val.isUndef()) return sema.addConstUndef(Type.initTag(.u1));18448 if (val.isUndef()) return sema.addConstUndef(Type.u1);
18449 const bool_ints = [2]Air.Inst.Ref{ .zero, .one };18449 if (val.toBool()) return sema.addConstant(Type.u1, Value.one);
18450 return bool_ints[@boolToInt(val.toBool())];18450 return sema.addConstant(Type.u1, Value.zero);
18451 }18451 }
18452 return block.addUnOp(.bool_to_int, operand);18452 return block.addUnOp(.bool_to_int, operand);
18453}18453}
src/translate_c.zig+1
...@@ -2494,6 +2494,7 @@ fn transCCast(...@@ -2494,6 +2494,7 @@ fn transCCast(
24942494
2495 if (isBoolRes(src_int_expr)) {2495 if (isBoolRes(src_int_expr)) {
2496 src_int_expr = try Tag.bool_to_int.create(c.arena, src_int_expr);2496 src_int_expr = try Tag.bool_to_int.create(c.arena, src_int_expr);
2497 return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr });
2497 }2498 }
24982499
2499 switch (cIntTypeCmp(dst_type, src_type)) {2500 switch (cIntTypeCmp(dst_type, src_type)) {
test/behavior/bool.zig+13-4
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const expect = std.testing.expect;3const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;
45
5test "bool literals" {6test "bool literals" {
6 try expect(true);7 try expect(true);
...@@ -12,14 +13,22 @@ test "cast bool to int" {...@@ -12,14 +13,22 @@ test "cast bool to int" {
1213
13 const t = true;14 const t = true;
14 const f = false;15 const f = false;
15 try expect(@boolToInt(t) == @as(u32, 1));16 try expectEqual(@as(u32, 1), @boolToInt(t));
16 try expect(@boolToInt(f) == @as(u32, 0));17 try expectEqual(@as(u32, 0), @boolToInt(f));
18 try expectEqual(-1, @bitCast(i1, @boolToInt(t)));
19 try expectEqual(0, @bitCast(i1, @boolToInt(f)));
20 try expectEqual(u1, @TypeOf(@boolToInt(t)));
21 try expectEqual(u1, @TypeOf(@boolToInt(f)));
17 try nonConstCastBoolToInt(t, f);22 try nonConstCastBoolToInt(t, f);
18}23}
1924
20fn nonConstCastBoolToInt(t: bool, f: bool) !void {25fn nonConstCastBoolToInt(t: bool, f: bool) !void {
21 try expect(@boolToInt(t) == @as(u32, 1));26 try expectEqual(@as(u32, 1), @boolToInt(t));
22 try expect(@boolToInt(f) == @as(u32, 0));27 try expectEqual(@as(u32, 0), @boolToInt(f));
28 try expectEqual(@as(i1, -1), @bitCast(i1, @boolToInt(t)));
29 try expectEqual(@as(i1, 0), @bitCast(i1, @boolToInt(f)));
30 try expectEqual(u1, @TypeOf(@boolToInt(t)));
31 try expectEqual(u1, @TypeOf(@boolToInt(f)));
23}32}
2433
25test "bool cmp" {34test "bool cmp" {