diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 5470da4cb1..b9d2cf6bb4 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -3364,6 +3364,7 @@ fn (g Gen) type_to_fmt(typ table.Type) string { } // Generates interface table and interface indexes +// TODO remove all `replace()` fn (v &Gen) interface_table() string { mut sb := strings.new_builder(100) for _, t in v.table.types { @@ -3378,10 +3379,10 @@ fn (v &Gen) interface_table() string { sb.writeln('// NR gen_types= $info.gen_types.len') for i, gen_type in info.gen_types { // ptr_ctype can be for example Cat OR Cat_ptr: - ptr_ctype := gen_type.replace('*', '_ptr') + ptr_ctype := gen_type.replace('*', '_ptr').replace('.', '__') // cctype is the Cleaned Concrete Type name, *without ptr*, // i.e. cctype is always just Cat, not Cat_ptr: - cctype := gen_type.replace('*', '') + cctype := gen_type.replace('*', '').replace('.', '__') // Speaker_Cat_index = 0 interface_index_name := '_${interface_name}_${ptr_ctype}_index' generated_casting_functions += ' @@ -3457,9 +3458,11 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { g.write('($elem_type_str[$len]){\n\t\t') for i, expr in it.exprs { if it.is_interface { - sym := g.table.get_type_symbol(it.interface_types[i]) - isym := g.table.get_type_symbol(it.interface_type) - g.write('I_${sym.name}_to_${isym.name}(') + // sym := g.table.get_type_symbol(it.interface_types[i]) + // isym := g.table.get_type_symbol(it.interface_type) + interface_styp := g.typ(it.interface_type) + styp := g.typ(it.interface_types[i]) + g.write('I_${styp}_to_${interface_styp}(') } g.expr(expr) if it.is_interface { diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 913508bc44..7f84acba4d 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -277,7 +277,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) { verror('method receiver type is 0, this means there are some uchecked exprs') } typ_sym := g.table.get_type_symbol(node.receiver_type) - mut receiver_name := typ_sym.name + // mut receiver_type_name := g.typ(node.receiver_type) + mut receiver_type_name := typ_sym.name.replace('.', '__') // TODO g.typ() ? if typ_sym.kind == .interface_ { // Find the index of the method mut idx := -1 @@ -292,7 +293,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { sret_type := g.typ(node.return_type) g.writeln('// interface method call') // `((void (*)())(Speaker_name_table[s._interface_idx][1]))(s._object);` - g.write('(($sret_type (*)())(${receiver_name}_name_table[') + g.write('(($sret_type (*)())(${receiver_type_name}_name_table[') g.expr(node.left) g.write('._interface_idx][$idx]))(') g.expr(node.left) @@ -327,13 +328,13 @@ fn (mut g Gen) method_call(node ast.CallExpr) { // && rec_sym.name == 'array' { // && rec_sym.name == 'array' && receiver_name.starts_with('array') { // `array_byte_clone` => `array_clone` - receiver_name = 'array' + receiver_type_name = 'array' if node.name in ['last', 'first'] { return_type_str := g.typ(node.return_type) g.write('*($return_type_str*)') } } - name := '${receiver_name}_$node.name'.replace('.', '__') + name := '${receiver_type_name}_$node.name'.replace('.', '__') // if node.receiver_type != 0 { // g.write('/*${g.typ(node.receiver_type)}*/') // g.write('/*expr_type=${g.typ(node.left_type)} rec type=${g.typ(node.receiver_type)}*/') @@ -509,9 +510,10 @@ fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) { // Cast a type to interface // `foo(dog)` => `foo(I_Dog_to_Animal(dog))` exp_sym := g.table.get_type_symbol(expected_types[arg_no]) - sym := g.table.get_type_symbol(arg.typ) + exp_styp := g.typ(expected_types[arg_no]) // g.table.get_type_symbol(expected_types[arg_no]) + styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ) if exp_sym.kind == .interface_ { - g.write('I_${sym.name}_to_${exp_sym.name}(') + g.write('/*i*/I_${styp}_to_${exp_styp}(') is_interface = true } } diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 1d0f9d32e9..c3bf2d4222 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -490,7 +490,8 @@ pub fn (t &Table) check(got, expected Type) bool { mut info := exp_type_sym.info as Interface // println('gen_types before') // println(info.gen_types) - if got_type_sym.name !in info.gen_types { + if got_type_sym.name !in info.gen_types && got_type_sym.kind != .interface_ { + // TODO `got` should never be an interface? info.gen_types << got_type_sym.name } // println('adding gen_type $got_type_sym.name')