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)
|
c.fail_if_immutable(call_expr.left)
|
||||||
// call_expr.is_mut = true
|
// 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
|
if method.return_type == table.void_type && method.ctdefine.len > 0
|
||||||
&& method.ctdefine !in c.pref.compile_defines {
|
&& method.ctdefine !in c.pref.compile_defines {
|
||||||
call_expr.should_be_skipped = true
|
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
|
// builtin C.m*, C.s* only - temp
|
||||||
c.warn('function `$f.name` must be called from an `unsafe` block', call_expr.pos)
|
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 {
|
for generic_type in call_expr.generic_types {
|
||||||
sym := c.table.get_type_symbol(generic_type)
|
sym := c.table.get_type_symbol(generic_type)
|
||||||
if sym.kind == .placeholder {
|
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()
|
return_type = p.parse_type()
|
||||||
}
|
}
|
||||||
mut type_sym_method_idx := 0
|
mut type_sym_method_idx := 0
|
||||||
|
no_body := p.tok.kind != .lcbr
|
||||||
// Register
|
// Register
|
||||||
if is_method {
|
if is_method {
|
||||||
mut type_sym := p.table.get_type_symbol(rec_type)
|
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_pub: is_pub
|
||||||
is_deprecated: is_deprecated
|
is_deprecated: is_deprecated
|
||||||
is_unsafe: is_unsafe
|
is_unsafe: is_unsafe
|
||||||
|
no_body: no_body
|
||||||
mod: p.mod
|
mod: p.mod
|
||||||
attrs: p.attrs
|
attrs: p.attrs
|
||||||
})
|
})
|
||||||
@ -369,6 +371,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||||||
is_pub: is_pub
|
is_pub: is_pub
|
||||||
is_deprecated: is_deprecated
|
is_deprecated: is_deprecated
|
||||||
is_unsafe: is_unsafe
|
is_unsafe: is_unsafe
|
||||||
|
no_body: no_body
|
||||||
mod: p.mod
|
mod: p.mod
|
||||||
attrs: p.attrs
|
attrs: p.attrs
|
||||||
language: language
|
language: language
|
||||||
@ -378,7 +381,6 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||||||
// Body
|
// Body
|
||||||
p.cur_fn_name = name
|
p.cur_fn_name = name
|
||||||
mut stmts := []ast.Stmt{}
|
mut stmts := []ast.Stmt{}
|
||||||
no_body := p.tok.kind != .lcbr
|
|
||||||
body_start_pos := p.peek_tok.position()
|
body_start_pos := p.peek_tok.position()
|
||||||
if p.tok.kind == .lcbr {
|
if p.tok.kind == .lcbr {
|
||||||
p.inside_fn = true
|
p.inside_fn = true
|
||||||
|
@ -32,6 +32,7 @@ pub:
|
|||||||
is_deprecated bool
|
is_deprecated bool
|
||||||
is_unsafe bool
|
is_unsafe bool
|
||||||
is_placeholder bool
|
is_placeholder bool
|
||||||
|
no_body bool
|
||||||
mod string
|
mod string
|
||||||
ctdefine string // compile time define. myflag, when [if myflag] tag
|
ctdefine string // compile time define. myflag, when [if myflag] tag
|
||||||
attrs []Attr
|
attrs []Attr
|
||||||
|
@ -573,6 +573,11 @@ pub fn (t &TypeSymbol) is_primitive() bool {
|
|||||||
return t.is_number() || t.is_pointer() || t.is_string()
|
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
|
// for debugging/errors only, perf is not an issue
|
||||||
pub fn (k Kind) str() string {
|
pub fn (k Kind) str() string {
|
||||||
k_str := match k {
|
k_str := match k {
|
||||||
|
Loading…
Reference in New Issue
Block a user