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:
parent
8e959ae5b5
commit
a49cecc2b4
@ -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] {
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
9
vlib/v/tests/map_with_selector_test.v
Normal file
9
vlib/v/tests/map_with_selector_test.v
Normal 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'
|
||||
}
|
Loading…
Reference in New Issue
Block a user