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