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 {
|
||||
// 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) ?
|
||||
sbase := new_udp_socket(local.port) ?
|
||||
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) ? {
|
||||
remote := c.sock.remote() or { return err_no_udp_remote }
|
||||
return c.write_to_ptr(remote, b, len)
|
||||
|
|
|
@ -295,10 +295,9 @@ pub:
|
|||
|
||||
// anonymous function
|
||||
pub struct AnonFn {
|
||||
pub:
|
||||
decl FnDecl
|
||||
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
|
||||
|
|
|
@ -59,6 +59,7 @@ pub mut:
|
|||
is_builtin_mod bool // are we in `builtin`?
|
||||
inside_unsafe bool
|
||||
inside_const bool
|
||||
inside_anon_fn bool
|
||||
skip_flags bool // should `#flag` and `#include` be skipped
|
||||
cur_generic_types []table.Type
|
||||
mut:
|
||||
|
@ -3283,10 +3284,13 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
|||
return node.typ
|
||||
}
|
||||
ast.AnonFn {
|
||||
c.inside_anon_fn = true
|
||||
keep_fn := c.cur_fn
|
||||
c.cur_fn = &node.decl
|
||||
c.stmts(node.decl.stmts)
|
||||
c.fn_decl(mut node.decl)
|
||||
c.cur_fn = keep_fn
|
||||
c.inside_anon_fn = false
|
||||
return node.typ
|
||||
}
|
||||
ast.ArrayDecompose {
|
||||
|
@ -5400,7 +5404,11 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
|||
returns := c.returns || has_top_return(node.stmts)
|
||||
if node.language == .v && !node.no_body && node.return_type != table.void_type && !returns
|
||||
&& 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
|
||||
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`
|
||||
1 | mut f := fn(i int) byte {}
|
||||
2 | f = 4
|
||||
|
|
Loading…
Reference in New Issue