diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 7bfc255c711635..874670b9c2caf1 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -729,7 +729,13 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { cloned = true } } else if right_sym.kind == .interface { - g.get_free_method(var_type) + if g.table.type_to_str(var_type) != 'IError' { + if var_type.has_flag(.shared_f) { + g.get_free_method(var_type.clear_flag(.shared_f).set_nr_muls(0)) + } else { + g.get_free_method(var_type) + } + } } } if !cloned { diff --git a/vlib/v/gen/c/auto_free_methods.v b/vlib/v/gen/c/auto_free_methods.v index d1196dcf97e491..223d473112d3a6 100644 --- a/vlib/v/gen/c/auto_free_methods.v +++ b/vlib/v/gen/c/auto_free_methods.v @@ -6,7 +6,9 @@ import v.ast import strings fn (mut g Gen) get_free_method(typ ast.Type) string { - g.autofree_methods[typ] = true + if typ in g.autofree_methods { + return g.autofree_methods[typ] + } mut sym := g.table.sym(g.unwrap_generic(typ)) if mut sym.info is ast.Alias { if sym.info.is_import { @@ -16,8 +18,10 @@ fn (mut g Gen) get_free_method(typ ast.Type) string { styp := g.typ(typ).replace('*', '') fn_name := styp_to_free_fn_name(styp) if sym.has_method_with_generic_parent('free') { + g.autofree_methods[typ] = fn_name return fn_name } + g.autofree_methods[typ] = fn_name return fn_name } @@ -78,12 +82,13 @@ fn (mut g Gen) gen_free_for_interface(sym ast.TypeSymbol, info ast.Interface, st } fn_builder.writeln('${g.static_modifier} void ${fn_name}(${styp}* it) {') for t in info.types { - sub_sym := g.table.sym(ast.mktyp(t)) + typ_ := g.unwrap_generic(t) + sub_sym := g.table.sym(typ_) if sub_sym.kind !in [.string, .array, .map, .struct] { continue } - fn_name_typ := g.get_free_method(t) - fn_builder.writeln('\tif (it->_typ == _${sym.cname}_${sub_sym.cname}_index) { ${fn_name_typ}(it); return; }') + fn_name_typ := g.get_free_method(typ_) + fn_builder.writeln('\tif (it->_typ == _${sym.cname}_${sub_sym.cname}_index) { ${fn_name_typ}(it->_${sub_sym.cname}); return; }') } fn_builder.writeln('}') } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 6f24e11518de4b..a956b057b704f1 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -245,7 +245,7 @@ mut: cur_fn &ast.FnDecl = unsafe { nil } // same here cur_lock ast.LockExpr cur_struct_init_typ ast.Type - autofree_methods map[int]bool + autofree_methods map[int]string generated_free_methods map[int]bool autofree_scope_stmts []string use_segfault_handler bool = true diff --git a/vlib/v/gen/c/testdata/interface_auto_free.c.must_have b/vlib/v/gen/c/testdata/interface_auto_free.c.must_have index 01ded274dcf830..41d8ea445035d7 100644 --- a/vlib/v/gen/c/testdata/interface_auto_free.c.must_have +++ b/vlib/v/gen/c/testdata/interface_auto_free.c.must_have @@ -1,7 +1,7 @@ - void main__IFoo_free(main__IFoo* it) { - if (it->_typ == _main__IFoo_main__Foo_index) { main__Foo_free(it); return; } - if (it->_typ == _main__IFoo_array_index) { array_free(it); return; } - if (it->_typ == _main__IFoo_map_index) { map_free(it); return; } - if (it->_typ == _main__IFoo_VAssertMetaInfo_index) { VAssertMetaInfo_free(it); return; } - if (it->_typ == _main__IFoo_MessageError_index) { MessageError_free(it); return; } +void main__IFoo_free(main__IFoo* it) { + if (it->_typ == _main__IFoo_main__Foo_index) { main__Foo_free(it->_main__Foo); return; } + if (it->_typ == _main__IFoo_array_index) { array_free(it->_array); return; } + if (it->_typ == _main__IFoo_map_index) { map_free(it->_map); return; } + if (it->_typ == _main__IFoo_VAssertMetaInfo_index) { VAssertMetaInfo_free(it->_VAssertMetaInfo); return; } + if (it->_typ == _main__IFoo_MessageError_index) { MessageError_free(it->_MessageError); return; } } \ No newline at end of file