From e03ece2a4b0eb3c1400c2ad813f4c7d5b22e4b66 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Sat, 30 Jan 2021 02:41:05 +0530 Subject: [PATCH] checker: check the fn decl for anon fns too (#7529) --- vlib/net/udp.v | 13 +++++++------ vlib/v/ast/ast.v | 5 ++--- vlib/v/checker/checker.v | 10 +++++++++- vlib/v/checker/tests/fn_var.out | 5 +++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/vlib/net/udp.v b/vlib/net/udp.v index e69cf39ab1..7d769c5e77 100644 --- a/vlib/net/udp.v +++ b/vlib/net/udp.v @@ -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) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 3cf5ada5d8..8f6a82da08 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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 diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b4cdb91126..43fa4a0886 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 diff --git a/vlib/v/checker/tests/fn_var.out b/vlib/v/checker/tests/fn_var.out index ace817b996..d1db2a0f07 100644 --- a/vlib/v/checker/tests/fn_var.out +++ b/vlib/v/checker/tests/fn_var.out @@ -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