| ... | ... | @@ -1496,7 +1496,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 1496 | 1496 | |
| 1497 | 1497 | if (ptr_val.castTag(.inferred_alloc)) |inferred_alloc| { |
| 1498 | 1498 | const peer_inst_list = inferred_alloc.data.stored_inst_list.items; |
| 1499 | | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list); |
| 1499 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none); |
| 1500 | 1500 | if (var_is_mut) { |
| 1501 | 1501 | try sema.validateVarType(block, ty_src, final_elem_ty); |
| 1502 | 1502 | } |
| ... | ... | @@ -2103,7 +2103,7 @@ fn analyzeBlockBody( |
| 2103 | 2103 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 2104 | 2104 | // to emit a jump instruction to after the block when it encounters the break. |
| 2105 | 2105 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 2106 | | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items); |
| 2106 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none); |
| 2107 | 2107 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 2108 | 2108 | child_block.instructions.items.len); |
| 2109 | 2109 | sema.air_instructions.items(.data)[merges.block_inst] = .{ .ty_pl = .{ |
| ... | ... | @@ -5325,7 +5325,7 @@ fn zirBitwise( |
| 5325 | 5325 | const rhs_ty = sema.typeOf(rhs); |
| 5326 | 5326 | |
| 5327 | 5327 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 5328 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 5328 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); |
| 5329 | 5329 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 5330 | 5330 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 5331 | 5331 | |
| ... | ... | @@ -5506,7 +5506,7 @@ fn analyzeArithmetic( |
| 5506 | 5506 | }; |
| 5507 | 5507 | |
| 5508 | 5508 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 5509 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 5509 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); |
| 5510 | 5510 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 5511 | 5511 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 5512 | 5512 | |
| ... | ... | @@ -5817,7 +5817,7 @@ fn analyzeCmp( |
| 5817 | 5817 | return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| 5818 | 5818 | } |
| 5819 | 5819 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 5820 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 5820 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); |
| 5821 | 5821 | if (!resolved_type.isSelfComparable(is_equality_cmp)) { |
| 5822 | 5822 | return sema.mod.fail(&block.base, src, "{s} operator not allowed for type '{}'", .{ |
| 5823 | 5823 | @tagName(op), resolved_type, |
| ... | ... | @@ -6027,7 +6027,7 @@ fn zirTypeofPeer( |
| 6027 | 6027 | inst_list[i] = sema.resolveInst(arg_ref); |
| 6028 | 6028 | } |
| 6029 | 6029 | |
| 6030 | | const result_type = try sema.resolvePeerTypes(block, src, inst_list); |
| 6030 | const result_type = try sema.resolvePeerTypes(block, src, inst_list, .{ .typeof_builtin_call_node_offset = extra.data.src_node }); |
| 6031 | 6031 | return sema.addType(result_type); |
| 6032 | 6032 | } |
| 6033 | 6033 | |
| ... | ... | @@ -8966,6 +8966,7 @@ fn resolvePeerTypes( |
| 8966 | 8966 | block: *Scope.Block, |
| 8967 | 8967 | src: LazySrcLoc, |
| 8968 | 8968 | instructions: []Air.Inst.Ref, |
| 8969 | candidate_srcs: Module.PeerTypeCandidateSrc, |
| 8969 | 8970 | ) !Type { |
| 8970 | 8971 | if (instructions.len == 0) |
| 8971 | 8972 | return Type.initTag(.noreturn); |
| ... | ... | @@ -8976,7 +8977,8 @@ fn resolvePeerTypes( |
| 8976 | 8977 | const target = sema.mod.getTarget(); |
| 8977 | 8978 | |
| 8978 | 8979 | var chosen = instructions[0]; |
| 8979 | | for (instructions[1..]) |candidate| { |
| 8980 | var chosen_i: usize = 0; |
| 8981 | for (instructions[1..]) |candidate, candidate_i| { |
| 8980 | 8982 | const candidate_ty = sema.typeOf(candidate); |
| 8981 | 8983 | const chosen_ty = sema.typeOf(chosen); |
| 8982 | 8984 | if (candidate_ty.eql(chosen_ty)) |
| ... | ... | @@ -8985,12 +8987,14 @@ fn resolvePeerTypes( |
| 8985 | 8987 | continue; |
| 8986 | 8988 | if (chosen_ty.zigTypeTag() == .NoReturn) { |
| 8987 | 8989 | chosen = candidate; |
| 8990 | chosen_i = candidate_i + 1; |
| 8988 | 8991 | continue; |
| 8989 | 8992 | } |
| 8990 | 8993 | if (candidate_ty.zigTypeTag() == .Undefined) |
| 8991 | 8994 | continue; |
| 8992 | 8995 | if (chosen_ty.zigTypeTag() == .Undefined) { |
| 8993 | 8996 | chosen = candidate; |
| 8997 | chosen_i = candidate_i + 1; |
| 8994 | 8998 | continue; |
| 8995 | 8999 | } |
| 8996 | 9000 | if (chosen_ty.isInt() and |
| ... | ... | @@ -8999,18 +9003,21 @@ fn resolvePeerTypes( |
| 8999 | 9003 | { |
| 9000 | 9004 | if (chosen_ty.intInfo(target).bits < candidate_ty.intInfo(target).bits) { |
| 9001 | 9005 | chosen = candidate; |
| 9006 | chosen_i = candidate_i + 1; |
| 9002 | 9007 | } |
| 9003 | 9008 | continue; |
| 9004 | 9009 | } |
| 9005 | 9010 | if (chosen_ty.isFloat() and candidate_ty.isFloat()) { |
| 9006 | 9011 | if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) { |
| 9007 | 9012 | chosen = candidate; |
| 9013 | chosen_i = candidate_i + 1; |
| 9008 | 9014 | } |
| 9009 | 9015 | continue; |
| 9010 | 9016 | } |
| 9011 | 9017 | |
| 9012 | 9018 | if (chosen_ty.zigTypeTag() == .ComptimeInt and candidate_ty.isInt()) { |
| 9013 | 9019 | chosen = candidate; |
| 9020 | chosen_i = candidate_i + 1; |
| 9014 | 9021 | continue; |
| 9015 | 9022 | } |
| 9016 | 9023 | |
| ... | ... | @@ -9020,6 +9027,7 @@ fn resolvePeerTypes( |
| 9020 | 9027 | |
| 9021 | 9028 | if (chosen_ty.zigTypeTag() == .ComptimeFloat and candidate_ty.isFloat()) { |
| 9022 | 9029 | chosen = candidate; |
| 9030 | chosen_i = candidate_i + 1; |
| 9023 | 9031 | continue; |
| 9024 | 9032 | } |
| 9025 | 9033 | |
| ... | ... | @@ -9032,11 +9040,38 @@ fn resolvePeerTypes( |
| 9032 | 9040 | } |
| 9033 | 9041 | if (chosen_ty.zigTypeTag() == .EnumLiteral and candidate_ty.zigTypeTag() == .Enum) { |
| 9034 | 9042 | chosen = candidate; |
| 9043 | chosen_i = candidate_i + 1; |
| 9035 | 9044 | continue; |
| 9036 | 9045 | } |
| 9037 | 9046 | |
| 9038 | | // TODO error notes pointing out each type |
| 9039 | | return sema.mod.fail(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); |
| 9047 | // At this point, we hit a compile error. We need to recover |
| 9048 | // the source locations. |
| 9049 | const chosen_src = candidate_srcs.resolve( |
| 9050 | sema.gpa, |
| 9051 | block.src_decl, |
| 9052 | instructions.len, |
| 9053 | chosen_i, |
| 9054 | ); |
| 9055 | const candidate_src = candidate_srcs.resolve( |
| 9056 | sema.gpa, |
| 9057 | block.src_decl, |
| 9058 | instructions.len, |
| 9059 | candidate_i + 1, |
| 9060 | ); |
| 9061 | |
| 9062 | const msg = msg: { |
| 9063 | const msg = try sema.mod.errMsg(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); |
| 9064 | errdefer msg.destroy(sema.gpa); |
| 9065 | |
| 9066 | if (chosen_src) |src_loc| |
| 9067 | try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{chosen_ty}); |
| 9068 | |
| 9069 | if (candidate_src) |src_loc| |
| 9070 | try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{candidate_ty}); |
| 9071 | |
| 9072 | break :msg msg; |
| 9073 | }; |
| 9074 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |
| 9040 | 9075 | } |
| 9041 | 9076 | |
| 9042 | 9077 | return sema.typeOf(chosen); |