mirror of
https://github.com/ziglang/zig.git
synced 2025-12-25 23:53:15 +00:00
Sema: add declared here note to function call errors
This commit is contained in:
parent
0778490283
commit
b757a96d5c
92
src/Sema.zig
92
src/Sema.zig
@ -5409,6 +5409,19 @@ fn lookupInNamespace(
|
||||
return null;
|
||||
}
|
||||
|
||||
fn funcDeclSrc(sema: *Sema, block: *Block, src: LazySrcLoc, func_inst: Air.Inst.Ref) !?Module.SrcLoc {
|
||||
const func_val = (try sema.resolveMaybeUndefVal(block, src, func_inst)) orelse return null;
|
||||
if (func_val.isUndef()) return null;
|
||||
const owner_decl_index = switch (func_val.tag()) {
|
||||
.extern_fn => func_val.castTag(.extern_fn).?.data.owner_decl,
|
||||
.function => func_val.castTag(.function).?.data.owner_decl,
|
||||
.decl_ref => sema.mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data.owner_decl,
|
||||
else => return null,
|
||||
};
|
||||
const owner_decl = sema.mod.declPtr(owner_decl_index);
|
||||
return owner_decl.srcLoc();
|
||||
}
|
||||
|
||||
fn zirCall(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
@ -5464,41 +5477,35 @@ fn zirCall(
|
||||
const func_ty_info = func_ty.fnInfo();
|
||||
|
||||
const fn_params_len = func_ty_info.param_types.len;
|
||||
if (func_ty_info.is_var_args) {
|
||||
assert(func_ty_info.cc == .C);
|
||||
if (total_args < fn_params_len) {
|
||||
// TODO add error note: declared here
|
||||
if (bound_arg_src != null) {
|
||||
return sema.fail(
|
||||
block,
|
||||
call_src,
|
||||
"member function expected at least {d} argument(s), found {d}",
|
||||
.{ fn_params_len - 1, args_len },
|
||||
);
|
||||
}
|
||||
return sema.fail(
|
||||
check_args: {
|
||||
if (func_ty_info.is_var_args) {
|
||||
assert(func_ty_info.cc == .C);
|
||||
if (total_args >= fn_params_len) break :check_args;
|
||||
} else if (fn_params_len == total_args) {
|
||||
break :check_args;
|
||||
}
|
||||
|
||||
const decl_src = try sema.funcDeclSrc(block, func_src, func);
|
||||
const member_str = if (bound_arg_src != null) "member function " else "";
|
||||
const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(
|
||||
block,
|
||||
func_src,
|
||||
"expected at least {d} argument(s), found {d}",
|
||||
.{ fn_params_len, args_len },
|
||||
"{s}expected {s}{d} argument(s), found {d}",
|
||||
.{
|
||||
member_str,
|
||||
variadic_str,
|
||||
fn_params_len - @boolToInt(bound_arg_src != null),
|
||||
args_len,
|
||||
},
|
||||
);
|
||||
}
|
||||
} else if (fn_params_len != total_args) {
|
||||
// TODO add error note: declared here
|
||||
if (bound_arg_src != null) {
|
||||
return sema.fail(
|
||||
block,
|
||||
call_src,
|
||||
"member function expected {d} argument(s), found {d}",
|
||||
.{ fn_params_len - 1, args_len },
|
||||
);
|
||||
}
|
||||
return sema.fail(
|
||||
block,
|
||||
call_src,
|
||||
"expected {d} argument(s), found {d}",
|
||||
.{ fn_params_len, args_len },
|
||||
);
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
|
||||
if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
}
|
||||
|
||||
const args_body = sema.code.extra[extra.end..];
|
||||
@ -5625,13 +5632,20 @@ fn analyzeCall(
|
||||
const func_ty_info = func_ty.fnInfo();
|
||||
const cc = func_ty_info.cc;
|
||||
if (cc == .Naked) {
|
||||
// TODO add error note: declared here
|
||||
return sema.fail(
|
||||
block,
|
||||
func_src,
|
||||
"unable to call function with naked calling convention",
|
||||
.{},
|
||||
);
|
||||
const decl_src = try sema.funcDeclSrc(block, func_src, func);
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(
|
||||
block,
|
||||
func_src,
|
||||
"unable to call function with naked calling convention",
|
||||
.{},
|
||||
);
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
|
||||
if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
}
|
||||
const fn_params_len = func_ty_info.param_types.len;
|
||||
if (func_ty_info.is_var_args) {
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
export fn entry() void {
|
||||
foo();
|
||||
}
|
||||
fn foo() callconv(.Naked) void { }
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// target=native
|
||||
//
|
||||
// :2:5: error: unable to call function with naked calling convention
|
||||
// :4:1: note: function declared here
|
||||
@ -11,4 +11,5 @@ pub export fn entry() void {
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :7:10: error: member function expected 2 argument(s), found 1
|
||||
// :7:6: error: member function expected 2 argument(s), found 1
|
||||
// :3:5: note: function declared here
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
export fn entry() void {
|
||||
foo();
|
||||
}
|
||||
fn foo() callconv(.Naked) void { }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:5: error: unable to call function with naked calling convention
|
||||
// tmp.zig:4:1: note: declared here
|
||||
@ -1,14 +0,0 @@
|
||||
const Foo = struct {
|
||||
fn method(self: *const Foo, a: i32) void {_ = self; _ = a;}
|
||||
};
|
||||
fn f(foo: *const Foo) void {
|
||||
|
||||
foo.method(1, 2);
|
||||
}
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(f)); }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:6:15: error: expected 2 argument(s), found 3
|
||||
@ -7,4 +7,5 @@ fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:6: error: expected 3 argument(s), found 1
|
||||
// :2:5: error: expected 3 argument(s), found 1
|
||||
// :4:1: note: function declared here
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
const Foo = struct {
|
||||
fn method(self: *const Foo, a: i32) void {_ = self; _ = a;}
|
||||
};
|
||||
fn f(foo: *const Foo) void {
|
||||
|
||||
foo.method(1, 2);
|
||||
}
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(&f)); }
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :6:8: error: member function expected 1 argument(s), found 2
|
||||
// :2:5: note: function declared here
|
||||
Loading…
x
Reference in New Issue
Block a user