authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-09 23:37:26+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-09 23:37:26+03:00
logb757a96d5c885442c38e217006d75c85a28daf09
tree61c938338f48de60fb50c00fa2d0cf33833e4209
parent0778490283a8129755e411877453a173759ab4f4

Sema: add declared here note to function call errors


7 files changed, 83 insertions(+), 66 deletions(-)

src/Sema.zig+53-39
...@@ -5409,6 +5409,19 @@ fn lookupInNamespace(...@@ -5409,6 +5409,19 @@ fn lookupInNamespace(
5409 return null;5409 return null;
5410}5410}
54115411
5412fn funcDeclSrc(sema: *Sema, block: *Block, src: LazySrcLoc, func_inst: Air.Inst.Ref) !?Module.SrcLoc {
5413 const func_val = (try sema.resolveMaybeUndefVal(block, src, func_inst)) orelse return null;
5414 if (func_val.isUndef()) return null;
5415 const owner_decl_index = switch (func_val.tag()) {
5416 .extern_fn => func_val.castTag(.extern_fn).?.data.owner_decl,
5417 .function => func_val.castTag(.function).?.data.owner_decl,
5418 .decl_ref => sema.mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data.owner_decl,
5419 else => return null,
5420 };
5421 const owner_decl = sema.mod.declPtr(owner_decl_index);
5422 return owner_decl.srcLoc();
5423}
5424
5412fn zirCall(5425fn zirCall(
5413 sema: *Sema,5426 sema: *Sema,
5414 block: *Block,5427 block: *Block,
...@@ -5464,41 +5477,35 @@ fn zirCall(...@@ -5464,41 +5477,35 @@ fn zirCall(
5464 const func_ty_info = func_ty.fnInfo();5477 const func_ty_info = func_ty.fnInfo();
54655478
5466 const fn_params_len = func_ty_info.param_types.len;5479 const fn_params_len = func_ty_info.param_types.len;
5467 if (func_ty_info.is_var_args) {5480 check_args: {
5468 assert(func_ty_info.cc == .C);5481 if (func_ty_info.is_var_args) {
5469 if (total_args < fn_params_len) {5482 assert(func_ty_info.cc == .C);
5470 // TODO add error note: declared here5483 if (total_args >= fn_params_len) break :check_args;
5471 if (bound_arg_src != null) {5484 } else if (fn_params_len == total_args) {
5472 return sema.fail(5485 break :check_args;
5473 block,
5474 call_src,
5475 "member function expected at least {d} argument(s), found {d}",
5476 .{ fn_params_len - 1, args_len },
5477 );
5478 }
5479 return sema.fail(
5480 block,
5481 func_src,
5482 "expected at least {d} argument(s), found {d}",
5483 .{ fn_params_len, args_len },
5484 );
5485 }5486 }
5486 } else if (fn_params_len != total_args) {5487
5487 // TODO add error note: declared here5488 const decl_src = try sema.funcDeclSrc(block, func_src, func);
5488 if (bound_arg_src != null) {5489 const member_str = if (bound_arg_src != null) "member function " else "";
5489 return sema.fail(5490 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
5491 const msg = msg: {
5492 const msg = try sema.errMsg(
5490 block,5493 block,
5491 call_src,5494 func_src,
5492 "member function expected {d} argument(s), found {d}",5495 "{s}expected {s}{d} argument(s), found {d}",
5493 .{ fn_params_len - 1, args_len },5496 .{
5497 member_str,
5498 variadic_str,
5499 fn_params_len - @boolToInt(bound_arg_src != null),
5500 args_len,
5501 },
5494 );5502 );
5495 }5503 errdefer msg.destroy(sema.gpa);
5496 return sema.fail(5504
5497 block,5505 if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});
5498 call_src,5506 break :msg msg;
5499 "expected {d} argument(s), found {d}",5507 };
5500 .{ fn_params_len, args_len },5508 return sema.failWithOwnedErrorMsg(msg);
5501 );
5502 }5509 }
55035510
5504 const args_body = sema.code.extra[extra.end..];5511 const args_body = sema.code.extra[extra.end..];
...@@ -5625,13 +5632,20 @@ fn analyzeCall(...@@ -5625,13 +5632,20 @@ fn analyzeCall(
5625 const func_ty_info = func_ty.fnInfo();5632 const func_ty_info = func_ty.fnInfo();
5626 const cc = func_ty_info.cc;5633 const cc = func_ty_info.cc;
5627 if (cc == .Naked) {5634 if (cc == .Naked) {
5628 // TODO add error note: declared here5635 const decl_src = try sema.funcDeclSrc(block, func_src, func);
5629 return sema.fail(5636 const msg = msg: {
5630 block,5637 const msg = try sema.errMsg(
5631 func_src,5638 block,
5632 "unable to call function with naked calling convention",5639 func_src,
5633 .{},5640 "unable to call function with naked calling convention",
5634 );5641 .{},
5642 );
5643 errdefer msg.destroy(sema.gpa);
5644
5645 if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});
5646 break :msg msg;
5647 };
5648 return sema.failWithOwnedErrorMsg(msg);
5635 }5649 }
5636 const fn_params_len = func_ty_info.param_types.len;5650 const fn_params_len = func_ty_info.param_types.len;
5637 if (func_ty_info.is_var_args) {5651 if (func_ty_info.is_var_args) {
test/cases/compile_errors/calling_function_with_naked_calling_convention.zig created+11
...@@ -0,0 +1,11 @@
1export fn entry() void {
2 foo();
3}
4fn foo() callconv(.Naked) void { }
5
6// error
7// backend=llvm
8// target=native
9//
10// :2:5: error: unable to call function with naked calling convention
11// :4:1: note: function declared here
test/cases/compile_errors/member_function_arg_mismatch.zig+2-1
...@@ -11,4 +11,5 @@ pub export fn entry() void {...@@ -11,4 +11,5 @@ pub export fn entry() void {
11// backend=stage211// backend=stage2
12// target=native12// target=native
13//13//
14// :7:10: error: member function expected 2 argument(s), found 114// :7:6: error: member function expected 2 argument(s), found 1
15// :3:5: note: function declared here
test/cases/compile_errors/stage1/obj/calling_function_with_naked_calling_convention.zig deleted-11
...@@ -1,11 +0,0 @@
1export fn entry() void {
2 foo();
3}
4fn foo() callconv(.Naked) void { }
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:5: error: unable to call function with naked calling convention
11// tmp.zig:4:1: note: declared here
test/cases/compile_errors/stage1/obj/wrong_number_of_arguments_for_method_fn_call.zig deleted-14
...@@ -1,14 +0,0 @@
1const Foo = struct {
2 fn method(self: *const Foo, a: i32) void {_ = self; _ = a;}
3};
4fn f(foo: *const Foo) void {
5
6 foo.method(1, 2);
7}
8export fn entry() usize { return @sizeOf(@TypeOf(f)); }
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:6:15: error: expected 2 argument(s), found 3
test/cases/compile_errors/wrong_number_of_arguments.zig+2-1
...@@ -7,4 +7,5 @@ fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }...@@ -7,4 +7,5 @@ fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:6: error: expected 3 argument(s), found 110// :2:5: error: expected 3 argument(s), found 1
11// :4:1: note: function declared here
test/cases/compile_errors/wrong_number_of_arguments_for_method_fn_call.zig created+15
...@@ -0,0 +1,15 @@
1const Foo = struct {
2 fn method(self: *const Foo, a: i32) void {_ = self; _ = a;}
3};
4fn f(foo: *const Foo) void {
5
6 foo.method(1, 2);
7}
8export fn entry() usize { return @sizeOf(@TypeOf(&f)); }
9
10// error
11// backend=stage2
12// target=native
13//
14// :6:8: error: member function expected 1 argument(s), found 2
15// :2:5: note: function declared here