| author | |
| committer | |
| log | 9a1608509300fcdf118d82063bbf1481a10ca551 |
| tree | 0c3b2cdc5f9462c26c9e41edcabc793ce66970e2 |
| parent | 537e2808e04fc34bb2015433895a57c15118eb28 |
| parent | 52ebba6bdf5662353ce11a701a3361cc0616c01c |
| signature |
Sema: Updated `zirShl` to compute `shl_exact` with `comptime_int` LHS using `shl`3 files changed, 12 insertions(+), 17 deletions(-)
doc/langref.html.in+5| ... | @@ -9163,6 +9163,11 @@ test "@setRuntimeSafety" { | ... | @@ -9163,6 +9163,11 @@ test "@setRuntimeSafety" { |
| 9163 | The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).Int.bits){#endsyntax#} bits. | 9163 | The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).Int.bits){#endsyntax#} bits. |
| 9164 | This is because {#syntax#}shift_amt >= @typeInfo(T).Int.bits{#endsyntax#} is undefined behavior. | 9164 | This is because {#syntax#}shift_amt >= @typeInfo(T).Int.bits{#endsyntax#} is undefined behavior. |
| 9165 | </p> | 9165 | </p> |
| 9166 | <p> | ||
| 9167 | {#syntax#}comptime_int{#endsyntax#} is modeled as an integer with an infinite number of bits, | ||
| 9168 | meaning that in such case, {#syntax#}@shlExact{#endsyntax#} always produces a result and | ||
| 9169 | cannot produce a compile error. | ||
| 9170 | </p> | ||
| 9166 | {#see_also|@shrExact|@shlWithOverflow#} | 9171 | {#see_also|@shrExact|@shlWithOverflow#} |
| 9167 | {#header_close#} | 9172 | {#header_close#} |
| 9168 | 9173 |
src/Sema.zig+5-17| ... | @@ -13247,32 +13247,20 @@ fn zirShl( | ... | @@ -13247,32 +13247,20 @@ fn zirShl( |
| 13247 | } | 13247 | } |
| 13248 | break :rs rhs_src; | 13248 | break :rs rhs_src; |
| 13249 | }; | 13249 | }; |
| 13250 | 13250 | const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) | |
| 13251 | const val = switch (air_tag) { | 13251 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) |
| 13252 | else switch (air_tag) { | ||
| 13252 | .shl_exact => val: { | 13253 | .shl_exact => val: { |
| 13253 | const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod); | 13254 | const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod); |
| 13254 | if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | ||
| 13255 | break :val shifted.wrapped_result; | ||
| 13256 | } | ||
| 13257 | if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) { | 13255 | if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) { |
| 13258 | break :val shifted.wrapped_result; | 13256 | break :val shifted.wrapped_result; |
| 13259 | } | 13257 | } |
| 13260 | return sema.fail(block, src, "operation caused overflow", .{}); | 13258 | return sema.fail(block, src, "operation caused overflow", .{}); |
| 13261 | }, | 13259 | }, |
| 13262 | 13260 | .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod), | |
| 13263 | .shl_sat => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) | 13261 | .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod), |
| 13264 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) | ||
| 13265 | else | ||
| 13266 | try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod), | ||
| 13267 | |||
| 13268 | .shl => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) | ||
| 13269 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) | ||
| 13270 | else | ||
| 13271 | try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod), | ||
| 13272 | |||
| 13273 | else => unreachable, | 13262 | else => unreachable, |
| 13274 | }; | 13263 | }; |
| 13275 | |||
| 13276 | return Air.internedToRef(val.toIntern()); | 13264 | return Air.internedToRef(val.toIntern()); |
| 13277 | } else lhs_src; | 13265 | } else lhs_src; |
| 13278 | 13266 |
test/behavior/math.zig+2| ... | @@ -1314,6 +1314,8 @@ test "exact shift left" { | ... | @@ -1314,6 +1314,8 @@ test "exact shift left" { |
| 1314 | 1314 | ||
| 1315 | try testShlExact(0b00110101); | 1315 | try testShlExact(0b00110101); |
| 1316 | try comptime testShlExact(0b00110101); | 1316 | try comptime testShlExact(0b00110101); |
| 1317 | |||
| 1318 | if (@shlExact(1, 1) != 2) @compileError("should be 2"); | ||
| 1317 | } | 1319 | } |
| 1318 | fn testShlExact(x: u8) !void { | 1320 | fn testShlExact(x: u8) !void { |
| 1319 | const shifted = @shlExact(x, 2); | 1321 | const shifted = @shlExact(x, 2); |