| ... | ... | @@ -1516,7 +1516,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 1516 | 1516 | |
| 1517 | 1517 | if (ptr_val.castTag(.inferred_alloc)) |inferred_alloc| { |
| 1518 | 1518 | const peer_inst_list = inferred_alloc.data.stored_inst_list.items; |
| 1519 | | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, null); |
| 1519 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none); |
| 1520 | 1520 | if (var_is_mut) { |
| 1521 | 1521 | try sema.validateVarType(block, ty_src, final_elem_ty); |
| 1522 | 1522 | } |
| ... | ... | @@ -2123,7 +2123,7 @@ fn analyzeBlockBody( |
| 2123 | 2123 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 2124 | 2124 | // to emit a jump instruction to after the block when it encounters the break. |
| 2125 | 2125 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 2126 | | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, null); |
| 2126 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none); |
| 2127 | 2127 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 2128 | 2128 | child_block.instructions.items.len); |
| 2129 | 2129 | sema.air_instructions.items(.data)[merges.block_inst] = .{ .ty_pl = .{ |
| ... | ... | @@ -4768,7 +4768,7 @@ fn zirBitwise( |
| 4768 | 4768 | const rhs_ty = sema.typeOf(rhs); |
| 4769 | 4769 | |
| 4770 | 4770 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 4771 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, null); |
| 4771 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); |
| 4772 | 4772 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4773 | 4773 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 4774 | 4774 | |
| ... | ... | @@ -4914,7 +4914,7 @@ fn analyzeArithmetic( |
| 4914 | 4914 | } |
| 4915 | 4915 | |
| 4916 | 4916 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 4917 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, null); |
| 4917 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); |
| 4918 | 4918 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4919 | 4919 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 4920 | 4920 | |
| ... | ... | @@ -5223,7 +5223,7 @@ fn analyzeCmp( |
| 5223 | 5223 | return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| 5224 | 5224 | } |
| 5225 | 5225 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 5226 | | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, null); |
| 5226 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); |
| 5227 | 5227 | if (!resolved_type.isSelfComparable(is_equality_cmp)) { |
| 5228 | 5228 | return sema.mod.fail(&block.base, src, "{s} operator not allowed for type '{}'", .{ |
| 5229 | 5229 | @tagName(op), resolved_type, |
| ... | ... | @@ -5433,7 +5433,7 @@ fn zirTypeofPeer( |
| 5433 | 5433 | inst_list[i] = sema.resolveInst(arg_ref); |
| 5434 | 5434 | } |
| 5435 | 5435 | |
| 5436 | | const result_type = try sema.resolvePeerTypes(block, src, inst_list, extra.data.src_node); |
| 5436 | const result_type = try sema.resolvePeerTypes(block, src, inst_list, .{ .typeof_builtin_call_node_offset = extra.data.src_node }); |
| 5437 | 5437 | return sema.addType(result_type); |
| 5438 | 5438 | } |
| 5439 | 5439 | |
| ... | ... | @@ -8324,42 +8324,12 @@ fn wrapErrorUnion( |
| 8324 | 8324 | } |
| 8325 | 8325 | } |
| 8326 | 8326 | |
| 8327 | | fn resolveTypeOfArgSrcLoc( |
| 8328 | | gpa: *Allocator, |
| 8329 | | decl: *Decl, |
| 8330 | | typeof_builtin_call_node_offset: i32, |
| 8331 | | candidates: usize, |
| 8332 | | candidate_i: usize, |
| 8333 | | ) LazySrcLoc { |
| 8334 | | @setCold(true); |
| 8335 | | if (candidates <= 2) { |
| 8336 | | switch (candidate_i) { |
| 8337 | | 0 => return LazySrcLoc{ .node_offset_builtin_call_arg0 = typeof_builtin_call_node_offset }, |
| 8338 | | 1 => return LazySrcLoc{ .node_offset_builtin_call_arg1 = typeof_builtin_call_node_offset }, |
| 8339 | | else => unreachable, |
| 8340 | | } |
| 8341 | | } |
| 8342 | | |
| 8343 | | const tree = decl.namespace.file_scope.getTree(gpa) catch |err| { |
| 8344 | | // In this case we emit a warning + a less precise source location. |
| 8345 | | log.warn("unable to load {s}: {s}", .{ |
| 8346 | | decl.namespace.file_scope.sub_file_path, @errorName(err), |
| 8347 | | }); |
| 8348 | | return LazySrcLoc{ .node_offset = 0 }; |
| 8349 | | }; |
| 8350 | | const node = decl.relativeToNodeIndex(typeof_builtin_call_node_offset); |
| 8351 | | const node_datas = tree.nodes.items(.data); |
| 8352 | | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; |
| 8353 | | |
| 8354 | | return LazySrcLoc{ .node_abs = params[candidate_i] }; |
| 8355 | | } |
| 8356 | | |
| 8357 | 8327 | fn resolvePeerTypes( |
| 8358 | 8328 | sema: *Sema, |
| 8359 | 8329 | block: *Scope.Block, |
| 8360 | 8330 | src: LazySrcLoc, |
| 8361 | 8331 | instructions: []Air.Inst.Ref, |
| 8362 | | typeof_builtin_call_node_offset: ?i32, |
| 8332 | candidate_srcs: Module.PeerTypeCandidateSrc, |
| 8363 | 8333 | ) !Type { |
| 8364 | 8334 | if (instructions.len == 0) |
| 8365 | 8335 | return Type.initTag(.noreturn); |
| ... | ... | @@ -8437,20 +8407,31 @@ fn resolvePeerTypes( |
| 8437 | 8407 | continue; |
| 8438 | 8408 | } |
| 8439 | 8409 | |
| 8440 | | // At this point, we hit a compile error. If the call to |
| 8441 | | // resolvePeerTypes originated from the @TypeOf builtin, we |
| 8442 | | // need to recover the source locations |
| 8410 | // At this point, we hit a compile error. We need to recover |
| 8411 | // the source locations. |
| 8412 | const chosen_src = candidate_srcs.resolve( |
| 8413 | sema.gpa, |
| 8414 | block.src_decl, |
| 8415 | instructions.len, |
| 8416 | chosen_i, |
| 8417 | ); |
| 8418 | const candidate_src = candidate_srcs.resolve( |
| 8419 | sema.gpa, |
| 8420 | block.src_decl, |
| 8421 | instructions.len, |
| 8422 | candidate_i + 1, |
| 8423 | ); |
| 8424 | |
| 8443 | 8425 | const msg = msg: { |
| 8444 | 8426 | const msg = try sema.mod.errMsg(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); |
| 8445 | 8427 | errdefer msg.destroy(sema.gpa); |
| 8446 | | // TODO add error notes for other scenarios |
| 8447 | | if (typeof_builtin_call_node_offset) |node_offset| { |
| 8448 | | const chosen_src = resolveTypeOfArgSrcLoc(sema.gpa, block.src_decl, node_offset, instructions.len, chosen_i); |
| 8449 | | const candidate_src = resolveTypeOfArgSrcLoc(sema.gpa, block.src_decl, node_offset, instructions.len, candidate_i + 1); |
| 8450 | 8428 | |
| 8451 | | try sema.mod.errNote(&block.base, chosen_src, msg, "type '{}' here", .{chosen_ty}); |
| 8452 | | try sema.mod.errNote(&block.base, candidate_src, msg, "type '{}' here", .{candidate_ty}); |
| 8453 | | } |
| 8429 | if (chosen_src) |src_loc| |
| 8430 | try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{chosen_ty}); |
| 8431 | |
| 8432 | if (candidate_src) |src_loc| |
| 8433 | try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{candidate_ty}); |
| 8434 | |
| 8454 | 8435 | break :msg msg; |
| 8455 | 8436 | }; |
| 8456 | 8437 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |