mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
Sema: improve error message when calling non-member function as method
Resolves: #14880
This commit is contained in:
parent
a097779b61
commit
948926c513
21
src/Sema.zig
21
src/Sema.zig
@ -23605,10 +23605,13 @@ fn fieldCallBind(
|
||||
}
|
||||
|
||||
// If we get here, we need to look for a decl in the struct type instead.
|
||||
switch (concrete_ty.zigTypeTag()) {
|
||||
.Struct, .Opaque, .Union, .Enum => {
|
||||
const found_decl = switch (concrete_ty.zigTypeTag()) {
|
||||
.Struct, .Opaque, .Union, .Enum => found_decl: {
|
||||
if (concrete_ty.getNamespace()) |namespace| {
|
||||
if (try sema.namespaceLookupRef(block, src, namespace, field_name)) |inst| {
|
||||
if (try sema.namespaceLookup(block, src, namespace, field_name)) |decl_idx| {
|
||||
try sema.addReferencedBy(block, src, decl_idx);
|
||||
const inst = try sema.analyzeDeclRef(decl_idx);
|
||||
|
||||
const decl_val = try sema.analyzeLoad(block, src, inst, src);
|
||||
const decl_type = sema.typeOf(decl_val);
|
||||
if (decl_type.zigTypeTag() == .Fn and
|
||||
@ -23625,7 +23628,7 @@ fn fieldCallBind(
|
||||
first_param_type.ptrSize() == .C) and
|
||||
first_param_type.childType().eql(concrete_ty, sema.mod)))
|
||||
{
|
||||
// zig fmt: on
|
||||
// zig fmt: on
|
||||
// TODO: bound fn calls on rvalues should probably
|
||||
// generate a by-value argument somehow.
|
||||
const ty = Type.Tag.bound_fn.init();
|
||||
@ -23664,16 +23667,22 @@ fn fieldCallBind(
|
||||
return sema.addConstant(ty, value);
|
||||
}
|
||||
}
|
||||
break :found_decl decl_idx;
|
||||
}
|
||||
}
|
||||
break :found_decl null;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
else => null,
|
||||
};
|
||||
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, src, "no field or member function named '{s}' in '{}'", .{ field_name, concrete_ty.fmt(sema.mod) });
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.addDeclaredHereNote(msg, concrete_ty);
|
||||
if (found_decl) |decl_idx| {
|
||||
const decl = sema.mod.declPtr(decl_idx);
|
||||
try sema.mod.errNoteNonLazy(decl.srcLoc(), msg, "'{s}' is not a member function", .{field_name});
|
||||
}
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
|
||||
@ -2,7 +2,7 @@ const Foo = struct {
|
||||
x: i32,
|
||||
|
||||
fn init(x: i32) Foo {
|
||||
return Foo {
|
||||
return Foo{
|
||||
.x = x,
|
||||
};
|
||||
}
|
||||
@ -20,3 +20,4 @@ export fn f() void {
|
||||
//
|
||||
// :14:9: error: no field or member function named 'init' in 'tmp.Foo'
|
||||
// :1:13: note: struct declared here
|
||||
// :4:5: note: 'init' is not a member function
|
||||
|
||||
@ -29,3 +29,4 @@ export fn foo() void {
|
||||
//
|
||||
// :23:6: error: no field or member function named 'init' in 'tmp.List'
|
||||
// :1:18: note: struct declared here
|
||||
// :5:9: note: 'init' is not a member function
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user