parser, checker, cgen: fix error for fn call using anon fn call argument (#14155)
							parent
							
								
									1291b621f6
								
							
						
					
					
						commit
						922cee9162
					
				| 
						 | 
				
			
			@ -578,6 +578,17 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
 | 
			
		|||
		found = true
 | 
			
		||||
		return ast.string_type
 | 
			
		||||
	}
 | 
			
		||||
	if !found && node.left is ast.CallExpr {
 | 
			
		||||
		c.expr(node.left)
 | 
			
		||||
		expr := node.left as ast.CallExpr
 | 
			
		||||
		sym := c.table.sym(expr.return_type)
 | 
			
		||||
		if sym.kind == .function {
 | 
			
		||||
			info := sym.info as ast.FnType
 | 
			
		||||
			node.return_type = info.func.return_type
 | 
			
		||||
			found = true
 | 
			
		||||
			func = info.func
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// already prefixed (mod.fn) or C/builtin/main
 | 
			
		||||
	if !found {
 | 
			
		||||
		if f := c.table.find_fn(fn_name) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -637,11 +637,12 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
 | 
			
		|||
	// see my comment in parser near anon_fn
 | 
			
		||||
	if node.left is ast.AnonFn {
 | 
			
		||||
		g.expr(node.left)
 | 
			
		||||
	}
 | 
			
		||||
	if node.left is ast.IndexExpr && node.name == '' {
 | 
			
		||||
	} else if node.left is ast.IndexExpr && node.name == '' {
 | 
			
		||||
		g.is_fn_index_call = true
 | 
			
		||||
		g.expr(node.left)
 | 
			
		||||
		g.is_fn_index_call = false
 | 
			
		||||
	} else if node.left is ast.CallExpr && node.name == '' {
 | 
			
		||||
		g.expr(node.left)
 | 
			
		||||
	}
 | 
			
		||||
	if node.should_be_skipped {
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2327,6 +2327,18 @@ pub fn (mut p Parser) name_expr() ast.Expr {
 | 
			
		|||
				p.error_with_pos('unexpected $p.prev_tok', p.prev_tok.pos())
 | 
			
		||||
			}
 | 
			
		||||
			node = p.call_expr(language, mod)
 | 
			
		||||
			if p.tok.kind == .lpar && p.prev_tok.line_nr == p.tok.line_nr {
 | 
			
		||||
				p.next()
 | 
			
		||||
				pos := p.tok.pos()
 | 
			
		||||
				args := p.call_args()
 | 
			
		||||
				p.check(.rpar)
 | 
			
		||||
				node = ast.CallExpr{
 | 
			
		||||
					left: node
 | 
			
		||||
					args: args
 | 
			
		||||
					pos: pos
 | 
			
		||||
					scope: p.scope
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else if (p.peek_tok.kind == .lcbr || (p.peek_tok.kind == .lt && lit0_is_capital))
 | 
			
		||||
		&& (!p.inside_match || (p.inside_select && prev_tok_kind == .arrow && lit0_is_capital))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
fn foofun1(op string) fn () string {
 | 
			
		||||
	return fn () string {
 | 
			
		||||
		return 'x passed'
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn foofun2(op string) fn () int {
 | 
			
		||||
	return fn () int {
 | 
			
		||||
		return 22
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test_fn_call_using_anon_fn_call_arg() {
 | 
			
		||||
	println(main.foofun1('1')())
 | 
			
		||||
	assert main.foofun1('1')() == 'x passed'
 | 
			
		||||
 | 
			
		||||
	println(main.foofun2('1')())
 | 
			
		||||
	assert main.foofun2('1')() == 22
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue