cgen: fix error for map get anon fn value (#13782)

pull/13785/head
yuyi 2022-03-21 06:20:55 +08:00 committed by GitHub
parent aaf87e04a2
commit c4b424717c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 13 deletions

View File

@ -955,7 +955,13 @@ fn (mut g Gen) optional_type_name(t ast.Type) (string, string) {
fn (g Gen) optional_type_text(styp string, base string) string {
// replace void with something else
size := if base == 'void' { 'byte' } else { base }
size := if base == 'void' {
'byte'
} else if base.starts_with('anon_fn') {
'void*'
} else {
base
}
ret := 'struct $styp {
byte state;
IError err;
@ -4826,12 +4832,15 @@ fn (mut g Gen) insert_at(pos int, s string) {
// Returns the type of the last stmt
fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Type) {
cvar_name := c_name(var_name)
mr_styp := g.base_type(return_type)
mut mr_styp := g.base_type(return_type)
is_none_ok := return_type == ast.ovoid_type
g.writeln(';')
if is_none_ok {
g.writeln('if (${cvar_name}.state != 0 && ${cvar_name}.err._typ != _IError_None___index) {')
} else {
if return_type != 0 && g.table.sym(return_type).kind == .function {
mr_styp = 'voidptr'
}
g.writeln('if (${cvar_name}.state != 0) { /*or block*/ ')
}
if or_block.kind == .block {

View File

@ -365,8 +365,11 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
info := sym.info as ast.Map
key_type_str := g.typ(info.key_type)
elem_type := info.value_type
elem_type_str := g.typ(elem_type)
mut elem_type_str := g.typ(elem_type)
elem_typ := g.table.sym(elem_type)
if elem_typ.kind == .function {
elem_type_str = 'voidptr'
}
get_and_set_types := elem_typ.kind in [.struct_, .map]
if g.is_assign_lhs && !g.is_arraymap_set && !get_and_set_types {
if g.assign_op == .assign || info.value_type == ast.string_type {
@ -401,12 +404,8 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
g.is_arraymap_set = old_is_arraymap_set
g.is_assign_lhs = old_is_assign_lhs
g.write('}')
if elem_typ.kind == .function {
g.write(', &(voidptr[]) { ')
} else {
g.arraymap_set_pos = g.out.len
g.write(', &($elem_type_str[]) { ')
}
g.arraymap_set_pos = g.out.len
g.write(', &($elem_type_str[]) { ')
if g.assign_op != .assign && info.value_type != ast.string_type {
zero := g.type_default(info.value_type)
g.write('$zero })))')
@ -450,8 +449,6 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
g.write_fn_ptr_decl(&elem_typ.info, '')
g.write(')(*(voidptr*)map_get(')
}
} else if elem_typ.kind == .function {
g.write('(*(voidptr*)map_get(')
} else {
g.write('(*($elem_type_str*)map_get(')
}
@ -477,8 +474,6 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
g.write('))')
} else if g.is_fn_index_call {
g.write(', &(voidptr[]){ $zero })))')
} else if elem_typ.kind == .function {
g.write(', &(voidptr[]){ $zero }))')
} else {
g.write(', &($elem_type_str[]){ $zero }))')
}

View File

@ -0,0 +1,25 @@
const numbers = {
'one': fn () int {
return 1
}
}
fn test_map_get_anon_fn_value() {
num1 := numbers['one'] or {
fn () int {
return 2
}
}
ret1 := num1()
println(ret1)
assert ret1 == 1
num2 := numbers['two'] or {
fn () int {
return 2
}
}
ret2 := num2()
println(ret2)
assert ret2 == 2
}