cgen: fix implicit the optional return value to have .ok = true, in anon `fn()?{}`
							parent
							
								
									a8f1824e51
								
							
						
					
					
						commit
						dceb63b9df
					
				| 
						 | 
				
			
			@ -183,7 +183,14 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
 | 
			
		|||
		default_expr := g.type_default(it.return_type)
 | 
			
		||||
		// TODO: perf?
 | 
			
		||||
		if default_expr == '{0}' {
 | 
			
		||||
			g.writeln('\treturn ($type_name)$default_expr;')
 | 
			
		||||
			if it.return_type.idx() == 1 && it.return_type.has_flag(.optional) {
 | 
			
		||||
				// The default return for anonymous functions that return `?,
 | 
			
		||||
				// should have .ok = true set, otherwise calling them with 
 | 
			
		||||
				// optfn() or { panic(err) } will cause a panic:
 | 
			
		||||
				g.writeln('\treturn (Option_void){.ok = true};')
 | 
			
		||||
			} else {
 | 
			
		||||
				g.writeln('\treturn ($type_name)$default_expr;')
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			g.writeln('\treturn $default_expr;')
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
type FnCb = fn (a string, b int) ?
 | 
			
		||||
 | 
			
		||||
fn test_calling_an_anon_function_returning_question() {
 | 
			
		||||
	create_and_call_anon_function() or { panic(err) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn create_and_call_anon_function() ? {
 | 
			
		||||
	x := fn (a string, b int) ? {
 | 
			
		||||
		println('test')
 | 
			
		||||
        // NB: the anon function does NOT return explicitly,
 | 
			
		||||
        // so V should generate an implicit "OK" value and
 | 
			
		||||
        // return it. Previously, it created an implicit optional
 | 
			
		||||
        // filled with 0s => .ok was false, and that was treated
 | 
			
		||||
        // as a failure, triggering or blocks.
 | 
			
		||||
	}
 | 
			
		||||
	should_not_call_block(x) ?
 | 
			
		||||
	assert true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn should_not_call_block(func FnCb) ? {
 | 
			
		||||
	func('abc', 123) or {
 | 
			
		||||
		println('this should NOT be called')
 | 
			
		||||
		assert false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue