authorgravatar for mparadinha@users.noreply.github.commparadinha <mparadinha@users.noreply.github.com> 2022-11-15 13:17:23+00:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 14:05:29-07:00
log35c13c262c99c3ae43dfffae0ea4ec331da25255
tree4c116a2fc39d1097f64032ba9540fc77ee122f8a
parent2d623d777406a0e1043eb9cf770c90468c65e52f

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...@@ -29768,9 +29768,20 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
29768 extra_index += body.len;29768 extra_index += body.len;
29769 const init = try sema.resolveBody(&block_scope, body, struct_obj.zir_index);29769 const init = try sema.resolveBody(&block_scope, body, struct_obj.zir_index);
29770 const field = &struct_obj.fields.values()[i];29770 const field = &struct_obj.fields.values()[i];
29771 const coerced = try sema.coerce(&block_scope, field.ty, init, src);29771 const coerced = sema.coerce(&block_scope, field.ty, init, .unneeded) catch |err| switch (err) {
29772 const default_val = (try sema.resolveMaybeUndefVal(coerced)) orelse29772 error.NeededSourceLocation => {
29773 return sema.failWithNeededComptime(&block_scope, src, "struct field default value must be comptime-known");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 };
29774 field.default_val = try default_val.copy(decl_arena_allocator);29785 field.default_val = try default_val.copy(decl_arena_allocator);
29775 }29786 }
29776 }29787 }
...@@ -30553,11 +30564,49 @@ fn enumFieldSrcLoc(...@@ -30553,11 +30564,49 @@ fn enumFieldSrcLoc(
30553 node_offset: i32,30564 node_offset: i32,
30554 field_index: usize,30565 field_index: usize,
30555) LazySrcLoc {30566) 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 {
30556 @setCold(true);30603 @setCold(true);
30557 const enum_node = decl.relativeToNodeIndex(node_offset);30604 const enum_node = decl.relativeToNodeIndex(node_offset);
30558 const node_tags = tree.nodes.items(.tag);30605 const node_tags = tree.nodes.items(.tag);
30559 var buffer: [2]std.zig.Ast.Node.Index = undefined;30606 var buffer: [2]std.zig.Ast.Node.Index = undefined;
30560 const container_decl = switch (node_tags[enum_node]) {30607 const container_decl = switch (node_tags[enum_node]) {
30608 .root => tree.containerDeclRoot(),
30609
30561 .container_decl,30610 .container_decl,
30562 .container_decl_trailing,30611 .container_decl_trailing,
30563 => tree.containerDecl(enum_node),30612 => tree.containerDecl(enum_node),
...@@ -30580,8 +30629,7 @@ fn enumFieldSrcLoc(...@@ -30580,8 +30629,7 @@ fn enumFieldSrcLoc(
30580 .tagged_union_enum_tag_trailing,30629 .tagged_union_enum_tag_trailing,
30581 => tree.taggedUnionEnumTag(enum_node),30630 => tree.taggedUnionEnumTag(enum_node),
3058230631
30583 // Container was constructed with `@Type`.30632 else => return null,
30584 else => return LazySrcLoc.nodeOffset(0),
30585 };30633 };
30586 var it_index: usize = 0;30634 var it_index: usize = 0;
30587 for (container_decl.ast.members) |member_node| {30635 for (container_decl.ast.members) |member_node| {
...@@ -30590,9 +30638,7 @@ fn enumFieldSrcLoc(...@@ -30590,9 +30638,7 @@ fn enumFieldSrcLoc(
30590 .container_field_align,30638 .container_field_align,
30591 .container_field,30639 .container_field,
30592 => {30640 => {
30593 if (it_index == field_index) {30641 if (it_index == field_index) return member_node;
30594 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(member_node));
30595 }
30596 it_index += 1;30642 it_index += 1;
30597 },30643 },
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 @@...@@ -1,4 +1,6 @@
1fn ignore(comptime param: anytype) void {_ = param;}1fn ignore(comptime param: anytype) void {
2 _ = param;
3}
24
3export fn foo() void {5export fn foo() void {
4 const MyStruct = struct {6 const MyStruct = struct {
...@@ -12,5 +14,5 @@ export fn foo() void {...@@ -12,5 +14,5 @@ export fn foo() void {
12// backend=stage214// backend=stage2
13// target=native15// target=native
14//16//
15// :4:22: error: expected type '[]u8', found '*const [3:0]u8'17// :7:28: error: expected type '[]u8', found '*const [3:0]u8'
16// :4:22: note: cast discards const qualifier18// :7:28: note: cast discards const qualifier