checker: check the fn decl for anon fns too (#7529)
parent
b8d93df55e
commit
e03ece2a4b
|
@ -18,12 +18,6 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dial_udp(laddr string, raddr string) ?&UdpConn {
|
pub fn dial_udp(laddr string, raddr string) ?&UdpConn {
|
||||||
// Dont have to do this when its fixed
|
|
||||||
// this just allows us to store this `none` optional in a struct
|
|
||||||
resolve_wrapper := fn (raddr string) ?Addr {
|
|
||||||
x := resolve_addr(raddr, .inet, .udp) or { return none }
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
local := resolve_addr(laddr, .inet, .udp) ?
|
local := resolve_addr(laddr, .inet, .udp) ?
|
||||||
sbase := new_udp_socket(local.port) ?
|
sbase := new_udp_socket(local.port) ?
|
||||||
sock := UdpSocket{
|
sock := UdpSocket{
|
||||||
|
@ -38,6 +32,13 @@ pub fn dial_udp(laddr string, raddr string) ?&UdpConn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_wrapper(raddr string) ?Addr {
|
||||||
|
// Dont have to do this when its fixed
|
||||||
|
// this just allows us to store this `none` optional in a struct
|
||||||
|
x := resolve_addr(raddr, .inet, .udp) or { return none }
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut c UdpConn) write_ptr(b byteptr, len int) ? {
|
pub fn (mut c UdpConn) write_ptr(b byteptr, len int) ? {
|
||||||
remote := c.sock.remote() or { return err_no_udp_remote }
|
remote := c.sock.remote() or { return err_no_udp_remote }
|
||||||
return c.write_to_ptr(remote, b, len)
|
return c.write_to_ptr(remote, b, len)
|
||||||
|
|
|
@ -295,10 +295,9 @@ pub:
|
||||||
|
|
||||||
// anonymous function
|
// anonymous function
|
||||||
pub struct AnonFn {
|
pub struct AnonFn {
|
||||||
pub:
|
|
||||||
decl FnDecl
|
|
||||||
pub mut:
|
pub mut:
|
||||||
typ table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated
|
decl FnDecl
|
||||||
|
typ table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated
|
||||||
}
|
}
|
||||||
|
|
||||||
// function or method declaration
|
// function or method declaration
|
||||||
|
|
|
@ -59,6 +59,7 @@ pub mut:
|
||||||
is_builtin_mod bool // are we in `builtin`?
|
is_builtin_mod bool // are we in `builtin`?
|
||||||
inside_unsafe bool
|
inside_unsafe bool
|
||||||
inside_const bool
|
inside_const bool
|
||||||
|
inside_anon_fn bool
|
||||||
skip_flags bool // should `#flag` and `#include` be skipped
|
skip_flags bool // should `#flag` and `#include` be skipped
|
||||||
cur_generic_types []table.Type
|
cur_generic_types []table.Type
|
||||||
mut:
|
mut:
|
||||||
|
@ -3283,10 +3284,13 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||||
return node.typ
|
return node.typ
|
||||||
}
|
}
|
||||||
ast.AnonFn {
|
ast.AnonFn {
|
||||||
|
c.inside_anon_fn = true
|
||||||
keep_fn := c.cur_fn
|
keep_fn := c.cur_fn
|
||||||
c.cur_fn = &node.decl
|
c.cur_fn = &node.decl
|
||||||
c.stmts(node.decl.stmts)
|
c.stmts(node.decl.stmts)
|
||||||
|
c.fn_decl(mut node.decl)
|
||||||
c.cur_fn = keep_fn
|
c.cur_fn = keep_fn
|
||||||
|
c.inside_anon_fn = false
|
||||||
return node.typ
|
return node.typ
|
||||||
}
|
}
|
||||||
ast.ArrayDecompose {
|
ast.ArrayDecompose {
|
||||||
|
@ -5400,7 +5404,11 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
returns := c.returns || has_top_return(node.stmts)
|
returns := c.returns || has_top_return(node.stmts)
|
||||||
if node.language == .v && !node.no_body && node.return_type != table.void_type && !returns
|
if node.language == .v && !node.no_body && node.return_type != table.void_type && !returns
|
||||||
&& node.name !in ['panic', 'exit'] {
|
&& node.name !in ['panic', 'exit'] {
|
||||||
c.error('missing return at end of function `$node.name`', node.pos)
|
if c.inside_anon_fn {
|
||||||
|
c.error('missing return at the end of an anonymous function', node.pos)
|
||||||
|
} else {
|
||||||
|
c.error('missing return at end of function `$node.name`', node.pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.returns = false
|
c.returns = false
|
||||||
node.source_file = c.file
|
node.source_file = c.file
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
vlib/v/checker/tests/fn_var.vv:1:10: error: missing return at the end of an anonymous function
|
||||||
|
1 | mut f := fn(i int) byte {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~
|
||||||
|
2 | f = 4
|
||||||
|
3 | mut p := &f
|
||||||
vlib/v/checker/tests/fn_var.vv:2:5: error: cannot assign to `f`: expected `fn (int) byte`, not `int literal`
|
vlib/v/checker/tests/fn_var.vv:2:5: error: cannot assign to `f`: expected `fn (int) byte`, not `int literal`
|
||||||
1 | mut f := fn(i int) byte {}
|
1 | mut f := fn(i int) byte {}
|
||||||
2 | f = 4
|
2 | f = 4
|
||||||
|
|
Loading…
Reference in New Issue