mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: make a calling no-body function a checker error (#8265)
This commit is contained in:
parent
2007dbc7b5
commit
3959ba5751
@ -1432,6 +1432,10 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||
c.fail_if_immutable(call_expr.left)
|
||||
// call_expr.is_mut = true
|
||||
}
|
||||
if (!left_type_sym.is_builtin() && method.mod != 'builtin') && method.language == .v
|
||||
&& method.no_body {
|
||||
c.error('cannot call a method that does not have a body', call_expr.pos)
|
||||
}
|
||||
if method.return_type == table.void_type && method.ctdefine.len > 0
|
||||
&& method.ctdefine !in c.pref.compile_defines {
|
||||
call_expr.should_be_skipped = true
|
||||
@ -1726,6 +1730,9 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
||||
// builtin C.m*, C.s* only - temp
|
||||
c.warn('function `$f.name` must be called from an `unsafe` block', call_expr.pos)
|
||||
}
|
||||
if f.mod != 'builtin' && f.language == .v && f.no_body {
|
||||
c.error('cannot call a function that does not have a body', call_expr.pos)
|
||||
}
|
||||
for generic_type in call_expr.generic_types {
|
||||
sym := c.table.get_type_symbol(generic_type)
|
||||
if sym.kind == .placeholder {
|
||||
|
13
vlib/v/checker/tests/fn_call_no_body.out
Normal file
13
vlib/v/checker/tests/fn_call_no_body.out
Normal file
@ -0,0 +1,13 @@
|
||||
vlib/v/checker/tests/fn_call_no_body.vv:7:9: error: cannot call a method that does not have a body
|
||||
5 |
|
||||
6 | fn main() {
|
||||
7 | Foo(0).f()
|
||||
| ~~~
|
||||
8 | f()
|
||||
9 | }
|
||||
vlib/v/checker/tests/fn_call_no_body.vv:8:2: error: cannot call a function that does not have a body
|
||||
6 | fn main() {
|
||||
7 | Foo(0).f()
|
||||
8 | f()
|
||||
| ~~~
|
||||
9 | }
|
9
vlib/v/checker/tests/fn_call_no_body.vv
Normal file
9
vlib/v/checker/tests/fn_call_no_body.vv
Normal file
@ -0,0 +1,9 @@
|
||||
type Foo = int
|
||||
fn (_ Foo) f()
|
||||
|
||||
fn f()
|
||||
|
||||
fn main() {
|
||||
Foo(0).f()
|
||||
f()
|
||||
}
|
@ -315,6 +315,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||
return_type = p.parse_type()
|
||||
}
|
||||
mut type_sym_method_idx := 0
|
||||
no_body := p.tok.kind != .lcbr
|
||||
// Register
|
||||
if is_method {
|
||||
mut type_sym := p.table.get_type_symbol(rec_type)
|
||||
@ -345,6 +346,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||
is_pub: is_pub
|
||||
is_deprecated: is_deprecated
|
||||
is_unsafe: is_unsafe
|
||||
no_body: no_body
|
||||
mod: p.mod
|
||||
attrs: p.attrs
|
||||
})
|
||||
@ -369,6 +371,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||
is_pub: is_pub
|
||||
is_deprecated: is_deprecated
|
||||
is_unsafe: is_unsafe
|
||||
no_body: no_body
|
||||
mod: p.mod
|
||||
attrs: p.attrs
|
||||
language: language
|
||||
@ -378,7 +381,6 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||
// Body
|
||||
p.cur_fn_name = name
|
||||
mut stmts := []ast.Stmt{}
|
||||
no_body := p.tok.kind != .lcbr
|
||||
body_start_pos := p.peek_tok.position()
|
||||
if p.tok.kind == .lcbr {
|
||||
p.inside_fn = true
|
||||
|
@ -32,6 +32,7 @@ pub:
|
||||
is_deprecated bool
|
||||
is_unsafe bool
|
||||
is_placeholder bool
|
||||
no_body bool
|
||||
mod string
|
||||
ctdefine string // compile time define. myflag, when [if myflag] tag
|
||||
attrs []Attr
|
||||
|
@ -573,6 +573,11 @@ pub fn (t &TypeSymbol) is_primitive() bool {
|
||||
return t.is_number() || t.is_pointer() || t.is_string()
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) is_builtin() bool {
|
||||
return t.mod == 'builtin'
|
||||
}
|
||||
|
||||
// for debugging/errors only, perf is not an issue
|
||||
pub fn (k Kind) str() string {
|
||||
k_str := match k {
|
||||
|
Loading…
Reference in New Issue
Block a user