1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: fix array map with it selector expr, used as an it method closure (#17968)

This commit is contained in:
Felipe Pena 2023-04-16 08:41:07 -03:00 committed by GitHub
parent 8e959ae5b5
commit a49cecc2b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 4 deletions

View File

@ -1471,6 +1471,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
node.has_hidden_receiver = true
method.name = ''
fn_type := ast.new_type(c.table.find_or_register_fn_type(method, false, true))
node.typ = fn_type
return fn_type
}
if sym.kind !in [.struct_, .aggregate, .interface_, .sum_type] {

View File

@ -2444,8 +2444,16 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
c.check_map_and_filter(true, elem_typ, node)
arg_sym := c.table.sym(arg_type)
ret_type := match arg_sym.info {
ast.FnType { arg_sym.info.func.return_type }
else { arg_type }
ast.FnType {
if node.args[0].expr is ast.SelectorExpr {
arg_type
} else {
arg_sym.info.func.return_type
}
}
else {
arg_type
}
}
node.return_type = c.table.find_or_register_array(c.unwrap_generic(ret_type))
if node.return_type.has_flag(.shared_f) {

View File

@ -421,12 +421,24 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
ret_sym := g.table.sym(node.return_type)
inp_sym := g.table.sym(node.receiver_type)
ret_info := ret_sym.info as ast.Array
ret_elem_type := g.typ(ret_info.elem_type)
mut ret_elem_type := g.typ(ret_info.elem_type)
inp_info := inp_sym.info as ast.Array
inp_elem_type := g.typ(inp_info.elem_type)
if inp_sym.kind != .array {
verror('map() requires an array')
}
mut closure_var_decl := ''
if node.args[0].expr is ast.SelectorExpr {
if node.args[0].expr.typ != ast.void_type {
var_sym := g.table.sym(node.args[0].expr.typ)
if var_sym.info is ast.FnType {
ret_elem_type = 'voidptr'
closure_var_decl = g.fn_var_signature(var_sym.info.func.return_type, var_sym.info.func.params.map(it.typ),
'ti')
}
}
}
g.empty_line = true
noscan := g.check_noscan(ret_info.elem_type)
has_infix_left_var_name := g.write_prepared_tmp_value(tmp, node, ret_typ, '{0}')
@ -473,7 +485,11 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
g.expr(node.args[0].expr)
}
else {
g.write('${ret_elem_type} ti = ')
if closure_var_decl != '' {
g.write('${closure_var_decl} = ')
} else {
g.write('${ret_elem_type} ti = ')
}
g.expr(node.args[0].expr)
}
}

View File

@ -0,0 +1,9 @@
fn test_main() {
k := [10, 20, 30]
println(k.map(it.hex()))
dump(k.map(it.hex))
a := k.map(it.hex)
assert dump(a[0]()) == 'a'
assert dump(a[1]()) == '14'
assert dump(a[2]()) == '1e'
}