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