checker: check non-optional fn return or_block (#9227)
							parent
							
								
									0d2bb714bc
								
							
						
					
					
						commit
						a187a4abb3
					
				|  | @ -3693,6 +3693,15 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { | ||||||
| 		} | 		} | ||||||
| 		ast.CallExpr { | 		ast.CallExpr { | ||||||
| 			mut ret_type := c.call_expr(mut node) | 			mut ret_type := c.call_expr(mut node) | ||||||
|  | 			if !ret_type.has_flag(.optional) { | ||||||
|  | 				if node.or_block.kind == .block { | ||||||
|  | 					c.error('unexpected `or` block, the function `$node.name` does not return an optional', | ||||||
|  | 						node.or_block.pos) | ||||||
|  | 				} else if node.or_block.kind == .propagate { | ||||||
|  | 					c.error('unexpected `?`, the function `$node.name` does not return an optional', | ||||||
|  | 						node.or_block.pos) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 			if ret_type.has_flag(.optional) && node.or_block.kind != .absent { | 			if ret_type.has_flag(.optional) && node.or_block.kind != .absent { | ||||||
| 				ret_type = ret_type.clear_flag(.optional) | 				ret_type = ret_type.clear_flag(.optional) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | vlib/v/checker/tests/fn_return_or_err.vv:6:17: error: unexpected `or` block, the function `pop` does not return an optional | ||||||
|  |     4 | | ||||||
|  |     5 | pub fn next(mut v []Typ) Typ { | ||||||
|  |     6 |     return v.pop() or { Typ{} } | ||||||
|  |       |                    ~~~~~~~~~~~~ | ||||||
|  |     7 | } | ||||||
|  |     8 | | ||||||
|  | @ -0,0 +1,13 @@ | ||||||
|  | module main | ||||||
|  | 
 | ||||||
|  | pub struct Typ {} | ||||||
|  | 
 | ||||||
|  | pub fn next(mut v []Typ) Typ { | ||||||
|  | 	return v.pop() or { Typ{} } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn main() { | ||||||
|  | 	mut v := [Typ{}] | ||||||
|  | 	last := next(mut v) | ||||||
|  | 	println('$last') | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue