diff --git a/doc/langref.html.in b/doc/langref.html.in index c07633273b..7b5d086f2d 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -9163,6 +9163,11 @@ test "@setRuntimeSafety" { The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).Int.bits){#endsyntax#} bits. This is because {#syntax#}shift_amt >= @typeInfo(T).Int.bits{#endsyntax#} is undefined behavior.
++ {#syntax#}comptime_int{#endsyntax#} is modeled as an integer with an infinite number of bits, + meaning that in such case, {#syntax#}@shlExact{#endsyntax#} always produces a result and + cannot produce a compile error. +
{#see_also|@shrExact|@shlWithOverflow#} {#header_close#} diff --git a/src/Sema.zig b/src/Sema.zig index a2ed81161b..c6cb1a8b2f 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -13247,32 +13247,20 @@ fn zirShl( } break :rs rhs_src; }; - - const val = switch (air_tag) { + const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) + try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) + else switch (air_tag) { .shl_exact => val: { const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod); - if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) { - break :val shifted.wrapped_result; - } if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) { break :val shifted.wrapped_result; } return sema.fail(block, src, "operation caused overflow", .{}); }, - - .shl_sat => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) - try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) - else - try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod), - - .shl => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) - try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) - else - try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod), - + .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod), + .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod), else => unreachable, }; - return Air.internedToRef(val.toIntern()); } else lhs_src; diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 3d3c282854..4f9f7a673d 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -1314,6 +1314,8 @@ test "exact shift left" { try testShlExact(0b00110101); try comptime testShlExact(0b00110101); + + if (@shlExact(1, 1) != 2) @compileError("should be 2"); } fn testShlExact(x: u8) !void { const shifted = @shlExact(x, 2);