| ... | ... | @@ -3963,7 +3963,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3963 | 3963 | const bin_op = sema.air_instructions.items(.data)[@backingInt(store_inst)].bin_op; |
| 3964 | 3964 | peer_val.* = bin_op.rhs; |
| 3965 | 3965 | } |
| 3966 | | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none); |
| 3966 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, .{ .insts = peer_vals }, .none); |
| 3967 | 3967 | // The layout of the peers is already resolved, so the layout of `final_elem_ty` is too. |
| 3968 | 3968 | final_elem_ty.assertHasLayout(zcu); |
| 3969 | 3969 | |
| ... | ... | @@ -5496,7 +5496,12 @@ fn resolveAnalyzedBlock( |
| 5496 | 5496 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 5497 | 5497 | // to emit a jump instruction to after the block when it encounters the break. |
| 5498 | 5498 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 5499 | | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .{ .override = merges.src_locs.items }); |
| 5499 | const resolved_ty = try sema.resolvePeerTypes( |
| 5500 | parent_block, |
| 5501 | src, |
| 5502 | .{ .insts = merges.results.items }, |
| 5503 | .{ .override = merges.src_locs.items }, |
| 5504 | ); |
| 5500 | 5505 | resolved_ty.assertHasLayout(zcu); |
| 5501 | 5506 | // TODO add note "missing else causes void value" |
| 5502 | 5507 | |
| ... | ... | @@ -12299,11 +12304,10 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( |
| 12299 | 12304 | |
| 12300 | 12305 | const capture_ty: Type = capture_ty: { |
| 12301 | 12306 | if (same_types) break :capture_ty first_field_ty; |
| 12302 | | // We need values to run PTR on, so make a bunch of undef constants. |
| 12303 | | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, item_refs.len); |
| 12304 | | for (dummy_captures, field_indices) |*dummy, field_idx| { |
| 12305 | | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 12306 | | dummy.* = try pt.undefRef(field_ty); |
| 12307 | |
| 12308 | const item_types = try sema.arena.alloc(Type, item_refs.len); |
| 12309 | for (item_types, field_indices) |*field_ty, field_idx| { |
| 12310 | field_ty.* = .fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 12307 | 12311 | } |
| 12308 | 12312 | |
| 12309 | 12313 | const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len); |
| ... | ... | @@ -12321,7 +12325,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( |
| 12321 | 12325 | break :capture_ty sema.resolvePeerTypes( |
| 12322 | 12326 | case_block, |
| 12323 | 12327 | capture_src, |
| 12324 | | dummy_captures, |
| 12328 | .{ .types = item_types }, |
| 12325 | 12329 | .{ .override = item_srcs }, |
| 12326 | 12330 | ) catch |err| switch (err) { |
| 12327 | 12331 | error.AlreadyReported => |e| { |
| ... | ... | @@ -12340,12 +12344,11 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( |
| 12340 | 12344 | const capture_ptr_ty = resolve: { |
| 12341 | 12345 | // By-ref captures of hetereogeneous types are only allowed if all field |
| 12342 | 12346 | // pointer types are peer resolvable to each other. |
| 12343 | | // We need values to run PTR on, so make a bunch of undef constants. |
| 12344 | | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, item_refs.len); |
| 12345 | | for (field_indices, dummy_captures) |field_index, *dummy| { |
| 12346 | | const field_ptr_ty = try operand_ptr_ty.fieldPtrType(field_index, pt); |
| 12347 | | dummy.* = try pt.undefRef(field_ptr_ty); |
| 12347 | const item_types = try sema.arena.alloc(Type, item_refs.len); |
| 12348 | for (item_types, field_indices) |*field_ptr_ty, field_index| { |
| 12349 | field_ptr_ty.* = try operand_ptr_ty.fieldPtrType(field_index, pt); |
| 12348 | 12350 | } |
| 12351 | |
| 12349 | 12352 | const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len); |
| 12350 | 12353 | for (item_srcs, 0..) |*item_src, item_i| { |
| 12351 | 12354 | item_src.* = .{ |
| ... | ... | @@ -12361,7 +12364,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( |
| 12361 | 12364 | break :resolve sema.resolvePeerTypes( |
| 12362 | 12365 | case_block, |
| 12363 | 12366 | capture_src, |
| 12364 | | dummy_captures, |
| 12367 | .{ .types = item_types }, |
| 12365 | 12368 | .{ .override = item_srcs }, |
| 12366 | 12369 | ) catch |err| switch (err) { |
| 12367 | 12370 | error.AlreadyReported => |e| { |
| ... | ... | @@ -13315,8 +13318,12 @@ fn zirBitwise( |
| 13315 | 13318 | const rhs_ty = sema.typeOf(rhs); |
| 13316 | 13319 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 13317 | 13320 | |
| 13318 | | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 13319 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); |
| 13321 | const resolved_type = try sema.resolvePeerTypes( |
| 13322 | block, |
| 13323 | src, |
| 13324 | .{ .insts = &.{ lhs, rhs } }, |
| 13325 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 13326 | ); |
| 13320 | 13327 | const scalar_type = resolved_type.scalarType(zcu); |
| 13321 | 13328 | const scalar_tag = scalar_type.zigTypeTag(zcu); |
| 13322 | 13329 | |
| ... | ... | @@ -13510,19 +13517,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13510 | 13517 | return sema.fail(block, rhs_src, "expected indexable; found '{f}'", .{rhs_ty.fmt(zcu)}); |
| 13511 | 13518 | }; |
| 13512 | 13519 | |
| 13513 | | const resolved_elem_ty = t: { |
| 13514 | | var trash_block = block.makeSubBlock(); |
| 13515 | | trash_block.comptime_reason = null; |
| 13516 | | defer trash_block.instructions.deinit(sema.gpa); |
| 13517 | | |
| 13518 | | const instructions = [_]Air.Inst.Ref{ |
| 13519 | | try trash_block.addTyOp(.bit_cast, lhs_info.elem_type, .void_value), |
| 13520 | | try trash_block.addTyOp(.bit_cast, rhs_info.elem_type, .void_value), |
| 13521 | | }; |
| 13522 | | break :t try sema.resolvePeerTypes(block, src, &instructions, .{ |
| 13523 | | .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, |
| 13524 | | }); |
| 13525 | | }; |
| 13520 | const resolved_elem_ty = try sema.resolvePeerTypes( |
| 13521 | block, |
| 13522 | src, |
| 13523 | .{ .types = &.{ lhs_info.elem_type, rhs_info.elem_type } }, |
| 13524 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 13525 | ); |
| 13526 | 13526 | |
| 13527 | 13527 | // When there is a sentinel mismatch, no sentinel on the result. |
| 13528 | 13528 | // Otherwise, use the sentinel value provided by either operand, |
| ... | ... | @@ -14004,9 +14004,12 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 14004 | 14004 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14005 | 14005 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14006 | 14006 | |
| 14007 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14008 | | .override = &.{ lhs_src, rhs_src }, |
| 14009 | | }); |
| 14007 | const resolved_type = try sema.resolvePeerTypes( |
| 14008 | block, |
| 14009 | src, |
| 14010 | .{ .insts = &.{ lhs, rhs } }, |
| 14011 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14012 | ); |
| 14010 | 14013 | |
| 14011 | 14014 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14012 | 14015 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14113,9 +14116,12 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14113 | 14116 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14114 | 14117 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14115 | 14118 | |
| 14116 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14117 | | .override = &.{ lhs_src, rhs_src }, |
| 14118 | | }); |
| 14119 | const resolved_type = try sema.resolvePeerTypes( |
| 14120 | block, |
| 14121 | src, |
| 14122 | .{ .insts = &.{ lhs, rhs } }, |
| 14123 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14124 | ); |
| 14119 | 14125 | |
| 14120 | 14126 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14121 | 14127 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14209,9 +14215,12 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14209 | 14215 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14210 | 14216 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14211 | 14217 | |
| 14212 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14213 | | .override = &.{ lhs_src, rhs_src }, |
| 14214 | | }); |
| 14218 | const resolved_type = try sema.resolvePeerTypes( |
| 14219 | block, |
| 14220 | src, |
| 14221 | .{ .insts = &.{ lhs, rhs } }, |
| 14222 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14223 | ); |
| 14215 | 14224 | |
| 14216 | 14225 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14217 | 14226 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14274,9 +14283,12 @@ fn zirDivCeil(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 14274 | 14283 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14275 | 14284 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14276 | 14285 | |
| 14277 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14278 | | .override = &.{ lhs_src, rhs_src }, |
| 14279 | | }); |
| 14286 | const resolved_type = try sema.resolvePeerTypes( |
| 14287 | block, |
| 14288 | src, |
| 14289 | .{ .insts = &.{ lhs, rhs } }, |
| 14290 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14291 | ); |
| 14280 | 14292 | |
| 14281 | 14293 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14282 | 14294 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14339,9 +14351,12 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14339 | 14351 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14340 | 14352 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14341 | 14353 | |
| 14342 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14343 | | .override = &.{ lhs_src, rhs_src }, |
| 14344 | | }); |
| 14354 | const resolved_type = try sema.resolvePeerTypes( |
| 14355 | block, |
| 14356 | src, |
| 14357 | .{ .insts = &.{ lhs, rhs } }, |
| 14358 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14359 | ); |
| 14345 | 14360 | |
| 14346 | 14361 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14347 | 14362 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14550,9 +14565,12 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14550 | 14565 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14551 | 14566 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14552 | 14567 | |
| 14553 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14554 | | .override = &.{ lhs_src, rhs_src }, |
| 14555 | | }); |
| 14568 | const resolved_type = try sema.resolvePeerTypes( |
| 14569 | block, |
| 14570 | src, |
| 14571 | .{ .insts = &.{ lhs, rhs } }, |
| 14572 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14573 | ); |
| 14556 | 14574 | |
| 14557 | 14575 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14558 | 14576 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14651,9 +14669,12 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 14651 | 14669 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14652 | 14670 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14653 | 14671 | |
| 14654 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14655 | | .override = &.{ lhs_src, rhs_src }, |
| 14656 | | }); |
| 14672 | const resolved_type = try sema.resolvePeerTypes( |
| 14673 | block, |
| 14674 | src, |
| 14675 | .{ .insts = &.{ lhs, rhs } }, |
| 14676 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14677 | ); |
| 14657 | 14678 | |
| 14658 | 14679 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14659 | 14680 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14715,9 +14736,12 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 14715 | 14736 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14716 | 14737 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 14717 | 14738 | |
| 14718 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 14719 | | .override = &.{ lhs_src, rhs_src }, |
| 14720 | | }); |
| 14739 | const resolved_type = try sema.resolvePeerTypes( |
| 14740 | block, |
| 14741 | src, |
| 14742 | .{ .insts = &.{ lhs, rhs } }, |
| 14743 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14744 | ); |
| 14721 | 14745 | |
| 14722 | 14746 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14723 | 14747 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14785,13 +14809,15 @@ fn zirOverflowArithmetic( |
| 14785 | 14809 | |
| 14786 | 14810 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14787 | 14811 | |
| 14788 | | const instructions = &[_]Air.Inst.Ref{ uncasted_lhs, uncasted_rhs }; |
| 14789 | 14812 | const dest_ty = if (zir_tag == .shl_with_overflow) |
| 14790 | 14813 | lhs_ty |
| 14791 | 14814 | else |
| 14792 | | try sema.resolvePeerTypes(block, src, instructions, .{ |
| 14793 | | .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, |
| 14794 | | }); |
| 14815 | try sema.resolvePeerTypes( |
| 14816 | block, |
| 14817 | src, |
| 14818 | .{ .insts = &.{ uncasted_lhs, uncasted_rhs } }, |
| 14819 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 14820 | ); |
| 14795 | 14821 | |
| 14796 | 14822 | const rhs_dest_ty = if (zir_tag == .shl_with_overflow) |
| 14797 | 14823 | try sema.log2IntType(block, lhs_ty, src) |
| ... | ... | @@ -15126,9 +15152,12 @@ fn analyzeArithmetic( |
| 15126 | 15152 | } |
| 15127 | 15153 | } |
| 15128 | 15154 | |
| 15129 | | const resolved_type = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ |
| 15130 | | .override = &.{ lhs_src, rhs_src }, |
| 15131 | | }); |
| 15155 | const resolved_type = try sema.resolvePeerTypes( |
| 15156 | block, |
| 15157 | src, |
| 15158 | .{ .insts = &.{ lhs, rhs } }, |
| 15159 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 15160 | ); |
| 15132 | 15161 | |
| 15133 | 15162 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 15134 | 15163 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -15732,8 +15761,12 @@ fn analyzeCmp( |
| 15732 | 15761 | const casted_rhs = try sema.analyzeErrUnionCode(block, rhs_src, rhs); |
| 15733 | 15762 | return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src); |
| 15734 | 15763 | } |
| 15735 | | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 15736 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); |
| 15764 | const resolved_type = try sema.resolvePeerTypes( |
| 15765 | block, |
| 15766 | src, |
| 15767 | .{ .insts = &.{ lhs, rhs } }, |
| 15768 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 15769 | ); |
| 15737 | 15770 | if (!resolved_type.isSelfComparable(zcu, is_equality_cmp)) { |
| 15738 | 15771 | return sema.fail(block, src, "operator {s} not allowed for type '{f}'", .{ |
| 15739 | 15772 | compareOperatorName(op), resolved_type.fmt(zcu), |
| ... | ... | @@ -17396,7 +17429,12 @@ fn zirTypeofPeer( |
| 17396 | 17429 | inst_list[i] = sema.resolveInst(arg_ref); |
| 17397 | 17430 | } |
| 17398 | 17431 | |
| 17399 | | const result_type = try sema.resolvePeerTypes(block, src, inst_list, .{ .typeof_builtin_call_node_offset = extra.data.src_node }); |
| 17432 | const result_type = try sema.resolvePeerTypes( |
| 17433 | block, |
| 17434 | src, |
| 17435 | .{ .insts = inst_list }, |
| 17436 | .{ .typeof_builtin_call_node_offset = extra.data.src_node }, |
| 17437 | ); |
| 17400 | 17438 | return Air.internedToRef(result_type.toIntern()); |
| 17401 | 17439 | } |
| 17402 | 17440 | |
| ... | ... | @@ -22994,9 +23032,12 @@ fn checkSimdBinOp( |
| 22994 | 23032 | |
| 22995 | 23033 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 22996 | 23034 | const vec_len: ?usize = if (lhs_ty.zigTypeTag(zcu) == .vector) lhs_ty.vectorLen(zcu) else null; |
| 22997 | | const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{ |
| 22998 | | .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, |
| 22999 | | }); |
| 23035 | const result_ty = try sema.resolvePeerTypes( |
| 23036 | block, |
| 23037 | src, |
| 23038 | .{ .insts = &.{ uncasted_lhs, uncasted_rhs } }, |
| 23039 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 23040 | ); |
| 23000 | 23041 | const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src); |
| 23001 | 23042 | const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src); |
| 23002 | 23043 | |
| ... | ... | @@ -32294,7 +32335,12 @@ fn cmpVector( |
| 32294 | 32335 | assert(rhs_ty.zigTypeTag(zcu) == .vector); |
| 32295 | 32336 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 32296 | 32337 | |
| 32297 | | const resolved_ty = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ .override = &.{ lhs_src, rhs_src } }); |
| 32338 | const resolved_ty = try sema.resolvePeerTypes( |
| 32339 | block, |
| 32340 | src, |
| 32341 | .{ .insts = &.{ lhs, rhs } }, |
| 32342 | .{ .override = &.{ lhs_src, rhs_src } }, |
| 32343 | ); |
| 32298 | 32344 | const casted_lhs = try sema.coerce(block, resolved_ty, lhs, lhs_src); |
| 32299 | 32345 | const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src); |
| 32300 | 32346 | |
| ... | ... | @@ -32628,7 +32674,7 @@ const PeerResolveResult = union(enum) { |
| 32628 | 32674 | sema: *Sema, |
| 32629 | 32675 | block: *Block, |
| 32630 | 32676 | src: LazySrcLoc, |
| 32631 | | instructions: []const Air.Inst.Ref, |
| 32677 | start_peer_tys: []const Type, |
| 32632 | 32678 | candidate_srcs: PeerTypeCandidateSrc, |
| 32633 | 32679 | ) !*Zcu.ErrorMsg { |
| 32634 | 32680 | const zcu = sema.pt.zcu; |
| ... | ... | @@ -32636,11 +32682,7 @@ const PeerResolveResult = union(enum) { |
| 32636 | 32682 | var opt_msg: ?*Zcu.ErrorMsg = null; |
| 32637 | 32683 | errdefer if (opt_msg) |msg| msg.destroy(sema.gpa); |
| 32638 | 32684 | |
| 32639 | | // If we mention fields we'll want to include field types, so put peer types in a buffer |
| 32640 | | var peer_tys = try sema.arena.alloc(Type, instructions.len); |
| 32641 | | for (peer_tys, instructions) |*ty, inst| { |
| 32642 | | ty.* = sema.typeOf(inst); |
| 32643 | | } |
| 32685 | var peer_tys = start_peer_tys; |
| 32644 | 32686 | |
| 32645 | 32687 | var cur = result; |
| 32646 | 32688 | while (true) { |
| ... | ... | @@ -32716,38 +32758,70 @@ fn resolvePeerTypes( |
| 32716 | 32758 | sema: *Sema, |
| 32717 | 32759 | block: *Block, |
| 32718 | 32760 | src: LazySrcLoc, |
| 32719 | | instructions: []const Air.Inst.Ref, |
| 32761 | peers: union(enum) { |
| 32762 | insts: []const Air.Inst.Ref, |
| 32763 | types: []const Type, |
| 32764 | }, |
| 32720 | 32765 | candidate_srcs: PeerTypeCandidateSrc, |
| 32721 | 32766 | ) !Type { |
| 32722 | | switch (instructions.len) { |
| 32723 | | 0 => return .noreturn, |
| 32724 | | 1 => return sema.typeOf(instructions[0]), |
| 32725 | | else => {}, |
| 32726 | | } |
| 32767 | const peer_tys: []?Type, const peer_vals: []?Value = switch (peers) { |
| 32768 | .insts => |insts| peers: { |
| 32769 | if (insts.len == 0) return .noreturn; |
| 32770 | |
| 32771 | // If everything is the same type we can bypass the main PTR logic. |
| 32772 | const first_ty = sema.typeOf(insts[0]); |
| 32773 | for (insts[1..]) |inst| { |
| 32774 | if (sema.typeOf(inst).toIntern() != first_ty.toIntern()) { |
| 32775 | break; |
| 32776 | } |
| 32777 | } else return first_ty; |
| 32727 | 32778 | |
| 32728 | | // Fast path: check if everything has the same type to bypass the main PTR logic. |
| 32729 | | same_type: { |
| 32730 | | const ty = sema.typeOf(instructions[0]); |
| 32731 | | for (instructions[1..]) |inst| { |
| 32732 | | if (sema.typeOf(inst).toIntern() != ty.toIntern()) { |
| 32733 | | break :same_type; |
| 32779 | const peer_tys = try sema.arena.alloc(?Type, insts.len); |
| 32780 | const peer_vals = try sema.arena.alloc(?Value, insts.len); |
| 32781 | |
| 32782 | for (peer_tys, peer_vals, insts) |*ty, *val, inst| { |
| 32783 | ty.* = sema.typeOf(inst); |
| 32784 | val.* = sema.resolveValue(inst); |
| 32734 | 32785 | } |
| 32735 | | } |
| 32736 | | return ty; |
| 32737 | | } |
| 32738 | 32786 | |
| 32739 | | const peer_tys = try sema.arena.alloc(?Type, instructions.len); |
| 32740 | | const peer_vals = try sema.arena.alloc(?Value, instructions.len); |
| 32787 | break :peers .{ peer_tys, peer_vals }; |
| 32788 | }, |
| 32741 | 32789 | |
| 32742 | | for (instructions, peer_tys, peer_vals) |inst, *ty, *val| { |
| 32743 | | ty.* = sema.typeOf(inst); |
| 32744 | | val.* = sema.resolveValue(inst); |
| 32745 | | } |
| 32790 | .types => |types| peers: { |
| 32791 | if (types.len == 0) return .noreturn; |
| 32792 | |
| 32793 | // If everything is the same type we can bypass the main PTR logic. |
| 32794 | for (types[1..]) |ty| { |
| 32795 | if (ty.toIntern() != types[0].toIntern()) { |
| 32796 | break; |
| 32797 | } |
| 32798 | } else return types[0]; |
| 32799 | |
| 32800 | const peer_tys = try sema.arena.alloc(?Type, types.len); |
| 32801 | const peer_vals = try sema.arena.alloc(?Value, types.len); |
| 32802 | |
| 32803 | for (peer_tys, peer_vals, types) |*opt_ty, *opt_val, ty| { |
| 32804 | opt_ty.* = ty; |
| 32805 | opt_val.* = try ty.onePossibleValue(sema.pt); |
| 32806 | } |
| 32807 | |
| 32808 | break :peers .{ peer_tys, peer_vals }; |
| 32809 | }, |
| 32810 | }; |
| 32746 | 32811 | |
| 32747 | 32812 | switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals)) { |
| 32748 | 32813 | .success => |ty| return ty, |
| 32749 | 32814 | else => |result| { |
| 32750 | | const msg = try result.report(sema, block, src, instructions, candidate_srcs); |
| 32815 | // We can't pass in `peer_tys` because `resolvePeerTypesInner` may clobber it. |
| 32816 | const report_peer_tys: []const Type = switch (peers) { |
| 32817 | .insts => |insts| types: { |
| 32818 | const types = try sema.arena.alloc(Type, insts.len); |
| 32819 | for (types, insts) |*ty, inst| ty.* = sema.typeOf(inst); |
| 32820 | break :types types; |
| 32821 | }, |
| 32822 | .types => |types| types, |
| 32823 | }; |
| 32824 | const msg = try result.report(sema, block, src, report_peer_tys, candidate_srcs); |
| 32751 | 32825 | return sema.failWithOwnedErrorMsg(block, msg); |
| 32752 | 32826 | }, |
| 32753 | 32827 | } |