| ... | @@ -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); | 1519 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, null); |
| 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); | 2126 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, null); |
| 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); | 4771 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, null); |
| 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); | 4917 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, null); |
| 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); | 5226 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, null); |
| 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); | 5436 | const result_type = try sema.resolvePeerTypes(block, src, inst_list, extra.data.src_node); |
| 5437 | return sema.addType(result_type); | 5437 | return sema.addType(result_type); |
| 5438 | } | 5438 | } |
| 5439 | | 5439 | |
| ... | @@ -8324,11 +8324,42 @@ fn wrapErrorUnion( | ... | @@ -8324,11 +8324,42 @@ 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 | |
| 8327 | fn resolvePeerTypes( | 8357 | fn resolvePeerTypes( |
| 8328 | sema: *Sema, | 8358 | sema: *Sema, |
| 8329 | block: *Scope.Block, | 8359 | block: *Scope.Block, |
| 8330 | src: LazySrcLoc, | 8360 | src: LazySrcLoc, |
| 8331 | instructions: []Air.Inst.Ref, | 8361 | instructions: []Air.Inst.Ref, |
| | 8362 | typeof_builtin_call_node_offset: ?i32, |
| 8332 | ) !Type { | 8363 | ) !Type { |
| 8333 | if (instructions.len == 0) | 8364 | if (instructions.len == 0) |
| 8334 | return Type.initTag(.noreturn); | 8365 | return Type.initTag(.noreturn); |
| ... | @@ -8339,7 +8370,8 @@ fn resolvePeerTypes( | ... | @@ -8339,7 +8370,8 @@ fn resolvePeerTypes( |
| 8339 | const target = sema.mod.getTarget(); | 8370 | const target = sema.mod.getTarget(); |
| 8340 | | 8371 | |
| 8341 | var chosen = instructions[0]; | 8372 | var chosen = instructions[0]; |
| 8342 | for (instructions[1..]) |candidate| { | 8373 | var chosen_i: usize = 0; |
| | 8374 | for (instructions[1..]) |candidate, candidate_i| { |
| 8343 | const candidate_ty = sema.typeOf(candidate); | 8375 | const candidate_ty = sema.typeOf(candidate); |
| 8344 | const chosen_ty = sema.typeOf(chosen); | 8376 | const chosen_ty = sema.typeOf(chosen); |
| 8345 | if (candidate_ty.eql(chosen_ty)) | 8377 | if (candidate_ty.eql(chosen_ty)) |
| ... | @@ -8348,12 +8380,14 @@ fn resolvePeerTypes( | ... | @@ -8348,12 +8380,14 @@ fn resolvePeerTypes( |
| 8348 | continue; | 8380 | continue; |
| 8349 | if (chosen_ty.zigTypeTag() == .NoReturn) { | 8381 | if (chosen_ty.zigTypeTag() == .NoReturn) { |
| 8350 | chosen = candidate; | 8382 | chosen = candidate; |
| | 8383 | chosen_i = candidate_i + 1; |
| 8351 | continue; | 8384 | continue; |
| 8352 | } | 8385 | } |
| 8353 | if (candidate_ty.zigTypeTag() == .Undefined) | 8386 | if (candidate_ty.zigTypeTag() == .Undefined) |
| 8354 | continue; | 8387 | continue; |
| 8355 | if (chosen_ty.zigTypeTag() == .Undefined) { | 8388 | if (chosen_ty.zigTypeTag() == .Undefined) { |
| 8356 | chosen = candidate; | 8389 | chosen = candidate; |
| | 8390 | chosen_i = candidate_i + 1; |
| 8357 | continue; | 8391 | continue; |
| 8358 | } | 8392 | } |
| 8359 | if (chosen_ty.isInt() and | 8393 | if (chosen_ty.isInt() and |
| ... | @@ -8362,18 +8396,21 @@ fn resolvePeerTypes( | ... | @@ -8362,18 +8396,21 @@ fn resolvePeerTypes( |
| 8362 | { | 8396 | { |
| 8363 | if (chosen_ty.intInfo(target).bits < candidate_ty.intInfo(target).bits) { | 8397 | if (chosen_ty.intInfo(target).bits < candidate_ty.intInfo(target).bits) { |
| 8364 | chosen = candidate; | 8398 | chosen = candidate; |
| | 8399 | chosen_i = candidate_i + 1; |
| 8365 | } | 8400 | } |
| 8366 | continue; | 8401 | continue; |
| 8367 | } | 8402 | } |
| 8368 | if (chosen_ty.isFloat() and candidate_ty.isFloat()) { | 8403 | if (chosen_ty.isFloat() and candidate_ty.isFloat()) { |
| 8369 | if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) { | 8404 | if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) { |
| 8370 | chosen = candidate; | 8405 | chosen = candidate; |
| | 8406 | chosen_i = candidate_i + 1; |
| 8371 | } | 8407 | } |
| 8372 | continue; | 8408 | continue; |
| 8373 | } | 8409 | } |
| 8374 | | 8410 | |
| 8375 | if (chosen_ty.zigTypeTag() == .ComptimeInt and candidate_ty.isInt()) { | 8411 | if (chosen_ty.zigTypeTag() == .ComptimeInt and candidate_ty.isInt()) { |
| 8376 | chosen = candidate; | 8412 | chosen = candidate; |
| | 8413 | chosen_i = candidate_i + 1; |
| 8377 | continue; | 8414 | continue; |
| 8378 | } | 8415 | } |
| 8379 | | 8416 | |
| ... | @@ -8383,6 +8420,7 @@ fn resolvePeerTypes( | ... | @@ -8383,6 +8420,7 @@ fn resolvePeerTypes( |
| 8383 | | 8420 | |
| 8384 | if (chosen_ty.zigTypeTag() == .ComptimeFloat and candidate_ty.isFloat()) { | 8421 | if (chosen_ty.zigTypeTag() == .ComptimeFloat and candidate_ty.isFloat()) { |
| 8385 | chosen = candidate; | 8422 | chosen = candidate; |
| | 8423 | chosen_i = candidate_i + 1; |
| 8386 | continue; | 8424 | continue; |
| 8387 | } | 8425 | } |
| 8388 | | 8426 | |
| ... | @@ -8395,15 +8433,24 @@ fn resolvePeerTypes( | ... | @@ -8395,15 +8433,24 @@ fn resolvePeerTypes( |
| 8395 | } | 8433 | } |
| 8396 | if (chosen_ty.zigTypeTag() == .EnumLiteral and candidate_ty.zigTypeTag() == .Enum) { | 8434 | if (chosen_ty.zigTypeTag() == .EnumLiteral and candidate_ty.zigTypeTag() == .Enum) { |
| 8397 | chosen = candidate; | 8435 | chosen = candidate; |
| | 8436 | chosen_i = candidate_i + 1; |
| 8398 | continue; | 8437 | continue; |
| 8399 | } | 8438 | } |
| 8400 | | 8439 | |
| | 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 |
| 8401 | const msg = msg: { | 8443 | const msg = msg: { |
| 8402 | const msg = try sema.mod.errMsg(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); | 8444 | const msg = try sema.mod.errMsg(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); |
| 8403 | errdefer msg.destroy(sema.gpa); | 8445 | errdefer msg.destroy(sema.gpa); |
| 8404 | // TODO add error notes | 8446 | // TODO add error notes for other scenarios |
| 8405 | // try sema.mod.errNote(&block.base, chosen.src, msg, "type '{}' here", .{chosen_ty}); | 8447 | if (typeof_builtin_call_node_offset) |node_offset| { |
| 8406 | // try sema.mod.errNote(&block.base, candidate.src, msg, "type '{}' here", .{candidate_ty}); | 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 | |
| | 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 | } |
| 8407 | break :msg msg; | 8454 | break :msg msg; |
| 8408 | }; | 8455 | }; |
| 8409 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); | 8456 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |