diff options
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 84 |
1 files changed, 58 insertions, 26 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index e0ff94ec83..3465f923a8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -10487,7 +10487,8 @@ fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const array = try sema.resolveInst(extra.lhs); - const elem_index = try sema.resolveInst(extra.rhs); + const uncoerced_elem_index = try sema.resolveInst(extra.rhs); + const elem_index = try sema.coerce(block, Type.usize, uncoerced_elem_index, elem_index_src); return sema.elemVal(block, src, array, elem_index, elem_index_src, true); } @@ -10539,7 +10540,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const array_ptr = try sema.resolveInst(extra.lhs); - const elem_index = try sema.resolveInst(extra.rhs); + const uncoerced_elem_index = try sema.resolveInst(extra.rhs); + const elem_index = try sema.coerce(block, Type.usize, uncoerced_elem_index, elem_index_src); return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true); } @@ -18722,11 +18724,13 @@ fn zirBoolBr( const inst_data = datas[@intFromEnum(inst)].pl_node; const extra = sema.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index); - const lhs = try sema.resolveInst(extra.data.lhs); + const uncoerced_lhs = try sema.resolveInst(extra.data.lhs); const body = sema.code.bodySlice(extra.end, extra.data.body_len); const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; + const lhs = try sema.coerce(parent_block, Type.bool, uncoerced_lhs, lhs_src); + if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { if (is_bool_or and lhs_val.toBool()) { return .bool_true; @@ -18736,7 +18740,11 @@ fn zirBoolBr( // comptime-known left-hand side. No need for a block here; the result // is simply the rhs expression. Here we rely on there only being 1 // break instruction (`break_inline`). - return sema.resolveBody(parent_block, body, inst); + const rhs_result = try sema.resolveBody(parent_block, body, inst); + if (sema.typeOf(rhs_result).isNoReturn(mod)) { + return rhs_result; + } + return sema.coerce(parent_block, Type.bool, rhs_result, rhs_src); } const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); @@ -18767,13 +18775,16 @@ fn zirBoolBr( _ = try lhs_block.addBr(block_inst, lhs_result); const rhs_result = try sema.resolveBody(rhs_block, body, inst); - if (!sema.typeOf(rhs_result).isNoReturn(mod)) { - _ = try rhs_block.addBr(block_inst, rhs_result); - } + const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod); + const coerced_rhs_result = if (!rhs_noret) rhs: { + const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src); + _ = try rhs_block.addBr(block_inst, coerced_result); + break :rhs coerced_result; + } else rhs_result; const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst); - if (!sema.typeOf(rhs_result).isNoReturn(mod)) { - if (try sema.resolveDefinedValue(rhs_block, rhs_src, rhs_result)) |rhs_val| { + if (!rhs_noret) { + if (try sema.resolveDefinedValue(rhs_block, rhs_src, coerced_rhs_result)) |rhs_val| { if (is_bool_or and rhs_val.toBool()) { return .bool_true; } else if (!is_bool_or and !rhs_val.toBool()) { @@ -20750,8 +20761,9 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const operand = try sema.resolveInst(inst_data.operand); const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const uncoerced_operand = try sema.resolveInst(inst_data.operand); + const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src); if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { const err_name = sema.mod.intern_pool.indexToKey(val.toIntern()).err.name; @@ -25375,15 +25387,21 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A } else if (extra.data.bits.has_align_ref) blk: { const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); extra_index += 1; - const align_tv = sema.resolveInstConst(block, align_src, align_ref, .{ + const uncoerced_align = sema.resolveInst(align_ref) catch |err| switch (err) { + error.GenericPoison => break :blk null, + else => |e| return e, + }; + const coerced_align = sema.coerce(block, Type.u29, uncoerced_align, align_src) catch |err| switch (err) { + error.GenericPoison => break :blk null, + else => |e| return e, + }; + const align_val = sema.resolveConstDefinedValue(block, align_src, coerced_align, .{ .needed_comptime_reason = "alignment must be comptime-known", }) catch |err| switch (err) { - error.GenericPoison => { - break :blk null; - }, + error.GenericPoison => break :blk null, else => |e| return e, }; - const alignment = try sema.validateAlignAllowZero(block, align_src, try align_tv.val.toUnsignedIntAdvanced(sema)); + const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntAdvanced(sema)); const default = target_util.defaultFunctionAlignment(target); break :blk if (alignment == default) .none else alignment; } else .none; @@ -25394,7 +25412,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const body = sema.code.bodySlice(extra_index, body_len); extra_index += body.len; - const addrspace_ty = try sema.getBuiltinType("AddressSpace"); + const addrspace_ty = Type.fromInterned(.address_space_type); const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, .{ .needed_comptime_reason = "addrspace must be comptime-known", }); @@ -25405,15 +25423,22 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A } else if (extra.data.bits.has_addrspace_ref) blk: { const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); extra_index += 1; - const addrspace_tv = sema.resolveInstConst(block, addrspace_src, addrspace_ref, .{ + const addrspace_ty = Type.fromInterned(.address_space_type); + const uncoerced_addrspace = sema.resolveInst(addrspace_ref) catch |err| switch (err) { + error.GenericPoison => break :blk null, + else => |e| return e, + }; + const coerced_addrspace = sema.coerce(block, addrspace_ty, uncoerced_addrspace, addrspace_src) catch |err| switch (err) { + error.GenericPoison => break :blk null, + else => |e| return e, + }; + const addrspace_val = sema.resolveConstDefinedValue(block, addrspace_src, coerced_addrspace, .{ .needed_comptime_reason = "addrspace must be comptime-known", }) catch |err| switch (err) { - error.GenericPoison => { - break :blk null; - }, + error.GenericPoison => break :blk null, else => |e| return e, }; - break :blk mod.toEnum(std.builtin.AddressSpace, addrspace_tv.val); + break :blk mod.toEnum(std.builtin.AddressSpace, addrspace_val); } else target_util.defaultAddressSpace(target, .function); const section: Section = if (extra.data.bits.has_section_body) blk: { @@ -25461,15 +25486,22 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A } else if (extra.data.bits.has_cc_ref) blk: { const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); extra_index += 1; - const cc_tv = sema.resolveInstConst(block, cc_src, cc_ref, .{ + const cc_ty = Type.fromInterned(.calling_convention_type); + const uncoerced_cc = sema.resolveInst(cc_ref) catch |err| switch (err) { + error.GenericPoison => break :blk null, + else => |e| return e, + }; + const coerced_cc = sema.coerce(block, cc_ty, uncoerced_cc, cc_src) catch |err| switch (err) { + error.GenericPoison => break :blk null, + else => |e| return e, + }; + const cc_val = sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .needed_comptime_reason = "calling convention must be comptime-known", }) catch |err| switch (err) { - error.GenericPoison => { - break :blk null; - }, + error.GenericPoison => break :blk null, else => |e| return e, }; - break :blk mod.toEnum(std.builtin.CallingConvention, cc_tv.val); + break :blk mod.toEnum(std.builtin.CallingConvention, cc_val); } else if (sema.owner_decl.is_exported and has_body) .C else |
