diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index ddcda677d6..68a0c7f740 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -1405,13 +1405,16 @@ pub const Mutable = struct { r.normalize(r.len); } } else { - r.copy(a); - if (r.len < req_limbs) { + if (a.limbs.len < req_limbs) { // Integer fits within target bits, no wrapping required. + r.copy(a); return; } - r.len = req_limbs; + r.copy(.{ + .positive = a.positive, + .limbs = a.limbs[0..req_limbs], + }); r.limbs[r.len - 1] &= mask; r.normalize(r.len); diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index 78762d4fca..00594b640f 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -1654,6 +1654,18 @@ test "big.int truncate negative multi to single" { try testing.expect((try a.to(i17)) == 0); } +test "big.int truncate multi unsigned many" { + var a = try Managed.initSet(testing.allocator, 1); + defer a.deinit(); + try a.shiftLeft(a, 1023); + + var b = try Managed.init(testing.allocator); + defer b.deinit(); + try b.truncate(a.toConst(), .signed, @bitSizeOf(i1)); + + try testing.expect((try b.to(i1)) == 0); +} + test "big.int saturate single signed positive" { var a = try Managed.initSet(testing.allocator, 0xBBBB_BBBB); defer a.deinit(); diff --git a/src/Sema.zig b/src/Sema.zig index b01e4539b0..b76274c446 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9477,14 +9477,18 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } const target = sema.mod.getTarget(); - const src_info = operand_ty.intInfo(target); const dest_info = dest_ty.intInfo(target); - if (src_info.bits == 0 or dest_info.bits == 0) { + if (dest_info.bits == 0) { return sema.addConstant(dest_ty, Value.zero); } if (!src_is_comptime_int) { + const src_info = operand_ty.intInfo(target); + if (src_info.bits == 0) { + return sema.addConstant(dest_ty, Value.zero); + } + if (src_info.signedness != dest_info.signedness) { return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{ @tagName(dest_info.signedness), operand_ty, diff --git a/test/behavior.zig b/test/behavior.zig index a5f6ba4b99..be55bb85e6 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -51,6 +51,7 @@ test { _ = @import("behavior/switch.zig"); _ = @import("behavior/this.zig"); _ = @import("behavior/translate_c_macros.zig"); + _ = @import("behavior/truncate.zig"); _ = @import("behavior/underscore.zig"); _ = @import("behavior/union.zig"); _ = @import("behavior/usingnamespace.zig"); @@ -163,7 +164,6 @@ test { _ = @import("behavior/switch_prong_err_enum.zig"); _ = @import("behavior/switch_prong_implicit_cast.zig"); _ = @import("behavior/switch_stage1.zig"); - _ = @import("behavior/truncate.zig"); _ = @import("behavior/try.zig"); _ = @import("behavior/tuple.zig"); _ = @import("behavior/type.zig");