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,9 +295,8 @@ pub: | |||
| 
 | ||||
| // anonymous function
 | ||||
| pub struct AnonFn { | ||||
| pub: | ||||
| 	decl FnDecl | ||||
| pub mut: | ||||
| 	decl FnDecl | ||||
| 	typ  table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated
 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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,8 +5404,12 @@ 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'] { | ||||
| 		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