authorgravatar for mparadinha@users.noreply.github.commparadinha <mparadinha@users.noreply.github.com> 2022-11-15 13:17:23+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-11-15 15:17:23+02:00
logc4f7663c921033a52b1688b88811c92422d58293
treedb397e08151a9666b3a1d03d6b97bcea9eada6e1
parentceb9fedb47d2a02b428e1dafaa3965104e752ddf
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Fix error reporting the wrong line for struct field inits (#13502)

* point to init part of field delc when that's where the error occurs * update test to reflect fixed error message * only lookup source location in case of error

2 files changed, 59 insertions(+), 11 deletions(-)

src/Sema.zig+54-8
......@@ -29768,9 +29768,20 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
2976829768 extra_index += body.len;
2976929769 const init = try sema.resolveBody(&block_scope, body, struct_obj.zir_index);
2977029770 const field = &struct_obj.fields.values()[i];
29771 const coerced = try sema.coerce(&block_scope, field.ty, init, src);
29772 const default_val = (try sema.resolveMaybeUndefVal(coerced)) orelse
29773 return sema.failWithNeededComptime(&block_scope, src, "struct field default value must be comptime-known");
29771 const coerced = sema.coerce(&block_scope, field.ty, init, .unneeded) catch |err| switch (err) {
29772 error.NeededSourceLocation => {
29773 const tree = try sema.getAstTree(&block_scope);
29774 const init_src = containerFieldInitSrcLoc(decl, tree.*, 0, i);
29775 _ = try sema.coerce(&block_scope, field.ty, init, init_src);
29776 return error.AnalysisFail;
29777 },
29778 else => |e| return e,
29779 };
29780 const default_val = (try sema.resolveMaybeUndefVal(coerced)) orelse {
29781 const tree = try sema.getAstTree(&block_scope);
29782 const init_src = containerFieldInitSrcLoc(decl, tree.*, 0, i);
29783 return sema.failWithNeededComptime(&block_scope, init_src, "struct field default value must be comptime-known");
29784 };
2977429785 field.default_val = try default_val.copy(decl_arena_allocator);
2977529786 }
2977629787 }
......@@ -30553,11 +30564,49 @@ fn enumFieldSrcLoc(
3055330564 node_offset: i32,
3055430565 field_index: usize,
3055530566) LazySrcLoc {
30567 @setCold(true);
30568 const field_node = containerFieldNode(decl, tree, node_offset, field_index) orelse
30569 return LazySrcLoc.nodeOffset(0);
30570 return decl.nodeSrcLoc(field_node);
30571}
30572
30573fn containerFieldInitSrcLoc(
30574 decl: *Decl,
30575 tree: std.zig.Ast,
30576 node_offset: i32,
30577 field_index: usize,
30578) LazySrcLoc {
30579 @setCold(true);
30580 const node_tags = tree.nodes.items(.tag);
30581 const field_node = containerFieldNode(decl, tree, node_offset, field_index) orelse
30582 return LazySrcLoc.nodeOffset(0);
30583 const node_data = tree.nodes.items(.data)[field_node];
30584
30585 const init_node = switch (node_tags[field_node]) {
30586 .container_field_init => node_data.rhs,
30587 .container_field => blk: {
30588 const extra_data = tree.extraData(node_data.rhs, std.zig.Ast.Node.ContainerField);
30589 break :blk extra_data.value_expr;
30590 },
30591 else => unreachable,
30592 };
30593
30594 return decl.nodeSrcLoc(init_node);
30595}
30596
30597fn containerFieldNode(
30598 decl: *Decl,
30599 tree: std.zig.Ast,
30600 node_offset: i32,
30601 field_index: usize,
30602) ?std.zig.Ast.Node.Index {
3055630603 @setCold(true);
3055730604 const enum_node = decl.relativeToNodeIndex(node_offset);
3055830605 const node_tags = tree.nodes.items(.tag);
3055930606 var buffer: [2]std.zig.Ast.Node.Index = undefined;
3056030607 const container_decl = switch (node_tags[enum_node]) {
30608 .root => tree.containerDeclRoot(),
30609
3056130610 .container_decl,
3056230611 .container_decl_trailing,
3056330612 => tree.containerDecl(enum_node),
......@@ -30580,8 +30629,7 @@ fn enumFieldSrcLoc(
3058030629 .tagged_union_enum_tag_trailing,
3058130630 => tree.taggedUnionEnumTag(enum_node),
3058230631
30583 // Container was constructed with `@Type`.
30584 else => return LazySrcLoc.nodeOffset(0),
30632 else => return null,
3058530633 };
3058630634 var it_index: usize = 0;
3058730635 for (container_decl.ast.members) |member_node| {
......@@ -30590,9 +30638,7 @@ fn enumFieldSrcLoc(
3059030638 .container_field_align,
3059130639 .container_field,
3059230640 => {
30593 if (it_index == field_index) {
30594 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(member_node));
30595 }
30641 if (it_index == field_index) return member_node;
3059630642 it_index += 1;
3059730643 },
3059830644
test/cases/compile_errors/issue_5221_invalid_struct_init_type_referenced_by_typeInfo_and_passed_into_function.zig+5-3
......@@ -1,4 +1,6 @@
1fn ignore(comptime param: anytype) void {_ = param;}
1fn ignore(comptime param: anytype) void {
2 _ = param;
3}
24
35export fn foo() void {
46 const MyStruct = struct {
......@@ -12,5 +14,5 @@ export fn foo() void {
1214// backend=stage2
1315// target=native
1416//
15// :4:22: error: expected type '[]u8', found '*const [3:0]u8'
16// :4:22: note: cast discards const qualifier
17// :7:28: error: expected type '[]u8', found '*const [3:0]u8'
18// :7:28: note: cast discards const qualifier