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