mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
Merge pull request #18057 from Vexu/fixes
Fix bad error location on field init with field access
This commit is contained in:
commit
54d196bb30
@ -8301,6 +8301,13 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index {
|
||||
assert(ip.items.items(.tag)[func_decl_index] == .func_decl);
|
||||
break :b ip.items.items(.data)[func_decl_index] + zir_body_inst_field_index;
|
||||
},
|
||||
.func_coerced => {
|
||||
const datas = ip.items.items(.data);
|
||||
const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
|
||||
datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
|
||||
]);
|
||||
return ip.funcZirBodyInst(uncoerced_func_index);
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
return @enumFromInt(ip.extra.items[extra_index]);
|
||||
|
||||
@ -1467,6 +1467,14 @@ pub const SrcLoc = struct {
|
||||
const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));
|
||||
return Span{ .start = start, .end = end, .main = start };
|
||||
},
|
||||
.node_offset_field_name_init => |node_off| {
|
||||
const tree = try src_loc.file_scope.getTree(gpa);
|
||||
const node = src_loc.declRelativeToNodeIndex(node_off);
|
||||
const tok_index = tree.firstToken(node) - 2;
|
||||
const start = tree.tokens.items(.start)[tok_index];
|
||||
const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));
|
||||
return Span{ .start = start, .end = end, .main = start };
|
||||
},
|
||||
.node_offset_deref_ptr => |node_off| {
|
||||
const tree = try src_loc.file_scope.getTree(gpa);
|
||||
const node = src_loc.declRelativeToNodeIndex(node_off);
|
||||
@ -2132,10 +2140,14 @@ pub const LazySrcLoc = union(enum) {
|
||||
/// The payload is offset from the containing Decl AST node.
|
||||
/// The source location points to the field name of:
|
||||
/// * a field access expression (`a.b`), or
|
||||
/// * the callee of a method call (`a.b()`), or
|
||||
/// * the operand ("b" node) of a field initialization expression (`.a = b`), or
|
||||
/// * the callee of a method call (`a.b()`)
|
||||
/// The Decl is determined contextually.
|
||||
node_offset_field_name: i32,
|
||||
/// The payload is offset from the containing Decl AST node.
|
||||
/// The source location points to the field name of the operand ("b" node)
|
||||
/// of a field initialization expression (`.a = b`)
|
||||
/// The Decl is determined contextually.
|
||||
node_offset_field_name_init: i32,
|
||||
/// The source location points to the pointer of a pointer deref expression,
|
||||
/// found by taking this AST node index offset from the containing
|
||||
/// Decl AST node, which points to a pointer deref AST node. Next, navigate
|
||||
@ -2374,6 +2386,7 @@ pub const LazySrcLoc = union(enum) {
|
||||
.node_offset_slice_sentinel,
|
||||
.node_offset_call_func,
|
||||
.node_offset_field_name,
|
||||
.node_offset_field_name_init,
|
||||
.node_offset_deref_ptr,
|
||||
.node_offset_asm_source,
|
||||
.node_offset_asm_ret_ty,
|
||||
|
||||
@ -9931,7 +9931,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
|
||||
const mod = sema.mod;
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
|
||||
const src = inst_data.src();
|
||||
const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
|
||||
const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node };
|
||||
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
|
||||
const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.field_name_start));
|
||||
const object_ptr = try sema.resolveInst(extra.lhs);
|
||||
@ -19921,7 +19921,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
|
||||
const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
|
||||
const ty_src = inst_data.src();
|
||||
const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
|
||||
const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node };
|
||||
const wrapped_aggregate_ty = sema.resolveType(block, ty_src, extra.container_type) catch |err| switch (err) {
|
||||
// Since this is a ZIR instruction that returns a type, encountering
|
||||
// generic poison should not result in a failed compilation, but the
|
||||
|
||||
@ -499,3 +499,24 @@ test "call inline fn through pointer" {
|
||||
const f = &S.foo;
|
||||
try f(123);
|
||||
}
|
||||
|
||||
test "call coerced function" {
|
||||
const T = struct {
|
||||
x: f64,
|
||||
const T = @This();
|
||||
usingnamespace Implement(1);
|
||||
const F = fn (comptime f64) type;
|
||||
const Implement: F = opaque {
|
||||
fn implementer(comptime val: anytype) type {
|
||||
return opaque {
|
||||
fn incr(self: T) T {
|
||||
return .{ .x = self.x + val };
|
||||
}
|
||||
};
|
||||
}
|
||||
}.implementer;
|
||||
};
|
||||
|
||||
const a = T{ .x = 3 };
|
||||
try std.testing.expect(a.incr().x == 4);
|
||||
}
|
||||
|
||||
@ -21,6 +21,13 @@ pub export fn entry() void {
|
||||
dump(.{ .field_1 = 123, .field_3 = 456 });
|
||||
}
|
||||
|
||||
pub export fn entry1() void {
|
||||
const x = Object{
|
||||
.abc = 1,
|
||||
};
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
@ -29,3 +36,5 @@ pub export fn entry() void {
|
||||
// :1:11: note: struct declared here
|
||||
// :21:30: error: no field named 'field_3' in struct 'tmp.Object'
|
||||
// :15:16: note: struct declared here
|
||||
// :26:10: error: no field named 'abc' in struct 'tmp.Object'
|
||||
// :15:16: note: struct declared here
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user