Skip to content

Commit 2702092

Browse files
committed
update uses of overflow arithmetic builtins
1 parent 3e39cd5 commit 2702092

29 files changed

+566
-435
lines changed

doc/langref.html.in

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5398,14 +5398,14 @@ pub fn parseU64(buf: []const u8, radix: u8) !u64 {
53985398
}
53995399

54005400
// x *= radix
5401-
if (@mulWithOverflow(u64, x, radix, &x)) {
5402-
return error.Overflow;
5403-
}
5401+
var ov = @mulWithOverflow(x, radix);
5402+
if (ov[1] != 0) return error.OverFlow;
5403+
54045404

54055405
// x += digit
5406-
if (@addWithOverflow(u64, x, digit, &x)) {
5407-
return error.Overflow;
5408-
}
5406+
ov = @addWithOverflow(ov[0], digit);
5407+
if (ov[1] != 0) return error.OverFlow;
5408+
x = ov[0];
54095409
}
54105410

54115411
return x;
@@ -5817,14 +5817,16 @@ test "merge error sets" {
58175817
{#code_begin|test|inferred_error_sets#}
58185818
// With an inferred error set
58195819
pub fn add_inferred(comptime T: type, a: T, b: T) !T {
5820-
var answer: T = undefined;
5821-
return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
5820+
const ov = @addWithOverflow(a, b);
5821+
if (ov[1] != 0) return error.Overflow;
5822+
return ov[0];
58225823
}
58235824

58245825
// With an explicit error set
58255826
pub fn add_explicit(comptime T: type, a: T, b: T) Error!T {
5826-
var answer: T = undefined;
5827-
return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
5827+
const ov = @addWithOverflow(a, b);
5828+
if (ov[1] != 0) return error.Overflow;
5829+
return ov[0];
58285830
}
58295831

58305832
const Error = error {
@@ -7617,11 +7619,9 @@ test "global assembly" {
76177619
</p>
76187620
{#header_close#}
76197621
{#header_open|@addWithOverflow#}
7620-
<pre>{#syntax#}@addWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre>
7622+
<pre>{#syntax#}@addWithOverflow(a: anytype, b: anytype) struct { @TypeOf(a, b), u1 }{#endsyntax#}</pre>
76217623
<p>
7622-
Performs {#syntax#}result.* = a + b{#endsyntax#}. If overflow or underflow occurs,
7623-
stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}.
7624-
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
7624+
Performs {#syntax#}a + b{#endsyntax#} and returns a tuple with the result and a possible overflow bit.
76257625
</p>
76267626
{#header_close#}
76277627
{#header_open|@alignCast#}
@@ -8680,11 +8680,9 @@ test "@wasmMemoryGrow" {
86808680
{#header_close#}
86818681

86828682
{#header_open|@mulWithOverflow#}
8683-
<pre>{#syntax#}@mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre>
8683+
<pre>{#syntax#}@mulWithOverflow(a: anytype, b: anytype) struct { @TypeOf(a, b), u1 }{#endsyntax#}</pre>
86848684
<p>
8685-
Performs {#syntax#}result.* = a * b{#endsyntax#}. If overflow or underflow occurs,
8686-
stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}.
8687-
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
8685+
Performs {#syntax#}a * b{#endsyntax#} and returns a tuple with the result and a possible overflow bit.
86888686
</p>
86898687
{#header_close#}
86908688

@@ -8958,15 +8956,13 @@ test "@setRuntimeSafety" {
89588956
{#header_close#}
89598957

89608958
{#header_open|@shlWithOverflow#}
8961-
<pre>{#syntax#}@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool{#endsyntax#}</pre>
8959+
<pre>{#syntax#}@shlWithOverflow(a: anytype, shift_amt: Log2T) struct { @TypeOf(a), u1 }{#endsyntax#}</pre>
89628960
<p>
8963-
Performs {#syntax#}result.* = a << b{#endsyntax#}. If overflow or underflow occurs,
8964-
stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}.
8965-
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
8961+
Performs {#syntax#}a << b{#endsyntax#} and returns a tuple with the result and a possible overflow bit.
89668962
</p>
89678963
<p>
8968-
The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).Int.bits){#endsyntax#} bits.
8969-
This is because {#syntax#}shift_amt >= @typeInfo(T).Int.bits{#endsyntax#} is undefined behavior.
8964+
The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(@TypeOf(a)).Int.bits){#endsyntax#} bits.
8965+
This is because {#syntax#}shift_amt >= @typeInfo(@TypeOf(a)).Int.bits{#endsyntax#} is undefined behavior.
89708966
</p>
89718967
{#see_also|@shlExact|@shrExact#}
89728968
{#header_close#}
@@ -9308,11 +9304,9 @@ fn doTheTest() !void {
93089304
{#header_close#}
93099305

93109306
{#header_open|@subWithOverflow#}
9311-
<pre>{#syntax#}@subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre>
9307+
<pre>{#syntax#}@subWithOverflow(a: anytype, b: anytype) struct { @TypeOf(a, b), u1 }{#endsyntax#}</pre>
93129308
<p>
9313-
Performs {#syntax#}result.* = a - b{#endsyntax#}. If overflow or underflow occurs,
9314-
stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}.
9315-
If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
9309+
Performs {#syntax#}a - b{#endsyntax#} and returns a tuple with the result and a possible overflow bit.
93169310
</p>
93179311
{#header_close#}
93189312

@@ -9759,11 +9753,11 @@ const print = @import("std").debug.print;
97599753
pub fn main() void {
97609754
var byte: u8 = 255;
97619755

9762-
var result: u8 = undefined;
9763-
if (@addWithOverflow(u8, byte, 10, &result)) {
9764-
print("overflowed result: {}\n", .{result});
9756+
const ov = @addWithOverflow(byte, 10);
9757+
if (ov[1] != 0) {
9758+
print("overflowed result: {}\n", .{ov[0]});
97659759
} else {
9766-
print("result: {}\n", .{result});
9760+
print("result: {}\n", .{ov[0]});
97679761
}
97689762
}
97699763
{#code_end#}

lib/compiler_rt/trunctfxf2.zig

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,16 @@ pub fn __trunctfxf2(a: f128) callconv(.C) f80 {
4949
const round_bits = a_abs & round_mask;
5050
if (round_bits > halfway) {
5151
// Round to nearest
52-
const carry = @boolToInt(@addWithOverflow(u64, res.fraction, 1, &res.fraction));
53-
res.exp += carry;
54-
res.fraction |= @as(u64, carry) << 63; // Restore integer bit after carry
52+
const ov = @addWithOverflow(res.fraction, 1);
53+
res.fraction = ov[0];
54+
res.exp += ov[1];
55+
res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
5556
} else if (round_bits == halfway) {
5657
// Ties to even
57-
const carry = @boolToInt(@addWithOverflow(u64, res.fraction, res.fraction & 1, &res.fraction));
58-
res.exp += carry;
59-
res.fraction |= @as(u64, carry) << 63; // Restore integer bit after carry
58+
const ov = @addWithOverflow(res.fraction, res.fraction & 1);
59+
res.fraction = ov[0];
60+
res.exp += ov[1];
61+
res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
6062
}
6163
if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals
6264
}

lib/std/compress/deflate/compressor_test.zig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ test "deflate/inflate" {
172172
defer testing.allocator.free(large_data_chunk);
173173
// fill with random data
174174
for (large_data_chunk) |_, i| {
175-
var mul: u8 = @truncate(u8, i);
176-
_ = @mulWithOverflow(u8, mul, mul, &mul);
177-
large_data_chunk[i] = mul;
175+
large_data_chunk[i] = @truncate(u8, i) *% @truncate(u8, i);
178176
}
179177
try testToFromWithLimit(large_data_chunk, limits);
180178
}

lib/std/crypto/pcurves/p256/p256_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
7575
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
7676
@setRuntimeSafety(mode == .Debug);
7777

78-
var t: u64 = undefined;
79-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
80-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
81-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
78+
const ov1 = @addWithOverflow(arg2, arg3);
79+
const ov2 = @addWithOverflow(ov1[0], arg1);
80+
out1.* = ov2[0];
81+
out2.* = ov1[1] | ov2[1];
8282
}
8383

8484
/// The function subborrowxU64 is a subtraction with borrow.
@@ -97,10 +97,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
9797
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
9898
@setRuntimeSafety(mode == .Debug);
9999

100-
var t: u64 = undefined;
101-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
102-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
103-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
100+
const ov1 = @subWithOverflow(arg2, arg3);
101+
const ov2 = @subWithOverflow(ov1[0], arg1);
102+
out1.* = ov2[0];
103+
out2.* = ov1[1] | ov2[1];
104104
}
105105

106106
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/p256/p256_scalar_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
7575
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
7676
@setRuntimeSafety(mode == .Debug);
7777

78-
var t: u64 = undefined;
79-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
80-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
81-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
78+
const ov1 = @addWithOverflow(arg2, arg3);
79+
const ov2 = @addWithOverflow(ov1[0], arg1);
80+
out1.* = ov2[0];
81+
out2.* = ov1[1] | ov2[1];
8282
}
8383

8484
/// The function subborrowxU64 is a subtraction with borrow.
@@ -97,10 +97,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
9797
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
9898
@setRuntimeSafety(mode == .Debug);
9999

100-
var t: u64 = undefined;
101-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
102-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
103-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
100+
const ov1 = @subWithOverflow(arg2, arg3);
101+
const ov2 = @subWithOverflow(ov1[0], arg1);
102+
out1.* = ov2[0];
103+
out2.* = ov1[1] | ov2[1];
104104
}
105105

106106
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/p384/p384_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [6]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/p384/p384_scalar_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [6]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/secp256k1/secp256k1_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/secp256k1/secp256k1_scalar_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/salsa20.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ fn SalsaNonVecImpl(comptime rounds: comptime_int) type {
263263
while (j < 64) : (j += 1) {
264264
xout[j] ^= buf[j];
265265
}
266-
ctx[9] += @boolToInt(@addWithOverflow(u32, ctx[8], 1, &ctx[8]));
266+
const ov = @addWithOverflow(ctx[8], 1);
267+
ctx[8] = ov[0];
268+
ctx[9] += ov[1];
267269
}
268270
if (i < in.len) {
269271
salsaCore(x[0..], ctx, true);

lib/std/crypto/utils.zig

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,19 @@ pub fn timingSafeAdd(comptime T: type, a: []const T, b: []const T, result: []T,
8787
if (endian == .Little) {
8888
var i: usize = 0;
8989
while (i < len) : (i += 1) {
90-
const tmp = @boolToInt(@addWithOverflow(u8, a[i], b[i], &result[i]));
91-
carry = tmp | @boolToInt(@addWithOverflow(u8, result[i], carry, &result[i]));
90+
const ov1 = @addWithOverflow(a[i], b[i]);
91+
const ov2 = @addWithOverflow(ov1[0], carry);
92+
result[i] = ov2[0];
93+
carry = ov1[1] | ov2[1];
9294
}
9395
} else {
9496
var i: usize = len;
9597
while (i != 0) {
9698
i -= 1;
97-
const tmp = @boolToInt(@addWithOverflow(u8, a[i], b[i], &result[i]));
98-
carry = tmp | @boolToInt(@addWithOverflow(u8, result[i], carry, &result[i]));
99+
const ov1 = @addWithOverflow(a[i], b[i]);
100+
const ov2 = @addWithOverflow(ov1[0], carry);
101+
result[i] = ov2[0];
102+
carry = ov1[1] | ov2[1];
99103
}
100104
}
101105
return @bitCast(bool, carry);
@@ -110,15 +114,19 @@ pub fn timingSafeSub(comptime T: type, a: []const T, b: []const T, result: []T,
110114
if (endian == .Little) {
111115
var i: usize = 0;
112116
while (i < len) : (i += 1) {
113-
const tmp = @boolToInt(@subWithOverflow(u8, a[i], b[i], &result[i]));
114-
borrow = tmp | @boolToInt(@subWithOverflow(u8, result[i], borrow, &result[i]));
117+
const ov1 = @subWithOverflow(a[i], b[i]);
118+
const ov2 = @subWithOverflow(ov1[0], borrow);
119+
result[i] = ov2[0];
120+
borrow = ov1[1] | ov2[1];
115121
}
116122
} else {
117123
var i: usize = len;
118124
while (i != 0) {
119125
i -= 1;
120-
const tmp = @boolToInt(@subWithOverflow(u8, a[i], b[i], &result[i]));
121-
borrow = tmp | @boolToInt(@subWithOverflow(u8, result[i], borrow, &result[i]));
126+
const ov1 = @subWithOverflow(a[i], b[i]);
127+
const ov2 = @subWithOverflow(ov1[0], borrow);
128+
result[i] = ov2[0];
129+
borrow = ov1[1] | ov2[1];
122130
}
123131
}
124132
return @bitCast(bool, borrow);

0 commit comments

Comments
 (0)