checker: check the fn decl for anon fns too (#7529)

pull/8433/head
Swastik Baranwal 2021-01-30 02:41:05 +05:30 committed by GitHub
parent b8d93df55e
commit e03ece2a4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 10 deletions

View File

@ -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)

View File

@ -295,9 +295,8 @@ pub:
// anonymous function // anonymous function
pub struct AnonFn { pub struct AnonFn {
pub:
decl FnDecl
pub mut: pub mut:
decl FnDecl
typ table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated typ table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated
} }

View File

@ -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,8 +5404,12 @@ 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'] {
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.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
} }

View 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