| ... | @@ -1516,7 +1516,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde | ... | @@ -1516,7 +1516,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 1516 | | 1516 | |
| 1517 | if (ptr_val.castTag(.inferred_alloc)) |inferred_alloc| { | 1517 | if (ptr_val.castTag(.inferred_alloc)) |inferred_alloc| { |
| 1518 | const peer_inst_list = inferred_alloc.data.stored_inst_list.items; | 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 | if (var_is_mut) { | 1520 | if (var_is_mut) { |
| 1521 | try sema.validateVarType(block, ty_src, final_elem_ty); | 1521 | try sema.validateVarType(block, ty_src, final_elem_ty); |
| 1522 | } | 1522 | } |
| ... | @@ -2123,7 +2123,7 @@ fn analyzeBlockBody( | ... | @@ -2123,7 +2123,7 @@ fn analyzeBlockBody( |
| 2123 | // Need to set the type and emit the Block instruction. This allows machine code generation | 2123 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 2124 | // to emit a jump instruction to after the block when it encounters the break. | 2124 | // to emit a jump instruction to after the block when it encounters the break. |
| 2125 | try parent_block.instructions.append(gpa, merges.block_inst); | 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 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | 2127 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 2128 | child_block.instructions.items.len); | 2128 | child_block.instructions.items.len); |
| 2129 | sema.air_instructions.items(.data)[merges.block_inst] = .{ .ty_pl = .{ | 2129 | sema.air_instructions.items(.data)[merges.block_inst] = .{ .ty_pl = .{ |
| ... | @@ -4768,7 +4768,7 @@ fn zirBitwise( | ... | @@ -4768,7 +4768,7 @@ fn zirBitwise( |
| 4768 | const rhs_ty = sema.typeOf(rhs); | 4768 | const rhs_ty = sema.typeOf(rhs); |
| 4769 | | 4769 | |
| 4770 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; | 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 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | 4772 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4773 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); | 4773 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 4774 | | 4774 | |
| ... | @@ -4914,7 +4914,7 @@ fn analyzeArithmetic( | ... | @@ -4914,7 +4914,7 @@ fn analyzeArithmetic( |
| 4914 | } | 4914 | } |
| 4915 | | 4915 | |
| 4916 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; | 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 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | 4918 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4919 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); | 4919 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 4920 | | 4920 | |
| ... | @@ -5223,7 +5223,7 @@ fn analyzeCmp( | ... | @@ -5223,7 +5223,7 @@ fn analyzeCmp( |
| 5223 | return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src); | 5223 | return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| 5224 | } | 5224 | } |
| 5225 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; | 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 | if (!resolved_type.isSelfComparable(is_equality_cmp)) { | 5227 | if (!resolved_type.isSelfComparable(is_equality_cmp)) { |
| 5228 | return sema.mod.fail(&block.base, src, "{s} operator not allowed for type '{}'", .{ | 5228 | return sema.mod.fail(&block.base, src, "{s} operator not allowed for type '{}'", .{ |
| 5229 | @tagName(op), resolved_type, | 5229 | @tagName(op), resolved_type, |
| ... | @@ -5433,7 +5433,7 @@ fn zirTypeofPeer( | ... | @@ -5433,7 +5433,7 @@ fn zirTypeofPeer( |
| 5433 | inst_list[i] = sema.resolveInst(arg_ref); | 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 | return sema.addType(result_type); | 5437 | return sema.addType(result_type); |
| 5438 | } | 5438 | } |
| 5439 | | 5439 | |
| ... | @@ -8324,42 +8324,12 @@ fn wrapErrorUnion( | ... | @@ -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 | fn resolvePeerTypes( | 8327 | fn resolvePeerTypes( |
| 8358 | sema: *Sema, | 8328 | sema: *Sema, |
| 8359 | block: *Scope.Block, | 8329 | block: *Scope.Block, |
| 8360 | src: LazySrcLoc, | 8330 | src: LazySrcLoc, |
| 8361 | instructions: []Air.Inst.Ref, | 8331 | instructions: []Air.Inst.Ref, |
| 8362 | typeof_builtin_call_node_offset: ?i32, | 8332 | candidate_srcs: Module.PeerTypeCandidateSrc, |
| 8363 | ) !Type { | 8333 | ) !Type { |
| 8364 | if (instructions.len == 0) | 8334 | if (instructions.len == 0) |
| 8365 | return Type.initTag(.noreturn); | 8335 | return Type.initTag(.noreturn); |
| ... | @@ -8437,20 +8407,31 @@ fn resolvePeerTypes( | ... | @@ -8437,20 +8407,31 @@ fn resolvePeerTypes( |
| 8437 | continue; | 8407 | continue; |
| 8438 | } | 8408 | } |
| 8439 | | 8409 | |
| 8440 | // At this point, we hit a compile error. If the call to | 8410 | // At this point, we hit a compile error. We need to recover |
| 8441 | // resolvePeerTypes originated from the @TypeOf builtin, we | 8411 | // the source locations. |
| 8442 | // need to recover 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 | const msg = msg: { | 8425 | const msg = msg: { |
| 8444 | const msg = try sema.mod.errMsg(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); | 8426 | const msg = try sema.mod.errMsg(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); |
| 8445 | errdefer msg.destroy(sema.gpa); | 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}); | 8429 | if (chosen_src) |src_loc| |
| 8452 | try sema.mod.errNote(&block.base, candidate_src, msg, "type '{}' here", .{candidate_ty}); | 8430 | try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{chosen_ty}); |
| 8453 | } | 8431 | |
| | 8432 | if (candidate_src) |src_loc| |
| | 8433 | try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{candidate_ty}); |
| | 8434 | |
| 8454 | break :msg msg; | 8435 | break :msg msg; |
| 8455 | }; | 8436 | }; |
| 8456 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); | 8437 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |