authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-11-21 15:12:03-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-11-21 15:12:03-05:00
log54d196bb300770394fd57db718ff1768edd552f8
treebea1eab99aeed800b92fc589ad505cb84a86f122
parentbe6f76655fb355426dc8f3824368376608bc0ba1
parentd63298da65df7fa2712bf9e9d65d36cd91af22fa
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #18057 from Vexu/fixes

Fix bad error location on field init with field access

5 files changed, 54 insertions(+), 4 deletions(-)

src/InternPool.zig+7
...@@ -8301,6 +8301,13 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index {...@@ -8301,6 +8301,13 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index {
8301 assert(ip.items.items(.tag)[func_decl_index] == .func_decl);8301 assert(ip.items.items(.tag)[func_decl_index] == .func_decl);
8302 break :b ip.items.items(.data)[func_decl_index] + zir_body_inst_field_index;8302 break :b ip.items.items(.data)[func_decl_index] + zir_body_inst_field_index;
8303 },8303 },
8304 .func_coerced => {
8305 const datas = ip.items.items(.data);
8306 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
8307 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
8308 ]);
8309 return ip.funcZirBodyInst(uncoerced_func_index);
8310 },
8304 else => unreachable,8311 else => unreachable,
8305 };8312 };
8306 return @enumFromInt(ip.extra.items[extra_index]);8313 return @enumFromInt(ip.extra.items[extra_index]);
src/Module.zig+15-2
...@@ -1467,6 +1467,14 @@ pub const SrcLoc = struct {...@@ -1467,6 +1467,14 @@ pub const SrcLoc = struct {
1467 const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));1467 const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));
1468 return Span{ .start = start, .end = end, .main = start };1468 return Span{ .start = start, .end = end, .main = start };
1469 },1469 },
1470 .node_offset_field_name_init => |node_off| {
1471 const tree = try src_loc.file_scope.getTree(gpa);
1472 const node = src_loc.declRelativeToNodeIndex(node_off);
1473 const tok_index = tree.firstToken(node) - 2;
1474 const start = tree.tokens.items(.start)[tok_index];
1475 const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));
1476 return Span{ .start = start, .end = end, .main = start };
1477 },
1470 .node_offset_deref_ptr => |node_off| {1478 .node_offset_deref_ptr => |node_off| {
1471 const tree = try src_loc.file_scope.getTree(gpa);1479 const tree = try src_loc.file_scope.getTree(gpa);
1472 const node = src_loc.declRelativeToNodeIndex(node_off);1480 const node = src_loc.declRelativeToNodeIndex(node_off);
...@@ -2132,10 +2140,14 @@ pub const LazySrcLoc = union(enum) {...@@ -2132,10 +2140,14 @@ pub const LazySrcLoc = union(enum) {
2132 /// The payload is offset from the containing Decl AST node.2140 /// The payload is offset from the containing Decl AST node.
2133 /// The source location points to the field name of:2141 /// The source location points to the field name of:
2134 /// * a field access expression (`a.b`), or2142 /// * a field access expression (`a.b`), or
2135 /// * the callee of a method call (`a.b()`), or2143 /// * the callee of a method call (`a.b()`)
2136 /// * the operand ("b" node) of a field initialization expression (`.a = b`), or
2137 /// The Decl is determined contextually.2144 /// The Decl is determined contextually.
2138 node_offset_field_name: i32,2145 node_offset_field_name: i32,
2146 /// The payload is offset from the containing Decl AST node.
2147 /// The source location points to the field name of the operand ("b" node)
2148 /// of a field initialization expression (`.a = b`)
2149 /// The Decl is determined contextually.
2150 node_offset_field_name_init: i32,
2139 /// The source location points to the pointer of a pointer deref expression,2151 /// The source location points to the pointer of a pointer deref expression,
2140 /// found by taking this AST node index offset from the containing2152 /// found by taking this AST node index offset from the containing
2141 /// Decl AST node, which points to a pointer deref AST node. Next, navigate2153 /// Decl AST node, which points to a pointer deref AST node. Next, navigate
...@@ -2374,6 +2386,7 @@ pub const LazySrcLoc = union(enum) {...@@ -2374,6 +2386,7 @@ pub const LazySrcLoc = union(enum) {
2374 .node_offset_slice_sentinel,2386 .node_offset_slice_sentinel,
2375 .node_offset_call_func,2387 .node_offset_call_func,
2376 .node_offset_field_name,2388 .node_offset_field_name,
2389 .node_offset_field_name_init,
2377 .node_offset_deref_ptr,2390 .node_offset_deref_ptr,
2378 .node_offset_asm_source,2391 .node_offset_asm_source,
2379 .node_offset_asm_ret_ty,2392 .node_offset_asm_ret_ty,
src/Sema.zig+2-2
...@@ -9931,7 +9931,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi...@@ -9931,7 +9931,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
9931 const mod = sema.mod;9931 const mod = sema.mod;
9932 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9932 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
9933 const src = inst_data.src();9933 const src = inst_data.src();
9934 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };9934 const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node };
9935 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;9935 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
9936 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.field_name_start));9936 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.field_name_start));
9937 const object_ptr = try sema.resolveInst(extra.lhs);9937 const object_ptr = try sema.resolveInst(extra.lhs);
...@@ -19921,7 +19921,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -19921,7 +19921,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
19921 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;19921 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
19922 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;19922 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
19923 const ty_src = inst_data.src();19923 const ty_src = inst_data.src();
19924 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };19924 const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node };
19925 const wrapped_aggregate_ty = sema.resolveType(block, ty_src, extra.container_type) catch |err| switch (err) {19925 const wrapped_aggregate_ty = sema.resolveType(block, ty_src, extra.container_type) catch |err| switch (err) {
19926 // Since this is a ZIR instruction that returns a type, encountering19926 // Since this is a ZIR instruction that returns a type, encountering
19927 // generic poison should not result in a failed compilation, but the19927 // generic poison should not result in a failed compilation, but the
test/behavior/call.zig+21
...@@ -499,3 +499,24 @@ test "call inline fn through pointer" {...@@ -499,3 +499,24 @@ test "call inline fn through pointer" {
499 const f = &S.foo;499 const f = &S.foo;
500 try f(123);500 try f(123);
501}501}
502
503test "call coerced function" {
504 const T = struct {
505 x: f64,
506 const T = @This();
507 usingnamespace Implement(1);
508 const F = fn (comptime f64) type;
509 const Implement: F = opaque {
510 fn implementer(comptime val: anytype) type {
511 return opaque {
512 fn incr(self: T) T {
513 return .{ .x = self.x + val };
514 }
515 };
516 }
517 }.implementer;
518 };
519
520 const a = T{ .x = 3 };
521 try std.testing.expect(a.incr().x == 4);
522}
test/cases/compile_errors/invalid_field_in_struct_value_expression.zig+9
...@@ -21,6 +21,13 @@ pub export fn entry() void {...@@ -21,6 +21,13 @@ pub export fn entry() void {
21 dump(.{ .field_1 = 123, .field_3 = 456 });21 dump(.{ .field_1 = 123, .field_3 = 456 });
22}22}
2323
24pub export fn entry1() void {
25 const x = Object{
26 .abc = 1,
27 };
28 _ = x;
29}
30
24// error31// error
25// backend=stage232// backend=stage2
26// target=native33// target=native
...@@ -29,3 +36,5 @@ pub export fn entry() void {...@@ -29,3 +36,5 @@ pub export fn entry() void {
29// :1:11: note: struct declared here36// :1:11: note: struct declared here
30// :21:30: error: no field named 'field_3' in struct 'tmp.Object'37// :21:30: error: no field named 'field_3' in struct 'tmp.Object'
31// :15:16: note: struct declared here38// :15:16: note: struct declared here
39// :26:10: error: no field named 'abc' in struct 'tmp.Object'
40// :15:16: note: struct declared here