authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-30 15:21:50+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-30 12:22:07-07:00
logd3b4b2edf140c002da4c9c1396c26e0f66835eb0
tree84fe3e9442f391eb19c79e1a51dc11c385884740
parent01d19a8d3cdd52ad50f45bfb8666b56ccf8d3a22

Sema: shift of comptime int with runtime value

Closes #12290

8 files changed, 167 insertions(+), 59 deletions(-)

src/AstGen.zig+22-11
...@@ -226,6 +226,8 @@ pub const ResultLoc = union(enum) {...@@ -226,6 +226,8 @@ pub const ResultLoc = union(enum) {
226 ref,226 ref,
227 /// The expression will be coerced into this type, but it will be evaluated as an rvalue.227 /// The expression will be coerced into this type, but it will be evaluated as an rvalue.
228 ty: Zir.Inst.Ref,228 ty: Zir.Inst.Ref,
229 /// Same as `ty` but for shift operands.
230 ty_shift_operand: Zir.Inst.Ref,
229 /// Same as `ty` but it is guaranteed that Sema will additionally perform the coercion,231 /// Same as `ty` but it is guaranteed that Sema will additionally perform the coercion,
230 /// so no `as` instruction needs to be emitted.232 /// so no `as` instruction needs to be emitted.
231 coerced_ty: Zir.Inst.Ref,233 coerced_ty: Zir.Inst.Ref,
...@@ -259,7 +261,7 @@ pub const ResultLoc = union(enum) {...@@ -259,7 +261,7 @@ pub const ResultLoc = union(enum) {
259 fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy {261 fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy {
260 switch (rl) {262 switch (rl) {
261 // In this branch there will not be any store_to_block_ptr instructions.263 // In this branch there will not be any store_to_block_ptr instructions.
262 .none, .ty, .coerced_ty, .ref => return .{264 .none, .ty, .ty_shift_operand, .coerced_ty, .ref => return .{
263 .tag = .break_operand,265 .tag = .break_operand,
264 .elide_store_to_block_ptr_instructions = false,266 .elide_store_to_block_ptr_instructions = false,
265 },267 },
...@@ -302,6 +304,14 @@ pub const ResultLoc = union(enum) {...@@ -302,6 +304,14 @@ pub const ResultLoc = union(enum) {
302 else => rl,304 else => rl,
303 };305 };
304 }306 }
307
308 fn zirTag(rl: ResultLoc) Zir.Inst.Tag {
309 return switch (rl) {
310 .ty => .as_node,
311 .ty_shift_operand => .as_shift_operand,
312 else => unreachable,
313 };
314 }
305};315};
306316
307pub const align_rl: ResultLoc = .{ .ty = .u29_type };317pub const align_rl: ResultLoc = .{ .ty = .u29_type };
...@@ -1385,7 +1395,7 @@ fn arrayInitExpr(...@@ -1385,7 +1395,7 @@ fn arrayInitExpr(
1385 const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon;1395 const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon;
1386 return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag);1396 return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag);
1387 },1397 },
1388 .ty, .coerced_ty => {1398 .ty, .ty_shift_operand, .coerced_ty => {
1389 const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon;1399 const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon;
1390 const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag);1400 const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag);
1391 return rvalue(gz, rl, result, node);1401 return rvalue(gz, rl, result, node);
...@@ -1631,7 +1641,7 @@ fn structInitExpr(...@@ -1631,7 +1641,7 @@ fn structInitExpr(
1631 return structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon);1641 return structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon);
1632 }1642 }
1633 },1643 },
1634 .ty, .coerced_ty => |ty_inst| {1644 .ty, .ty_shift_operand, .coerced_ty => |ty_inst| {
1635 if (struct_init.ast.type_expr == 0) {1645 if (struct_init.ast.type_expr == 0) {
1636 const result = try structInitExprRlNone(gz, scope, node, struct_init, ty_inst, .struct_init_anon);1646 const result = try structInitExprRlNone(gz, scope, node, struct_init, ty_inst, .struct_init_anon);
1637 return rvalue(gz, rl, result, node);1647 return rvalue(gz, rl, result, node);
...@@ -2327,6 +2337,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2327,6 +2337,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2327 .anyframe_type,2337 .anyframe_type,
2328 .as,2338 .as,
2329 .as_node,2339 .as_node,
2340 .as_shift_operand,
2330 .bit_and,2341 .bit_and,
2331 .bitcast,2342 .bitcast,
2332 .bit_or,2343 .bit_or,
...@@ -2497,7 +2508,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2497,7 +2508,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2497 .field_parent_ptr,2508 .field_parent_ptr,
2498 .maximum,2509 .maximum,
2499 .minimum,2510 .minimum,
2500 .builtin_async_call,
2501 .c_import,2511 .c_import,
2502 .@"resume",2512 .@"resume",
2503 .@"await",2513 .@"await",
...@@ -7278,7 +7288,7 @@ fn as(...@@ -7278,7 +7288,7 @@ fn as(
7278) InnerError!Zir.Inst.Ref {7288) InnerError!Zir.Inst.Ref {
7279 const dest_type = try typeExpr(gz, scope, lhs);7289 const dest_type = try typeExpr(gz, scope, lhs);
7280 switch (rl) {7290 switch (rl) {
7281 .none, .discard, .ref, .ty, .coerced_ty => {7291 .none, .discard, .ref, .ty, .ty_shift_operand, .coerced_ty => {
7282 const result = try reachableExpr(gz, scope, .{ .ty = dest_type }, rhs, node);7292 const result = try reachableExpr(gz, scope, .{ .ty = dest_type }, rhs, node);
7283 return rvalue(gz, rl, result, node);7293 return rvalue(gz, rl, result, node);
7284 },7294 },
...@@ -7959,7 +7969,8 @@ fn builtinCall(...@@ -7959,7 +7969,8 @@ fn builtinCall(
7959 return rvalue(gz, rl, result, node);7969 return rvalue(gz, rl, result, node);
7960 },7970 },
7961 .async_call => {7971 .async_call => {
7962 const result = try gz.addPlNode(.builtin_async_call, node, Zir.Inst.AsyncCall{7972 const result = try gz.addExtendedPayload(.builtin_async_call, Zir.Inst.AsyncCall{
7973 .node = gz.nodeIndexToRelative(node),
7963 .frame_buffer = try expr(gz, scope, .none, params[0]),7974 .frame_buffer = try expr(gz, scope, .none, params[0]),
7964 .result_ptr = try expr(gz, scope, .none, params[1]),7975 .result_ptr = try expr(gz, scope, .none, params[1]),
7965 .fn_ptr = try expr(gz, scope, .none, params[2]),7976 .fn_ptr = try expr(gz, scope, .none, params[2]),
...@@ -8178,7 +8189,7 @@ fn shiftOp(...@@ -8178,7 +8189,7 @@ fn shiftOp(
8178) InnerError!Zir.Inst.Ref {8189) InnerError!Zir.Inst.Ref {
8179 const lhs = try expr(gz, scope, .none, lhs_node);8190 const lhs = try expr(gz, scope, .none, lhs_node);
8180 const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node);8191 const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node);
8181 const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, rhs_node);8192 const rhs = try expr(gz, scope, .{ .ty_shift_operand = log2_int_type }, rhs_node);
8182 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{8193 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
8183 .lhs = lhs,8194 .lhs = lhs,
8184 .rhs = rhs,8195 .rhs = rhs,
...@@ -9409,7 +9420,7 @@ fn rvalue(...@@ -9409,7 +9420,7 @@ fn rvalue(
9409 }9420 }
9410 return indexToRef(gop.value_ptr.*);9421 return indexToRef(gop.value_ptr.*);
9411 },9422 },
9412 .ty => |ty_inst| {9423 .ty, .ty_shift_operand => |ty_inst| {
9413 // Quickly eliminate some common, unnecessary type coercion.9424 // Quickly eliminate some common, unnecessary type coercion.
9414 const as_ty = @as(u64, @enumToInt(Zir.Inst.Ref.type_type)) << 32;9425 const as_ty = @as(u64, @enumToInt(Zir.Inst.Ref.type_type)) << 32;
9415 const as_comptime_int = @as(u64, @enumToInt(Zir.Inst.Ref.comptime_int_type)) << 32;9426 const as_comptime_int = @as(u64, @enumToInt(Zir.Inst.Ref.comptime_int_type)) << 32;
...@@ -9470,7 +9481,7 @@ fn rvalue(...@@ -9470,7 +9481,7 @@ fn rvalue(
9470 => return result, // type of result is already correct9481 => return result, // type of result is already correct
94719482
9472 // Need an explicit type coercion instruction.9483 // Need an explicit type coercion instruction.
9473 else => return gz.addPlNode(.as_node, src_node, Zir.Inst.As{9484 else => return gz.addPlNode(rl.zirTag(), src_node, Zir.Inst.As{
9474 .dest_type = ty_inst,9485 .dest_type = ty_inst,
9475 .operand = result,9486 .operand = result,
9476 }),9487 }),
...@@ -10350,7 +10361,7 @@ const GenZir = struct {...@@ -10350,7 +10361,7 @@ const GenZir = struct {
10350 // we emit ZIR for the block break instructions to have the result values,10361 // we emit ZIR for the block break instructions to have the result values,
10351 // and then rvalue() on that to pass the value to the result location.10362 // and then rvalue() on that to pass the value to the result location.
10352 switch (parent_rl) {10363 switch (parent_rl) {
10353 .ty, .coerced_ty => |ty_inst| {10364 .ty, .ty_shift_operand, .coerced_ty => |ty_inst| {
10354 gz.rl_ty_inst = ty_inst;10365 gz.rl_ty_inst = ty_inst;
10355 gz.break_result_loc = parent_rl;10366 gz.break_result_loc = parent_rl;
10356 },10367 },
...@@ -11506,7 +11517,7 @@ const GenZir = struct {...@@ -11506,7 +11517,7 @@ const GenZir = struct {
11506 fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void {11517 fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void {
11507 switch (rl) {11518 switch (rl) {
11508 .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node),11519 .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node),
11509 .ty => _ = try gz.addUnNode(.ret_node, operand, node),11520 .ty, .ty_shift_operand => _ = try gz.addUnNode(.ret_node, operand, node),
11510 else => unreachable,11521 else => unreachable,
11511 }11522 }
11512 }11523 }
src/Autodoc.zig+1-1
...@@ -1888,7 +1888,7 @@ fn walkInstruction(...@@ -1888,7 +1888,7 @@ fn walkInstruction(
1888 .expr = .{ .typeInfo = operand_index },1888 .expr = .{ .typeInfo = operand_index },
1889 };1889 };
1890 },1890 },
1891 .as_node => {1891 .as_node, .as_shift_operand => {
1892 const pl_node = data[inst_index].pl_node;1892 const pl_node = data[inst_index].pl_node;
1893 const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);1893 const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);
1894 const dest_type_walk = try self.walkRef(1894 const dest_type_walk = try self.walkRef(
src/Sema.zig+76-26
...@@ -712,6 +712,7 @@ fn analyzeBodyInner(...@@ -712,6 +712,7 @@ fn analyzeBodyInner(
712 .vector_type => try sema.zirVectorType(block, inst),712 .vector_type => try sema.zirVectorType(block, inst),
713 .as => try sema.zirAs(block, inst),713 .as => try sema.zirAs(block, inst),
714 .as_node => try sema.zirAsNode(block, inst),714 .as_node => try sema.zirAsNode(block, inst),
715 .as_shift_operand => try sema.zirAsShiftOperand(block, inst),
715 .bit_and => try sema.zirBitwise(block, inst, .bit_and),716 .bit_and => try sema.zirBitwise(block, inst, .bit_and),
716 .bit_not => try sema.zirBitNot(block, inst),717 .bit_not => try sema.zirBitNot(block, inst),
717 .bit_or => try sema.zirBitwise(block, inst, .bit_or),718 .bit_or => try sema.zirBitwise(block, inst, .bit_or),
...@@ -848,7 +849,6 @@ fn analyzeBodyInner(...@@ -848,7 +849,6 @@ fn analyzeBodyInner(
848 .mul_add => try sema.zirMulAdd(block, inst),849 .mul_add => try sema.zirMulAdd(block, inst),
849 .builtin_call => try sema.zirBuiltinCall(block, inst),850 .builtin_call => try sema.zirBuiltinCall(block, inst),
850 .field_parent_ptr => try sema.zirFieldParentPtr(block, inst),851 .field_parent_ptr => try sema.zirFieldParentPtr(block, inst),
851 .builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst),
852 .@"resume" => try sema.zirResume(block, inst),852 .@"resume" => try sema.zirResume(block, inst),
853 .@"await" => try sema.zirAwait(block, inst),853 .@"await" => try sema.zirAwait(block, inst),
854 .array_base_ptr => try sema.zirArrayBasePtr(block, inst),854 .array_base_ptr => try sema.zirArrayBasePtr(block, inst),
...@@ -956,6 +956,7 @@ fn analyzeBodyInner(...@@ -956,6 +956,7 @@ fn analyzeBodyInner(
956 .error_to_int => try sema.zirErrorToInt( block, extended),956 .error_to_int => try sema.zirErrorToInt( block, extended),
957 .int_to_error => try sema.zirIntToError( block, extended),957 .int_to_error => try sema.zirIntToError( block, extended),
958 .reify => try sema.zirReify( block, extended, inst),958 .reify => try sema.zirReify( block, extended, inst),
959 .builtin_async_call => try sema.zirBuiltinAsyncCall( block, extended),
959 // zig fmt: on960 // zig fmt: on
960 .fence => {961 .fence => {
961 try sema.zirFence(block, extended);962 try sema.zirFence(block, extended);
...@@ -8257,7 +8258,7 @@ fn zirAs(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst...@@ -8257,7 +8258,7 @@ fn zirAs(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst
8257 defer tracy.end();8258 defer tracy.end();
82588259
8259 const bin_inst = sema.code.instructions.items(.data)[inst].bin;8260 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
8260 return sema.analyzeAs(block, sema.src, bin_inst.lhs, bin_inst.rhs);8261 return sema.analyzeAs(block, sema.src, bin_inst.lhs, bin_inst.rhs, false);
8261}8262}
82628263
8263fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8264fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -8267,7 +8268,17 @@ fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -8267,7 +8268,17 @@ fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
8267 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;8268 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
8268 const src = inst_data.src();8269 const src = inst_data.src();
8269 const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data;8270 const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data;
8270 return sema.analyzeAs(block, src, extra.dest_type, extra.operand);8271 return sema.analyzeAs(block, src, extra.dest_type, extra.operand, false);
8272}
8273
8274fn zirAsShiftOperand(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8275 const tracy = trace(@src());
8276 defer tracy.end();
8277
8278 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
8279 const src = inst_data.src();
8280 const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data;
8281 return sema.analyzeAs(block, src, extra.dest_type, extra.operand, true);
8271}8282}
82728283
8273fn analyzeAs(8284fn analyzeAs(
...@@ -8276,6 +8287,7 @@ fn analyzeAs(...@@ -8276,6 +8287,7 @@ fn analyzeAs(
8276 src: LazySrcLoc,8287 src: LazySrcLoc,
8277 zir_dest_type: Zir.Inst.Ref,8288 zir_dest_type: Zir.Inst.Ref,
8278 zir_operand: Zir.Inst.Ref,8289 zir_operand: Zir.Inst.Ref,
8290 no_cast_to_comptime_int: bool,
8279) CompileError!Air.Inst.Ref {8291) CompileError!Air.Inst.Ref {
8280 const is_ret = if (Zir.refToIndex(zir_dest_type)) |ptr_index|8292 const is_ret = if (Zir.refToIndex(zir_dest_type)) |ptr_index|
8281 sema.code.instructions.items(.tag)[ptr_index] == .ret_type8293 sema.code.instructions.items(.tag)[ptr_index] == .ret_type
...@@ -8287,7 +8299,7 @@ fn analyzeAs(...@@ -8287,7 +8299,7 @@ fn analyzeAs(
8287 if (dest_ty.zigTypeTag() == .NoReturn) {8299 if (dest_ty.zigTypeTag() == .NoReturn) {
8288 return sema.fail(block, src, "cannot cast to noreturn", .{});8300 return sema.fail(block, src, "cannot cast to noreturn", .{});
8289 }8301 }
8290 return sema.coerceExtra(block, dest_ty, operand, src, true, is_ret) catch |err| switch (err) {8302 return sema.coerceExtra(block, dest_ty, operand, src, .{ .is_ret = is_ret, .no_cast_to_comptime_int = no_cast_to_comptime_int }) catch |err| switch (err) {
8291 error.NotCoercible => unreachable,8303 error.NotCoercible => unreachable,
8292 else => |e| return e,8304 else => |e| return e,
8293 };8305 };
...@@ -10491,7 +10503,12 @@ fn zirShl(...@@ -10491,7 +10503,12 @@ fn zirShl(
1049110503
10492 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {10504 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {
10493 if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty);10505 if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty);
10494 const rhs_val = maybe_rhs_val orelse break :rs rhs_src;10506 const rhs_val = maybe_rhs_val orelse {
10507 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
10508 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be a comptime known", .{});
10509 }
10510 break :rs rhs_src;
10511 };
1049510512
10496 const val = switch (air_tag) {10513 const val = switch (air_tag) {
10497 .shl_exact => val: {10514 .shl_exact => val: {
...@@ -10615,7 +10632,10 @@ fn zirShr(...@@ -10615,7 +10632,10 @@ fn zirShr(
10615 const target = sema.mod.getTarget();10632 const target = sema.mod.getTarget();
10616 const scalar_ty = lhs_ty.scalarType();10633 const scalar_ty = lhs_ty.scalarType();
1061710634
10618 const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: {10635 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);
10636 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs);
10637
10638 const runtime_src = if (maybe_rhs_val) |rhs_val| rs: {
10619 if (rhs_val.isUndef()) {10639 if (rhs_val.isUndef()) {
10620 return sema.addConstUndef(lhs_ty);10640 return sema.addConstUndef(lhs_ty);
10621 }10641 }
...@@ -10647,7 +10667,7 @@ fn zirShr(...@@ -10647,7 +10667,7 @@ fn zirShr(
10647 });10667 });
10648 }10668 }
10649 }10669 }
10650 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {10670 if (maybe_lhs_val) |lhs_val| {
10651 if (lhs_val.isUndef()) {10671 if (lhs_val.isUndef()) {
10652 return sema.addConstUndef(lhs_ty);10672 return sema.addConstUndef(lhs_ty);
10653 }10673 }
...@@ -10665,6 +10685,10 @@ fn zirShr(...@@ -10665,6 +10685,10 @@ fn zirShr(
10665 }10685 }
10666 } else rhs_src;10686 } else rhs_src;
1066710687
10688 if (maybe_rhs_val == null and scalar_ty.zigTypeTag() == .ComptimeInt) {
10689 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be a comptime known", .{});
10690 }
10691
10668 try sema.requireRuntimeBlock(block, src, runtime_src);10692 try sema.requireRuntimeBlock(block, src, runtime_src);
10669 const result = try block.addBinOp(air_tag, lhs, rhs);10693 const result = try block.addBinOp(air_tag, lhs, rhs);
10670 if (block.wantSafety()) {10694 if (block.wantSafety()) {
...@@ -15385,7 +15409,7 @@ fn analyzeRet(...@@ -15385,7 +15409,7 @@ fn analyzeRet(
15385 if (sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) {15409 if (sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) {
15386 try sema.addToInferredErrorSet(uncasted_operand);15410 try sema.addToInferredErrorSet(uncasted_operand);
15387 }15411 }
15388 const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, true, true) catch |err| switch (err) {15412 const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) {
15389 error.NotCoercible => unreachable,15413 error.NotCoercible => unreachable,
15390 else => |e| return e,15414 else => |e| return e,
15391 };15415 };
...@@ -19652,9 +19676,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -19652,9 +19676,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
19652 });19676 });
19653}19677}
1965419678
19655fn zirBuiltinAsyncCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19679fn zirBuiltinAsyncCall(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
19656 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;19680 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
19657 const src = inst_data.src();19681 const src = LazySrcLoc.nodeOffset(extra.node);
19658 return sema.failWithUseOfAsync(block, src);19682 return sema.failWithUseOfAsync(block, src);
19659}19683}
1966019684
...@@ -22542,7 +22566,7 @@ fn coerce(...@@ -22542,7 +22566,7 @@ fn coerce(
22542 inst: Air.Inst.Ref,22566 inst: Air.Inst.Ref,
22543 inst_src: LazySrcLoc,22567 inst_src: LazySrcLoc,
22544) CompileError!Air.Inst.Ref {22568) CompileError!Air.Inst.Ref {
22545 return sema.coerceExtra(block, dest_ty_unresolved, inst, inst_src, true, false) catch |err| switch (err) {22569 return sema.coerceExtra(block, dest_ty_unresolved, inst, inst_src, .{}) catch |err| switch (err) {
22546 error.NotCoercible => unreachable,22570 error.NotCoercible => unreachable,
22547 else => |e| return e,22571 else => |e| return e,
22548 };22572 };
...@@ -22554,14 +22578,22 @@ const CoersionError = CompileError || error{...@@ -22554,14 +22578,22 @@ const CoersionError = CompileError || error{
22554 NotCoercible,22578 NotCoercible,
22555};22579};
2255622580
22581const CoerceOpts = struct {
22582 /// Should coerceExtra emit error messages.
22583 report_err: bool = true,
22584 /// Ignored if `report_err == false`.
22585 is_ret: bool = false,
22586 /// Should coercion to comptime_int ermit an error message.
22587 no_cast_to_comptime_int: bool = false,
22588};
22589
22557fn coerceExtra(22590fn coerceExtra(
22558 sema: *Sema,22591 sema: *Sema,
22559 block: *Block,22592 block: *Block,
22560 dest_ty_unresolved: Type,22593 dest_ty_unresolved: Type,
22561 inst: Air.Inst.Ref,22594 inst: Air.Inst.Ref,
22562 inst_src: LazySrcLoc,22595 inst_src: LazySrcLoc,
22563 report_err: bool,22596 opts: CoerceOpts,
22564 is_ret: bool,
22565) CoersionError!Air.Inst.Ref {22597) CoersionError!Air.Inst.Ref {
22566 switch (dest_ty_unresolved.tag()) {22598 switch (dest_ty_unresolved.tag()) {
22567 .var_args_param => return sema.coerceVarArgParam(block, inst, inst_src),22599 .var_args_param => return sema.coerceVarArgParam(block, inst, inst_src),
...@@ -22613,7 +22645,7 @@ fn coerceExtra(...@@ -22613,7 +22645,7 @@ fn coerceExtra(
2261322645
22614 // T to ?T22646 // T to ?T
22615 const child_type = try dest_ty.optionalChildAlloc(sema.arena);22647 const child_type = try dest_ty.optionalChildAlloc(sema.arena);
22616 const intermediate = sema.coerceExtra(block, child_type, inst, inst_src, false, is_ret) catch |err| switch (err) {22648 const intermediate = sema.coerceExtra(block, child_type, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {
22617 error.NotCoercible => {22649 error.NotCoercible => {
22618 if (in_memory_result == .no_match) {22650 if (in_memory_result == .no_match) {
22619 // Try to give more useful notes22651 // Try to give more useful notes
...@@ -22729,7 +22761,7 @@ fn coerceExtra(...@@ -22729,7 +22761,7 @@ fn coerceExtra(
22729 return sema.addConstant(dest_ty, Value.@"null");22761 return sema.addConstant(dest_ty, Value.@"null");
22730 },22762 },
22731 .ComptimeInt => {22763 .ComptimeInt => {
22732 const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, false, is_ret) catch |err| switch (err) {22764 const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {
22733 error.NotCoercible => break :pointer,22765 error.NotCoercible => break :pointer,
22734 else => |e| return e,22766 else => |e| return e,
22735 };22767 };
...@@ -22740,7 +22772,7 @@ fn coerceExtra(...@@ -22740,7 +22772,7 @@ fn coerceExtra(
22740 .signed => Type.isize,22772 .signed => Type.isize,
22741 .unsigned => Type.usize,22773 .unsigned => Type.usize,
22742 };22774 };
22743 const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, false, is_ret) catch |err| switch (err) {22775 const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {
22744 error.NotCoercible => {22776 error.NotCoercible => {
22745 // Try to give more useful notes22777 // Try to give more useful notes
22746 in_memory_result = try sema.coerceInMemoryAllowed(block, ptr_size_ty, inst_ty, false, target, dest_ty_src, inst_src);22778 in_memory_result = try sema.coerceInMemoryAllowed(block, ptr_size_ty, inst_ty, false, target, dest_ty_src, inst_src);
...@@ -22866,7 +22898,13 @@ fn coerceExtra(...@@ -22866,7 +22898,13 @@ fn coerceExtra(
22866 },22898 },
22867 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) {22899 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) {
22868 .Float, .ComptimeFloat => float: {22900 .Float, .ComptimeFloat => float: {
22869 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;22901 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse {
22902 if (dest_ty.zigTypeTag() == .ComptimeInt) {
22903 if (!opts.report_err) return error.NotCoercible;
22904 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime known");
22905 }
22906 break :float;
22907 };
2287022908
22871 if (val.floatHasFraction()) {22909 if (val.floatHasFraction()) {
22872 return sema.fail(22910 return sema.fail(
...@@ -22883,11 +22921,16 @@ fn coerceExtra(...@@ -22883,11 +22921,16 @@ fn coerceExtra(
22883 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {22921 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
22884 // comptime known integer to other number22922 // comptime known integer to other number
22885 if (!(try sema.intFitsInType(block, inst_src, val, dest_ty, null))) {22923 if (!(try sema.intFitsInType(block, inst_src, val, dest_ty, null))) {
22886 if (!report_err) return error.NotCoercible;22924 if (!opts.report_err) return error.NotCoercible;
22887 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) });22925 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) });
22888 }22926 }
22889 return try sema.addConstant(dest_ty, val);22927 return try sema.addConstant(dest_ty, val);
22890 }22928 }
22929 if (dest_ty.zigTypeTag() == .ComptimeInt) {
22930 if (!opts.report_err) return error.NotCoercible;
22931 if (opts.no_cast_to_comptime_int) return inst;
22932 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime known");
22933 }
2289122934
22892 // integer widening22935 // integer widening
22893 const dst_info = dest_ty.intInfo(target);22936 const dst_info = dest_ty.intInfo(target);
...@@ -22924,6 +22967,7 @@ fn coerceExtra(...@@ -22924,6 +22967,7 @@ fn coerceExtra(
22924 }22967 }
22925 return try sema.addConstant(dest_ty, result_val);22968 return try sema.addConstant(dest_ty, result_val);
22926 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {22969 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {
22970 if (!opts.report_err) return error.NotCoercible;
22927 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime known");22971 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime known");
22928 }22972 }
2292922973
...@@ -22936,7 +22980,13 @@ fn coerceExtra(...@@ -22936,7 +22980,13 @@ fn coerceExtra(
22936 }22980 }
22937 },22981 },
22938 .Int, .ComptimeInt => int: {22982 .Int, .ComptimeInt => int: {
22939 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :int;22983 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse {
22984 if (dest_ty.zigTypeTag() == .ComptimeFloat) {
22985 if (!opts.report_err) return error.NotCoercible;
22986 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime known");
22987 }
22988 break :int;
22989 };
22940 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);22990 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);
22941 // TODO implement this compile error22991 // TODO implement this compile error
22942 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);22992 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
...@@ -23088,9 +23138,9 @@ fn coerceExtra(...@@ -23088,9 +23138,9 @@ fn coerceExtra(
23088 return sema.addConstUndef(dest_ty);23138 return sema.addConstUndef(dest_ty);
23089 }23139 }
2309023140
23091 if (!report_err) return error.NotCoercible;23141 if (!opts.report_err) return error.NotCoercible;
2309223142
23093 if (is_ret and dest_ty.zigTypeTag() == .NoReturn) {23143 if (opts.is_ret and dest_ty.zigTypeTag() == .NoReturn) {
23094 const msg = msg: {23144 const msg = msg: {
23095 const msg = try sema.errMsg(block, inst_src, "function declared 'noreturn' returns", .{});23145 const msg = try sema.errMsg(block, inst_src, "function declared 'noreturn' returns", .{});
23096 errdefer msg.destroy(sema.gpa);23146 errdefer msg.destroy(sema.gpa);
...@@ -23127,7 +23177,7 @@ fn coerceExtra(...@@ -23127,7 +23177,7 @@ fn coerceExtra(
23127 try in_memory_result.report(sema, block, inst_src, msg);23177 try in_memory_result.report(sema, block, inst_src, msg);
2312823178
23129 // Add notes about function return type23179 // Add notes about function return type
23130 if (is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) {23180 if (opts.is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) {
23131 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };23181 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
23132 const src_decl = sema.mod.declPtr(sema.func.?.owner_decl);23182 const src_decl = sema.mod.declPtr(sema.func.?.owner_decl);
23133 if (inst_ty.isError() and !dest_ty.isError()) {23183 if (inst_ty.isError() and !dest_ty.isError()) {
...@@ -24088,7 +24138,7 @@ fn storePtr2(...@@ -24088,7 +24138,7 @@ fn storePtr2(
24088 // https://github.com/ziglang/zig/issues/1115424138 // https://github.com/ziglang/zig/issues/11154
24089 if (sema.obtainBitCastedVectorPtr(ptr)) |vector_ptr| {24139 if (sema.obtainBitCastedVectorPtr(ptr)) |vector_ptr| {
24090 const vector_ty = sema.typeOf(vector_ptr).childType();24140 const vector_ty = sema.typeOf(vector_ptr).childType();
24091 const vector = sema.coerceExtra(block, vector_ty, uncasted_operand, operand_src, true, is_ret) catch |err| switch (err) {24141 const vector = sema.coerceExtra(block, vector_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) {
24092 error.NotCoercible => unreachable,24142 error.NotCoercible => unreachable,
24093 else => |e| return e,24143 else => |e| return e,
24094 };24144 };
...@@ -24096,7 +24146,7 @@ fn storePtr2(...@@ -24096,7 +24146,7 @@ fn storePtr2(
24096 return;24146 return;
24097 }24147 }
2409824148
24099 const operand = sema.coerceExtra(block, elem_ty, uncasted_operand, operand_src, true, is_ret) catch |err| switch (err) {24149 const operand = sema.coerceExtra(block, elem_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) {
24100 error.NotCoercible => unreachable,24150 error.NotCoercible => unreachable,
24101 else => |e| return e,24151 else => |e| return e,
24102 };24152 };
...@@ -26831,7 +26881,7 @@ fn wrapErrorUnionPayload(...@@ -26831,7 +26881,7 @@ fn wrapErrorUnionPayload(
26831 inst_src: LazySrcLoc,26881 inst_src: LazySrcLoc,
26832) !Air.Inst.Ref {26882) !Air.Inst.Ref {
26833 const dest_payload_ty = dest_ty.errorUnionPayload();26883 const dest_payload_ty = dest_ty.errorUnionPayload();
26834 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, false, false);26884 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });
26835 if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {26885 if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {
26836 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));26886 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));
26837 }26887 }
src/Zir.zig+9-6
...@@ -242,6 +242,8 @@ pub const Inst = struct {...@@ -242,6 +242,8 @@ pub const Inst = struct {
242 /// Type coercion to the function's return type.242 /// Type coercion to the function's return type.
243 /// Uses the `pl_node` field. Payload is `As`. AST node could be many things.243 /// Uses the `pl_node` field. Payload is `As`. AST node could be many things.
244 as_node,244 as_node,
245 /// Same as `as_node` but ignores runtime to comptime int error.
246 as_shift_operand,
245 /// Bitwise AND. `&`247 /// Bitwise AND. `&`
246 bit_and,248 bit_and,
247 /// Reinterpret the memory representation of a value as a different type.249 /// Reinterpret the memory representation of a value as a different type.
...@@ -942,9 +944,6 @@ pub const Inst = struct {...@@ -942,9 +944,6 @@ pub const Inst = struct {
942 /// Implements the `@maximum` builtin.944 /// Implements the `@maximum` builtin.
943 /// Uses the `pl_node` union field with payload `Bin`945 /// Uses the `pl_node` union field with payload `Bin`
944 maximum,946 maximum,
945 /// Implements the `@asyncCall` builtin.
946 /// Uses the `pl_node` union field with payload `AsyncCall`.
947 builtin_async_call,
948 /// Implements the `@cImport` builtin.947 /// Implements the `@cImport` builtin.
949 /// Uses the `pl_node` union field with payload `Block`.948 /// Uses the `pl_node` union field with payload `Block`.
950 c_import,949 c_import,
...@@ -1029,6 +1028,7 @@ pub const Inst = struct {...@@ -1029,6 +1028,7 @@ pub const Inst = struct {
1029 .anyframe_type,1028 .anyframe_type,
1030 .as,1029 .as,
1031 .as_node,1030 .as_node,
1031 .as_shift_operand,
1032 .bit_and,1032 .bit_and,
1033 .bitcast,1033 .bitcast,
1034 .bit_or,1034 .bit_or,
...@@ -1231,7 +1231,6 @@ pub const Inst = struct {...@@ -1231,7 +1231,6 @@ pub const Inst = struct {
1231 .memcpy,1231 .memcpy,
1232 .memset,1232 .memset,
1233 .minimum,1233 .minimum,
1234 .builtin_async_call,
1235 .c_import,1234 .c_import,
1236 .@"resume",1235 .@"resume",
1237 .@"await",1236 .@"await",
...@@ -1339,6 +1338,7 @@ pub const Inst = struct {...@@ -1339,6 +1338,7 @@ pub const Inst = struct {
1339 .anyframe_type,1338 .anyframe_type,
1340 .as,1339 .as,
1341 .as_node,1340 .as_node,
1341 .as_shift_operand,
1342 .bit_and,1342 .bit_and,
1343 .bitcast,1343 .bitcast,
1344 .bit_or,1344 .bit_or,
...@@ -1513,7 +1513,6 @@ pub const Inst = struct {...@@ -1513,7 +1513,6 @@ pub const Inst = struct {
1513 .field_parent_ptr,1513 .field_parent_ptr,
1514 .maximum,1514 .maximum,
1515 .minimum,1515 .minimum,
1516 .builtin_async_call,
1517 .c_import,1516 .c_import,
1518 .@"resume",1517 .@"resume",
1519 .@"await",1518 .@"await",
...@@ -1577,6 +1576,7 @@ pub const Inst = struct {...@@ -1577,6 +1576,7 @@ pub const Inst = struct {
1577 .anyframe_type = .un_node,1576 .anyframe_type = .un_node,
1578 .as = .bin,1577 .as = .bin,
1579 .as_node = .pl_node,1578 .as_node = .pl_node,
1579 .as_shift_operand = .pl_node,
1580 .bit_and = .pl_node,1580 .bit_and = .pl_node,
1581 .bitcast = .pl_node,1581 .bitcast = .pl_node,
1582 .bit_not = .un_node,1582 .bit_not = .un_node,
...@@ -1801,7 +1801,6 @@ pub const Inst = struct {...@@ -1801,7 +1801,6 @@ pub const Inst = struct {
1801 .memcpy = .pl_node,1801 .memcpy = .pl_node,
1802 .memset = .pl_node,1802 .memset = .pl_node,
1803 .minimum = .pl_node,1803 .minimum = .pl_node,
1804 .builtin_async_call = .pl_node,
1805 .c_import = .pl_node,1804 .c_import = .pl_node,
18061805
1807 .alloc = .un_node,1806 .alloc = .un_node,
...@@ -1972,6 +1971,9 @@ pub const Inst = struct {...@@ -1972,6 +1971,9 @@ pub const Inst = struct {
1972 /// `operand` is payload index to `UnNode`.1971 /// `operand` is payload index to `UnNode`.
1973 /// `small` contains `NameStrategy1972 /// `small` contains `NameStrategy
1974 reify,1973 reify,
1974 /// Implements the `@asyncCall` builtin.
1975 /// `operand` is payload index to `AsyncCall`.
1976 builtin_async_call,
19751977
1976 pub const InstData = struct {1978 pub const InstData = struct {
1977 opcode: Extended,1979 opcode: Extended,
...@@ -3454,6 +3456,7 @@ pub const Inst = struct {...@@ -3454,6 +3456,7 @@ pub const Inst = struct {
3454 };3456 };
34553457
3456 pub const AsyncCall = struct {3458 pub const AsyncCall = struct {
3459 node: i32,
3457 frame_buffer: Ref,3460 frame_buffer: Ref,
3458 result_ptr: Ref,3461 result_ptr: Ref,
3459 fn_ptr: Ref,3462 fn_ptr: Ref,
src/print_zir.zig+5-6
...@@ -283,7 +283,6 @@ const Writer = struct {...@@ -283,7 +283,6 @@ const Writer = struct {
283 .mul_add => try self.writeMulAdd(stream, inst),283 .mul_add => try self.writeMulAdd(stream, inst),
284 .field_parent_ptr => try self.writeFieldParentPtr(stream, inst),284 .field_parent_ptr => try self.writeFieldParentPtr(stream, inst),
285 .builtin_call => try self.writeBuiltinCall(stream, inst),285 .builtin_call => try self.writeBuiltinCall(stream, inst),
286 .builtin_async_call => try self.writeBuiltinAsyncCall(stream, inst),
287286
288 .struct_init_anon,287 .struct_init_anon,
289 .struct_init_anon_ref,288 .struct_init_anon_ref,
...@@ -397,7 +396,7 @@ const Writer = struct {...@@ -397,7 +396,7 @@ const Writer = struct {
397 .field_val_named,396 .field_val_named,
398 => try self.writePlNodeFieldNamed(stream, inst),397 => try self.writePlNodeFieldNamed(stream, inst),
399398
400 .as_node => try self.writeAs(stream, inst),399 .as_node, .as_shift_operand => try self.writeAs(stream, inst),
401400
402 .repeat,401 .repeat,
403 .repeat_inline,402 .repeat_inline,
...@@ -531,6 +530,7 @@ const Writer = struct {...@@ -531,6 +530,7 @@ const Writer = struct {
531 try stream.writeAll(") ");530 try stream.writeAll(") ");
532 try self.writeSrc(stream, src);531 try self.writeSrc(stream, src);
533 },532 },
533 .builtin_async_call => try self.writeBuiltinAsyncCall(stream, extended),
534 }534 }
535 }535 }
536536
...@@ -814,9 +814,8 @@ const Writer = struct {...@@ -814,9 +814,8 @@ const Writer = struct {
814 try self.writeSrc(stream, inst_data.src());814 try self.writeSrc(stream, inst_data.src());
815 }815 }
816816
817 fn writeBuiltinAsyncCall(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {817 fn writeBuiltinAsyncCall(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
818 const inst_data = self.code.instructions.items(.data)[inst].pl_node;818 const extra = self.code.extraData(Zir.Inst.AsyncCall, extended.operand).data;
819 const extra = self.code.extraData(Zir.Inst.AsyncCall, inst_data.payload_index).data;
820 try self.writeInstRef(stream, extra.frame_buffer);819 try self.writeInstRef(stream, extra.frame_buffer);
821 try stream.writeAll(", ");820 try stream.writeAll(", ");
822 try self.writeInstRef(stream, extra.result_ptr);821 try self.writeInstRef(stream, extra.result_ptr);
...@@ -825,7 +824,7 @@ const Writer = struct {...@@ -825,7 +824,7 @@ const Writer = struct {
825 try stream.writeAll(", ");824 try stream.writeAll(", ");
826 try self.writeInstRef(stream, extra.args);825 try self.writeInstRef(stream, extra.args);
827 try stream.writeAll(") ");826 try stream.writeAll(") ");
828 try self.writeSrc(stream, inst_data.src());827 try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.node));
829 }828 }
830829
831 fn writeParam(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {830 fn writeParam(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
test/cases/compile_errors/runtime_to_comptime_num.zig created+31
...@@ -0,0 +1,31 @@
1pub export fn entry() void {
2 var a: u32 = 0;
3 _ = @as(comptime_int, a);
4}
5pub export fn entry2() void{
6 var a: u32 = 0;
7 _ = @as(comptime_float, a);
8}
9pub export fn entry3() void{
10 comptime var aa: comptime_float = 0.0;
11 var a: f32 = 4;
12 aa = a;
13}
14pub export fn entry4() void{
15 comptime var aa: comptime_int = 0.0;
16 var a: f32 = 4;
17 aa = a;
18}
19
20// error
21// backend=stage2
22// target=native
23//
24// :3:27: error: unable to resolve comptime value
25// :3:27: note: value being casted to 'comptime_int' must be comptime known
26// :7:29: error: unable to resolve comptime value
27// :7:29: note: value being casted to 'comptime_float' must be comptime known
28// :12:10: error: unable to resolve comptime value
29// :12:10: note: value being casted to 'comptime_float' must be comptime known
30// :17:10: error: unable to resolve comptime value
31// :17:10: note: value being casted to 'comptime_int' must be comptime known
test/cases/compile_errors/shifting_without_int_type_or_comptime_known.zig created+23
...@@ -0,0 +1,23 @@
1export fn entry(x: u8) u8 {
2 return 0x11 << x;
3}
4export fn entry1(x: u8) u8 {
5 return 0x11 >> x;
6}
7export fn entry2() void {
8 var x: u5 = 1;
9 _ = @shlExact(12345, x);
10}
11export fn entry3() void {
12 var x: u5 = 1;
13 _ = @shrExact(12345, x);
14}
15
16// error
17// backend=stage2
18// target=native
19//
20// :2:17: error: LHS of shift must be a fixed-width integer type, or RHS must be a comptime known
21// :5:17: error: LHS of shift must be a fixed-width integer type, or RHS must be a comptime known
22// :9:9: error: LHS of shift must be a fixed-width integer type, or RHS must be a comptime known
23// :13:9: error: LHS of shift must be a fixed-width integer type, or RHS must be a comptime known
test/cases/compile_errors/stage1/obj/shifting_without_int_type_or_comptime_known.zig deleted-9
...@@ -1,9 +0,0 @@
1export fn entry(x: u8) u8 {
2 return 0x11 << x;
3}
4
5// error
6// backend=stage1
7// target=native
8//
9// tmp.zig:2:17: error: LHS of shift must be a fixed-width integer type, or RHS must be compile-time known