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 {...@@ -1867,6 +1867,16 @@ pub const SrcLoc = struct {
1867 else => return nodeToSpan(tree, node),1867 else => return nodeToSpan(tree, node),
1868 }1868 }
1869 },1869 },
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 },
1870 }1880 }
1871 }1881 }
18721882
...@@ -2221,6 +2231,10 @@ pub const LazySrcLoc = union(enum) {...@@ -2221,6 +2231,10 @@ pub const LazySrcLoc = union(enum) {
2221 /// The source location points to the RHS of an assignment.2231 /// The source location points to the RHS of an assignment.
2222 /// The Decl is determined contextually.2232 /// The Decl is determined contextually.
2223 node_offset_store_operand: i32,2233 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,
2224 /// The source location points to a for loop input.2238 /// The source location points to a for loop input.
2225 /// The Decl is determined contextually.2239 /// The Decl is determined contextually.
2226 for_input: struct {2240 for_input: struct {
...@@ -2347,6 +2361,7 @@ pub const LazySrcLoc = union(enum) {...@@ -2347,6 +2361,7 @@ pub const LazySrcLoc = union(enum) {
2347 .node_offset_init_ty,2361 .node_offset_init_ty,
2348 .node_offset_store_ptr,2362 .node_offset_store_ptr,
2349 .node_offset_store_operand,2363 .node_offset_store_operand,
2364 .node_offset_return_operand,
2350 .for_input,2365 .for_input,
2351 .for_capture_from_input,2366 .for_capture_from_input,
2352 .array_cat_lhs,2367 .array_cat_lhs,
src/Sema.zig+8-7
...@@ -19182,7 +19182,7 @@ fn zirRetErrValue(...@@ -19182,7 +19182,7 @@ fn zirRetErrValue(
19182 .ty = error_set_type.toIntern(),19182 .ty = error_set_type.toIntern(),
19183 .name = err_name,19183 .name = err_name,
19184 } })));19184 } })));
19185 return sema.analyzeRet(block, result_inst, src);19185 return sema.analyzeRet(block, result_inst, src, src);
19186}19186}
1918719187
19188fn zirRetImplicit(19188fn zirRetImplicit(
...@@ -19232,7 +19232,7 @@ fn zirRetImplicit(...@@ -19232,7 +19232,7 @@ fn zirRetImplicit(
19232 return sema.failWithOwnedErrorMsg(block, msg);19232 return sema.failWithOwnedErrorMsg(block, msg);
19233 }19233 }
1923419234
19235 return sema.analyzeRet(block, operand, r_brace_src);19235 return sema.analyzeRet(block, operand, r_brace_src, r_brace_src);
19236}19236}
1923719237
19238fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {19238fn 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...@@ -19243,7 +19243,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
19243 const operand = try sema.resolveInst(inst_data.operand);19243 const operand = try sema.resolveInst(inst_data.operand);
19244 const src = inst_data.src();19244 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 });
19247}19247}
1924819248
19249fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {19249fn 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...@@ -19256,7 +19256,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1925619256
19257 if (block.is_comptime or block.inlining != null or sema.func_is_naked) {19257 if (block.is_comptime or block.inlining != null or sema.func_is_naked) {
19258 const operand = try sema.analyzeLoad(block, src, ret_ptr, src);19258 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 });
19260 }19260 }
1926119261
19262 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {19262 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
...@@ -19450,6 +19450,7 @@ fn analyzeRet(...@@ -19450,6 +19450,7 @@ fn analyzeRet(
19450 block: *Block,19450 block: *Block,
19451 uncasted_operand: Air.Inst.Ref,19451 uncasted_operand: Air.Inst.Ref,
19452 src: LazySrcLoc,19452 src: LazySrcLoc,
19453 operand_src: LazySrcLoc,
19453) CompileError!Zir.Inst.Index {19454) CompileError!Zir.Inst.Index {
19454 // Special case for returning an error to an inferred error set; we need to19455 // Special case for returning an error to an inferred error set; we need to
19455 // add the error tag to the inferred error set of the in-scope function, so19456 // add the error tag to the inferred error set of the in-scope function, so
...@@ -19458,14 +19459,14 @@ fn analyzeRet(...@@ -19458,14 +19459,14 @@ fn analyzeRet(
19458 if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {19459 if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {
19459 try sema.addToInferredErrorSet(uncasted_operand);19460 try sema.addToInferredErrorSet(uncasted_operand);
19460 }19461 }
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) {
19462 error.NotCoercible => unreachable,19463 error.NotCoercible => unreachable,
19463 else => |e| return e,19464 else => |e| return e,
19464 };19465 };
1946519466
19466 if (block.inlining) |inlining| {19467 if (block.inlining) |inlining| {
19467 if (block.is_comptime) {19468 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, .{
19469 .needed_comptime_reason = "value being returned at comptime must be comptime-known",19470 .needed_comptime_reason = "value being returned at comptime must be comptime-known",
19470 });19471 });
19471 inlining.comptime_result = operand;19472 inlining.comptime_result = operand;
...@@ -19500,7 +19501,7 @@ fn analyzeRet(...@@ -19500,7 +19501,7 @@ fn analyzeRet(
19500 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {19501 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
19501 // Avoid adding a frame to the error return trace in case the value is comptime-known19502 // Avoid adding a frame to the error return trace in case the value is comptime-known
19502 // to be not an error.19503 // 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);
19504 return sema.retWithErrTracing(block, src, is_non_err, air_tag, operand);19505 return sema.retWithErrTracing(block, src, is_non_err, air_tag, operand);
19505 }19506 }
1950619507