checker, cgen: fix fn type call of match expr (#12579)
parent
a59eabc4ab
commit
cf274f262c
|
@ -2674,22 +2674,33 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||||
}
|
}
|
||||||
// check for arg (var) of fn type
|
// check for arg (var) of fn type
|
||||||
if !found {
|
if !found {
|
||||||
if v := node.scope.find_var(fn_name) {
|
mut typ := 0
|
||||||
if v.typ != 0 {
|
if obj := node.scope.find(node.name) {
|
||||||
generic_vts := c.table.get_type_symbol(v.typ)
|
match obj {
|
||||||
if generic_vts.kind == .function {
|
ast.GlobalField {
|
||||||
info := generic_vts.info as ast.FnType
|
typ = obj.typ
|
||||||
|
}
|
||||||
|
ast.Var {
|
||||||
|
typ = if obj.smartcasts.len != 0 { obj.smartcasts.last() } else { obj.typ }
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if typ != 0 {
|
||||||
|
generic_vts := c.table.get_final_type_symbol(typ)
|
||||||
|
if generic_vts.kind == .function {
|
||||||
|
info := generic_vts.info as ast.FnType
|
||||||
|
func = info.func
|
||||||
|
found = true
|
||||||
|
found_in_args = true
|
||||||
|
} else {
|
||||||
|
vts := c.table.get_type_symbol(c.unwrap_generic(typ))
|
||||||
|
if vts.kind == .function {
|
||||||
|
info := vts.info as ast.FnType
|
||||||
func = info.func
|
func = info.func
|
||||||
found = true
|
found = true
|
||||||
found_in_args = true
|
found_in_args = true
|
||||||
} else {
|
|
||||||
vts := c.table.get_type_symbol(c.unwrap_generic(v.typ))
|
|
||||||
if vts.kind == .function {
|
|
||||||
info := vts.info as ast.FnType
|
|
||||||
func = info.func
|
|
||||||
found = true
|
|
||||||
found_in_args = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1180,7 +1180,41 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
// g.writeln(';')
|
// g.writeln(';')
|
||||||
// g.write(cur_line + ' /* <== af cur line*/')
|
// g.write(cur_line + ' /* <== af cur line*/')
|
||||||
// }
|
// }
|
||||||
g.write(g.get_ternary_name(name))
|
mut is_fn_var := false
|
||||||
|
if obj := node.scope.find(node.name) {
|
||||||
|
match obj {
|
||||||
|
ast.Var {
|
||||||
|
if obj.smartcasts.len > 0 {
|
||||||
|
for _ in obj.smartcasts {
|
||||||
|
g.write('(*')
|
||||||
|
}
|
||||||
|
for i, typ in obj.smartcasts {
|
||||||
|
cast_sym := g.table.get_type_symbol(g.unwrap_generic(typ))
|
||||||
|
mut is_ptr := false
|
||||||
|
if i == 0 {
|
||||||
|
g.write(node.name)
|
||||||
|
if obj.orig_type.is_ptr() {
|
||||||
|
is_ptr = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dot := if is_ptr { '->' } else { '.' }
|
||||||
|
if mut cast_sym.info is ast.Aggregate {
|
||||||
|
sym := g.table.get_type_symbol(cast_sym.info.types[g.aggregate_type_idx])
|
||||||
|
g.write('${dot}_$sym.cname')
|
||||||
|
} else {
|
||||||
|
g.write('${dot}_$cast_sym.cname')
|
||||||
|
}
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
|
is_fn_var = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !is_fn_var {
|
||||||
|
g.write(g.get_ternary_name(name))
|
||||||
|
}
|
||||||
if is_interface_call {
|
if is_interface_call {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
type FnZ = fn () string
|
||||||
|
|
||||||
|
type FnO = fn (int) string
|
||||||
|
|
||||||
|
type FnQ = FnO | FnZ
|
||||||
|
|
||||||
|
fn fnz_z() string {
|
||||||
|
return 'Got zero'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fnz_o(one int) string {
|
||||||
|
return 'Got one $one'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_fn_type_call_of_match_expr() {
|
||||||
|
mut arr := [FnQ(FnZ(fnz_z)), FnQ(FnO(fnz_o))]
|
||||||
|
for item in arr {
|
||||||
|
match item {
|
||||||
|
FnZ {
|
||||||
|
println(item())
|
||||||
|
assert item() == 'Got zero'
|
||||||
|
}
|
||||||
|
FnO {
|
||||||
|
println(item(42))
|
||||||
|
assert item(42) == 'Got one 42'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue