authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-16 11:25:32+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-16 11:26:35+00:00
loge6cf3ce24c42d4a2dffd4f0204a22a31eef3c562
treeeaa21f0a22f03d595151edc806d7120d8f5e0074
parent260c84535546c81028cf42f1eb6ec9f17275db0f
signaturelock-open Commit is signed but in an unrecognized format.

Sema: correct source location for return value coercion errors

When coercing the operand of a `ret_node` etc instruction, the source location for errors used to point to the entire `return` statement. Instead, we now point to the operand, as would be expected if there was an explicit `as_node` instruction (like there used to be).

2 files changed, 23 insertions(+), 7 deletions(-)

src/Module.zig+15
......@@ -1867,6 +1867,16 @@ pub const SrcLoc = struct {
18671867 else => return nodeToSpan(tree, node),
18681868 }
18691869 },
1870 .node_offset_return_operand => |node_off| {
1871 const tree = try src_loc.file_scope.getTree(gpa);
1872 const node = src_loc.declRelativeToNodeIndex(node_off);
1873 const node_tags = tree.nodes.items(.tag);
1874 const node_datas = tree.nodes.items(.data);
1875 if (node_tags[node] == .@"return" and node_datas[node].lhs != 0) {
1876 return nodeToSpan(tree, node_datas[node].lhs);
1877 }
1878 return nodeToSpan(tree, node);
1879 },
18701880 }
18711881 }
18721882
......@@ -2221,6 +2231,10 @@ pub const LazySrcLoc = union(enum) {
22212231 /// The source location points to the RHS of an assignment.
22222232 /// The Decl is determined contextually.
22232233 node_offset_store_operand: i32,
2234 /// The source location points to the operand of a `return` statement, or
2235 /// the `return` itself if there is no explicit operand.
2236 /// The Decl is determined contextually.
2237 node_offset_return_operand: i32,
22242238 /// The source location points to a for loop input.
22252239 /// The Decl is determined contextually.
22262240 for_input: struct {
......@@ -2347,6 +2361,7 @@ pub const LazySrcLoc = union(enum) {
23472361 .node_offset_init_ty,
23482362 .node_offset_store_ptr,
23492363 .node_offset_store_operand,
2364 .node_offset_return_operand,
23502365 .for_input,
23512366 .for_capture_from_input,
23522367 .array_cat_lhs,
src/Sema.zig+8-7
......@@ -19182,7 +19182,7 @@ fn zirRetErrValue(
1918219182 .ty = error_set_type.toIntern(),
1918319183 .name = err_name,
1918419184 } })));
19185 return sema.analyzeRet(block, result_inst, src);
19185 return sema.analyzeRet(block, result_inst, src, src);
1918619186}
1918719187
1918819188fn zirRetImplicit(
......@@ -19232,7 +19232,7 @@ fn zirRetImplicit(
1923219232 return sema.failWithOwnedErrorMsg(block, msg);
1923319233 }
1923419234
19235 return sema.analyzeRet(block, operand, r_brace_src);
19235 return sema.analyzeRet(block, operand, r_brace_src, r_brace_src);
1923619236}
1923719237
1923819238fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
......@@ -19243,7 +19243,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1924319243 const operand = try sema.resolveInst(inst_data.operand);
1924419244 const src = inst_data.src();
1924519245
19246 return sema.analyzeRet(block, operand, src);
19246 return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node });
1924719247}
1924819248
1924919249fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
......@@ -19256,7 +19256,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1925619256
1925719257 if (block.is_comptime or block.inlining != null or sema.func_is_naked) {
1925819258 const operand = try sema.analyzeLoad(block, src, ret_ptr, src);
19259 return sema.analyzeRet(block, operand, src);
19259 return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node });
1926019260 }
1926119261
1926219262 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
......@@ -19450,6 +19450,7 @@ fn analyzeRet(
1945019450 block: *Block,
1945119451 uncasted_operand: Air.Inst.Ref,
1945219452 src: LazySrcLoc,
19453 operand_src: LazySrcLoc,
1945319454) CompileError!Zir.Inst.Index {
1945419455 // Special case for returning an error to an inferred error set; we need to
1945519456 // add the error tag to the inferred error set of the in-scope function, so
......@@ -19458,14 +19459,14 @@ fn analyzeRet(
1945819459 if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {
1945919460 try sema.addToInferredErrorSet(uncasted_operand);
1946019461 }
19461 const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) {
19462 const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, operand_src, .{ .is_ret = true }) catch |err| switch (err) {
1946219463 error.NotCoercible => unreachable,
1946319464 else => |e| return e,
1946419465 };
1946519466
1946619467 if (block.inlining) |inlining| {
1946719468 if (block.is_comptime) {
19468 const ret_val = try sema.resolveConstValue(block, src, operand, .{
19469 const ret_val = try sema.resolveConstValue(block, operand_src, operand, .{
1946919470 .needed_comptime_reason = "value being returned at comptime must be comptime-known",
1947019471 });
1947119472 inlining.comptime_result = operand;
......@@ -19500,7 +19501,7 @@ fn analyzeRet(
1950019501 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
1950119502 // Avoid adding a frame to the error return trace in case the value is comptime-known
1950219503 // to be not an error.
19503 const is_non_err = try sema.analyzeIsNonErr(block, src, operand);
19504 const is_non_err = try sema.analyzeIsNonErr(block, operand_src, operand);
1950419505 return sema.retWithErrTracing(block, src, is_non_err, air_tag, operand);
1950519506 }
1950619507