diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-08-30 15:21:50 +0300 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-08-30 12:22:07 -0700 |
| commit | d3b4b2edf140c002da4c9c1396c26e0f66835eb0 (patch) | |
| tree | 84fe3e9442f391eb19c79e1a51dc11c385884740 /src | |
| parent | 01d19a8d3cdd52ad50f45bfb8666b56ccf8d3a22 (diff) | |
| download | zig-d3b4b2edf140c002da4c9c1396c26e0f66835eb0.tar.gz zig-d3b4b2edf140c002da4c9c1396c26e0f66835eb0.zip | |
Sema: shift of comptime int with runtime value
Closes #12290
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 33 | ||||
| -rw-r--r-- | src/Autodoc.zig | 2 | ||||
| -rw-r--r-- | src/Sema.zig | 102 | ||||
| -rw-r--r-- | src/Zir.zig | 15 | ||||
| -rw-r--r-- | src/print_zir.zig | 11 |
5 files changed, 113 insertions, 50 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index 943d0aad08..79e5ad963e 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -226,6 +226,8 @@ pub const ResultLoc = union(enum) { ref, /// The expression will be coerced into this type, but it will be evaluated as an rvalue. ty: Zir.Inst.Ref, + /// Same as `ty` but for shift operands. + ty_shift_operand: Zir.Inst.Ref, /// Same as `ty` but it is guaranteed that Sema will additionally perform the coercion, /// so no `as` instruction needs to be emitted. coerced_ty: Zir.Inst.Ref, @@ -259,7 +261,7 @@ pub const ResultLoc = union(enum) { fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy { switch (rl) { // In this branch there will not be any store_to_block_ptr instructions. - .none, .ty, .coerced_ty, .ref => return .{ + .none, .ty, .ty_shift_operand, .coerced_ty, .ref => return .{ .tag = .break_operand, .elide_store_to_block_ptr_instructions = false, }, @@ -302,6 +304,14 @@ pub const ResultLoc = union(enum) { else => rl, }; } + + fn zirTag(rl: ResultLoc) Zir.Inst.Tag { + return switch (rl) { + .ty => .as_node, + .ty_shift_operand => .as_shift_operand, + else => unreachable, + }; + } }; pub const align_rl: ResultLoc = .{ .ty = .u29_type }; @@ -1385,7 +1395,7 @@ fn arrayInitExpr( const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); }, - .ty, .coerced_ty => { + .ty, .ty_shift_operand, .coerced_ty => { const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); return rvalue(gz, rl, result, node); @@ -1631,7 +1641,7 @@ fn structInitExpr( return structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); } }, - .ty, .coerced_ty => |ty_inst| { + .ty, .ty_shift_operand, .coerced_ty => |ty_inst| { if (struct_init.ast.type_expr == 0) { const result = try structInitExprRlNone(gz, scope, node, struct_init, ty_inst, .struct_init_anon); return rvalue(gz, rl, result, node); @@ -2327,6 +2337,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .anyframe_type, .as, .as_node, + .as_shift_operand, .bit_and, .bitcast, .bit_or, @@ -2497,7 +2508,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .field_parent_ptr, .maximum, .minimum, - .builtin_async_call, .c_import, .@"resume", .@"await", @@ -7278,7 +7288,7 @@ fn as( ) InnerError!Zir.Inst.Ref { const dest_type = try typeExpr(gz, scope, lhs); switch (rl) { - .none, .discard, .ref, .ty, .coerced_ty => { + .none, .discard, .ref, .ty, .ty_shift_operand, .coerced_ty => { const result = try reachableExpr(gz, scope, .{ .ty = dest_type }, rhs, node); return rvalue(gz, rl, result, node); }, @@ -7959,7 +7969,8 @@ fn builtinCall( return rvalue(gz, rl, result, node); }, .async_call => { - const result = try gz.addPlNode(.builtin_async_call, node, Zir.Inst.AsyncCall{ + const result = try gz.addExtendedPayload(.builtin_async_call, Zir.Inst.AsyncCall{ + .node = gz.nodeIndexToRelative(node), .frame_buffer = try expr(gz, scope, .none, params[0]), .result_ptr = try expr(gz, scope, .none, params[1]), .fn_ptr = try expr(gz, scope, .none, params[2]), @@ -8178,7 +8189,7 @@ fn shiftOp( ) InnerError!Zir.Inst.Ref { const lhs = try expr(gz, scope, .none, lhs_node); const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); - const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, rhs_node); + const rhs = try expr(gz, scope, .{ .ty_shift_operand = log2_int_type }, rhs_node); const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs, @@ -9409,7 +9420,7 @@ fn rvalue( } return indexToRef(gop.value_ptr.*); }, - .ty => |ty_inst| { + .ty, .ty_shift_operand => |ty_inst| { // Quickly eliminate some common, unnecessary type coercion. const as_ty = @as(u64, @enumToInt(Zir.Inst.Ref.type_type)) << 32; const as_comptime_int = @as(u64, @enumToInt(Zir.Inst.Ref.comptime_int_type)) << 32; @@ -9470,7 +9481,7 @@ fn rvalue( => return result, // type of result is already correct // Need an explicit type coercion instruction. - else => return gz.addPlNode(.as_node, src_node, Zir.Inst.As{ + else => return gz.addPlNode(rl.zirTag(), src_node, Zir.Inst.As{ .dest_type = ty_inst, .operand = result, }), @@ -10350,7 +10361,7 @@ const GenZir = struct { // we emit ZIR for the block break instructions to have the result values, // and then rvalue() on that to pass the value to the result location. switch (parent_rl) { - .ty, .coerced_ty => |ty_inst| { + .ty, .ty_shift_operand, .coerced_ty => |ty_inst| { gz.rl_ty_inst = ty_inst; gz.break_result_loc = parent_rl; }, @@ -11506,7 +11517,7 @@ const GenZir = struct { fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void { switch (rl) { .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node), - .ty => _ = try gz.addUnNode(.ret_node, operand, node), + .ty, .ty_shift_operand => _ = try gz.addUnNode(.ret_node, operand, node), else => unreachable, } } diff --git a/src/Autodoc.zig b/src/Autodoc.zig index db681157ae..0e056c093f 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -1888,7 +1888,7 @@ fn walkInstruction( .expr = .{ .typeInfo = operand_index }, }; }, - .as_node => { + .as_node, .as_shift_operand => { const pl_node = data[inst_index].pl_node; const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index); const dest_type_walk = try self.walkRef( diff --git a/src/Sema.zig b/src/Sema.zig index bf147a7cb4..1b35f52437 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -712,6 +712,7 @@ fn analyzeBodyInner( .vector_type => try sema.zirVectorType(block, inst), .as => try sema.zirAs(block, inst), .as_node => try sema.zirAsNode(block, inst), + .as_shift_operand => try sema.zirAsShiftOperand(block, inst), .bit_and => try sema.zirBitwise(block, inst, .bit_and), .bit_not => try sema.zirBitNot(block, inst), .bit_or => try sema.zirBitwise(block, inst, .bit_or), @@ -848,7 +849,6 @@ fn analyzeBodyInner( .mul_add => try sema.zirMulAdd(block, inst), .builtin_call => try sema.zirBuiltinCall(block, inst), .field_parent_ptr => try sema.zirFieldParentPtr(block, inst), - .builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst), .@"resume" => try sema.zirResume(block, inst), .@"await" => try sema.zirAwait(block, inst), .array_base_ptr => try sema.zirArrayBasePtr(block, inst), @@ -956,6 +956,7 @@ fn analyzeBodyInner( .error_to_int => try sema.zirErrorToInt( block, extended), .int_to_error => try sema.zirIntToError( block, extended), .reify => try sema.zirReify( block, extended, inst), + .builtin_async_call => try sema.zirBuiltinAsyncCall( block, extended), // zig fmt: on .fence => { try sema.zirFence(block, extended); @@ -8257,7 +8258,7 @@ fn zirAs(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst defer tracy.end(); const bin_inst = sema.code.instructions.items(.data)[inst].bin; - return sema.analyzeAs(block, sema.src, bin_inst.lhs, bin_inst.rhs); + return sema.analyzeAs(block, sema.src, bin_inst.lhs, bin_inst.rhs, false); } fn 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. const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data; - return sema.analyzeAs(block, src, extra.dest_type, extra.operand); + return sema.analyzeAs(block, src, extra.dest_type, extra.operand, false); +} + +fn zirAsShiftOperand(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { + const tracy = trace(@src()); + defer tracy.end(); + + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const src = inst_data.src(); + const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data; + return sema.analyzeAs(block, src, extra.dest_type, extra.operand, true); } fn analyzeAs( @@ -8276,6 +8287,7 @@ fn analyzeAs( src: LazySrcLoc, zir_dest_type: Zir.Inst.Ref, zir_operand: Zir.Inst.Ref, + no_cast_to_comptime_int: bool, ) CompileError!Air.Inst.Ref { const is_ret = if (Zir.refToIndex(zir_dest_type)) |ptr_index| sema.code.instructions.items(.tag)[ptr_index] == .ret_type @@ -8287,7 +8299,7 @@ fn analyzeAs( if (dest_ty.zigTypeTag() == .NoReturn) { return sema.fail(block, src, "cannot cast to noreturn", .{}); } - return sema.coerceExtra(block, dest_ty, operand, src, true, is_ret) catch |err| switch (err) { + 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) { error.NotCoercible => unreachable, else => |e| return e, }; @@ -10491,7 +10503,12 @@ fn zirShl( const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty); - const rhs_val = maybe_rhs_val orelse break :rs rhs_src; + const rhs_val = maybe_rhs_val orelse { + if (scalar_ty.zigTypeTag() == .ComptimeInt) { + return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be a comptime known", .{}); + } + break :rs rhs_src; + }; const val = switch (air_tag) { .shl_exact => val: { @@ -10615,7 +10632,10 @@ fn zirShr( const target = sema.mod.getTarget(); const scalar_ty = lhs_ty.scalarType(); - const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: { + const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs); + const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs); + + const runtime_src = if (maybe_rhs_val) |rhs_val| rs: { if (rhs_val.isUndef()) { return sema.addConstUndef(lhs_ty); } @@ -10647,7 +10667,7 @@ fn zirShr( }); } } - if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { + if (maybe_lhs_val) |lhs_val| { if (lhs_val.isUndef()) { return sema.addConstUndef(lhs_ty); } @@ -10665,6 +10685,10 @@ fn zirShr( } } else rhs_src; + if (maybe_rhs_val == null and scalar_ty.zigTypeTag() == .ComptimeInt) { + return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be a comptime known", .{}); + } + try sema.requireRuntimeBlock(block, src, runtime_src); const result = try block.addBinOp(air_tag, lhs, rhs); if (block.wantSafety()) { @@ -15385,7 +15409,7 @@ fn analyzeRet( if (sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) { try sema.addToInferredErrorSet(uncasted_operand); } - const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, true, true) catch |err| switch (err) { + const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) { error.NotCoercible => unreachable, else => |e| return e, }; @@ -19652,9 +19676,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void }); } -fn zirBuiltinAsyncCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const inst_data = sema.code.instructions.items(.data)[inst].pl_node; - const src = inst_data.src(); +fn zirBuiltinAsyncCall(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const src = LazySrcLoc.nodeOffset(extra.node); return sema.failWithUseOfAsync(block, src); } @@ -22542,7 +22566,7 @@ fn coerce( inst: Air.Inst.Ref, inst_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { - return sema.coerceExtra(block, dest_ty_unresolved, inst, inst_src, true, false) catch |err| switch (err) { + return sema.coerceExtra(block, dest_ty_unresolved, inst, inst_src, .{}) catch |err| switch (err) { error.NotCoercible => unreachable, else => |e| return e, }; @@ -22554,14 +22578,22 @@ const CoersionError = CompileError || error{ NotCoercible, }; +const CoerceOpts = struct { + /// Should coerceExtra emit error messages. + report_err: bool = true, + /// Ignored if `report_err == false`. + is_ret: bool = false, + /// Should coercion to comptime_int ermit an error message. + no_cast_to_comptime_int: bool = false, +}; + fn coerceExtra( sema: *Sema, block: *Block, dest_ty_unresolved: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, - report_err: bool, - is_ret: bool, + opts: CoerceOpts, ) CoersionError!Air.Inst.Ref { switch (dest_ty_unresolved.tag()) { .var_args_param => return sema.coerceVarArgParam(block, inst, inst_src), @@ -22613,7 +22645,7 @@ fn coerceExtra( // T to ?T const child_type = try dest_ty.optionalChildAlloc(sema.arena); - const intermediate = sema.coerceExtra(block, child_type, inst, inst_src, false, is_ret) catch |err| switch (err) { + const intermediate = sema.coerceExtra(block, child_type, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { error.NotCoercible => { if (in_memory_result == .no_match) { // Try to give more useful notes @@ -22729,7 +22761,7 @@ fn coerceExtra( return sema.addConstant(dest_ty, Value.@"null"); }, .ComptimeInt => { - const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, false, is_ret) catch |err| switch (err) { + const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { error.NotCoercible => break :pointer, else => |e| return e, }; @@ -22740,7 +22772,7 @@ fn coerceExtra( .signed => Type.isize, .unsigned => Type.usize, }; - const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, false, is_ret) catch |err| switch (err) { + const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { error.NotCoercible => { // Try to give more useful notes 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( }, .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) { .Float, .ComptimeFloat => float: { - const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float; + const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse { + if (dest_ty.zigTypeTag() == .ComptimeInt) { + if (!opts.report_err) return error.NotCoercible; + return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime known"); + } + break :float; + }; if (val.floatHasFraction()) { return sema.fail( @@ -22883,11 +22921,16 @@ fn coerceExtra( if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { // comptime known integer to other number if (!(try sema.intFitsInType(block, inst_src, val, dest_ty, null))) { - if (!report_err) return error.NotCoercible; + if (!opts.report_err) return error.NotCoercible; return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); } return try sema.addConstant(dest_ty, val); } + if (dest_ty.zigTypeTag() == .ComptimeInt) { + if (!opts.report_err) return error.NotCoercible; + if (opts.no_cast_to_comptime_int) return inst; + return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime known"); + } // integer widening const dst_info = dest_ty.intInfo(target); @@ -22924,6 +22967,7 @@ fn coerceExtra( } return try sema.addConstant(dest_ty, result_val); } else if (dest_ty.zigTypeTag() == .ComptimeFloat) { + if (!opts.report_err) return error.NotCoercible; return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime known"); } @@ -22936,7 +22980,13 @@ fn coerceExtra( } }, .Int, .ComptimeInt => int: { - const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :int; + const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse { + if (dest_ty.zigTypeTag() == .ComptimeFloat) { + if (!opts.report_err) return error.NotCoercible; + return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime known"); + } + break :int; + }; const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target); // TODO implement this compile error //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty); @@ -23088,9 +23138,9 @@ fn coerceExtra( return sema.addConstUndef(dest_ty); } - if (!report_err) return error.NotCoercible; + if (!opts.report_err) return error.NotCoercible; - if (is_ret and dest_ty.zigTypeTag() == .NoReturn) { + if (opts.is_ret and dest_ty.zigTypeTag() == .NoReturn) { const msg = msg: { const msg = try sema.errMsg(block, inst_src, "function declared 'noreturn' returns", .{}); errdefer msg.destroy(sema.gpa); @@ -23127,7 +23177,7 @@ fn coerceExtra( try in_memory_result.report(sema, block, inst_src, msg); // Add notes about function return type - if (is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) { + if (opts.is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) { const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; const src_decl = sema.mod.declPtr(sema.func.?.owner_decl); if (inst_ty.isError() and !dest_ty.isError()) { @@ -24088,7 +24138,7 @@ fn storePtr2( // https://github.com/ziglang/zig/issues/11154 if (sema.obtainBitCastedVectorPtr(ptr)) |vector_ptr| { const vector_ty = sema.typeOf(vector_ptr).childType(); - const vector = sema.coerceExtra(block, vector_ty, uncasted_operand, operand_src, true, is_ret) catch |err| switch (err) { + const vector = sema.coerceExtra(block, vector_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) { error.NotCoercible => unreachable, else => |e| return e, }; @@ -24096,7 +24146,7 @@ fn storePtr2( return; } - const operand = sema.coerceExtra(block, elem_ty, uncasted_operand, operand_src, true, is_ret) catch |err| switch (err) { + const operand = sema.coerceExtra(block, elem_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) { error.NotCoercible => unreachable, else => |e| return e, }; @@ -26831,7 +26881,7 @@ fn wrapErrorUnionPayload( inst_src: LazySrcLoc, ) !Air.Inst.Ref { const dest_payload_ty = dest_ty.errorUnionPayload(); - const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, false, false); + const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false }); if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| { return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val)); } diff --git a/src/Zir.zig b/src/Zir.zig index ec9ddfcffb..3ce086e10b 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -242,6 +242,8 @@ pub const Inst = struct { /// Type coercion to the function's return type. /// Uses the `pl_node` field. Payload is `As`. AST node could be many things. as_node, + /// Same as `as_node` but ignores runtime to comptime int error. + as_shift_operand, /// Bitwise AND. `&` bit_and, /// Reinterpret the memory representation of a value as a different type. @@ -942,9 +944,6 @@ pub const Inst = struct { /// Implements the `@maximum` builtin. /// Uses the `pl_node` union field with payload `Bin` maximum, - /// Implements the `@asyncCall` builtin. - /// Uses the `pl_node` union field with payload `AsyncCall`. - builtin_async_call, /// Implements the `@cImport` builtin. /// Uses the `pl_node` union field with payload `Block`. c_import, @@ -1029,6 +1028,7 @@ pub const Inst = struct { .anyframe_type, .as, .as_node, + .as_shift_operand, .bit_and, .bitcast, .bit_or, @@ -1231,7 +1231,6 @@ pub const Inst = struct { .memcpy, .memset, .minimum, - .builtin_async_call, .c_import, .@"resume", .@"await", @@ -1339,6 +1338,7 @@ pub const Inst = struct { .anyframe_type, .as, .as_node, + .as_shift_operand, .bit_and, .bitcast, .bit_or, @@ -1513,7 +1513,6 @@ pub const Inst = struct { .field_parent_ptr, .maximum, .minimum, - .builtin_async_call, .c_import, .@"resume", .@"await", @@ -1577,6 +1576,7 @@ pub const Inst = struct { .anyframe_type = .un_node, .as = .bin, .as_node = .pl_node, + .as_shift_operand = .pl_node, .bit_and = .pl_node, .bitcast = .pl_node, .bit_not = .un_node, @@ -1801,7 +1801,6 @@ pub const Inst = struct { .memcpy = .pl_node, .memset = .pl_node, .minimum = .pl_node, - .builtin_async_call = .pl_node, .c_import = .pl_node, .alloc = .un_node, @@ -1972,6 +1971,9 @@ pub const Inst = struct { /// `operand` is payload index to `UnNode`. /// `small` contains `NameStrategy reify, + /// Implements the `@asyncCall` builtin. + /// `operand` is payload index to `AsyncCall`. + builtin_async_call, pub const InstData = struct { opcode: Extended, @@ -3454,6 +3456,7 @@ pub const Inst = struct { }; pub const AsyncCall = struct { + node: i32, frame_buffer: Ref, result_ptr: Ref, fn_ptr: Ref, diff --git a/src/print_zir.zig b/src/print_zir.zig index f315d7f014..976d012138 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -283,7 +283,6 @@ const Writer = struct { .mul_add => try self.writeMulAdd(stream, inst), .field_parent_ptr => try self.writeFieldParentPtr(stream, inst), .builtin_call => try self.writeBuiltinCall(stream, inst), - .builtin_async_call => try self.writeBuiltinAsyncCall(stream, inst), .struct_init_anon, .struct_init_anon_ref, @@ -397,7 +396,7 @@ const Writer = struct { .field_val_named, => try self.writePlNodeFieldNamed(stream, inst), - .as_node => try self.writeAs(stream, inst), + .as_node, .as_shift_operand => try self.writeAs(stream, inst), .repeat, .repeat_inline, @@ -531,6 +530,7 @@ const Writer = struct { try stream.writeAll(") "); try self.writeSrc(stream, src); }, + .builtin_async_call => try self.writeBuiltinAsyncCall(stream, extended), } } @@ -814,9 +814,8 @@ const Writer = struct { try self.writeSrc(stream, inst_data.src()); } - fn writeBuiltinAsyncCall(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { - const inst_data = self.code.instructions.items(.data)[inst].pl_node; - const extra = self.code.extraData(Zir.Inst.AsyncCall, inst_data.payload_index).data; + fn writeBuiltinAsyncCall(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { + const extra = self.code.extraData(Zir.Inst.AsyncCall, extended.operand).data; try self.writeInstRef(stream, extra.frame_buffer); try stream.writeAll(", "); try self.writeInstRef(stream, extra.result_ptr); @@ -825,7 +824,7 @@ const Writer = struct { try stream.writeAll(", "); try self.writeInstRef(stream, extra.args); try stream.writeAll(") "); - try self.writeSrc(stream, inst_data.src()); + try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.node)); } fn writeParam(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { |
