diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 9147393314201c..a3ab73f1882aa6 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -7941,6 +7941,7 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}* } } mut methods := st_sym.methods.clone() + mut aliased_method_names := []string{} method_names := methods.map(it.name) match st_sym.info { ast.Struct, ast.Interface, ast.SumType { @@ -7955,12 +7956,38 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}* } } } + ast.Alias { + parent_sym := g.table.sym(st_sym.info.parent_type) + match parent_sym.info { + ast.Struct, ast.Interface, ast.SumType { + mut t_method_names := methods.map(it.name) + for method in parent_sym.methods { + if method.name in methodidx { + parent_method := parent_sym.find_method_with_generic_parent(method.name) or { + continue + } + if parent_method.name !in methodidx { + continue + } + if parent_method.name !in t_method_names { + methods << parent_method + aliased_method_names << parent_method.name + t_method_names << parent_method.name + } + } + } + } + else {} + } + } else {} } t_methods := g.table.get_embed_methods(st_sym) + mut t_method_names := methods.map(it.name) for t_method in t_methods { - if t_method.name !in methods.map(it.name) { + if t_method.name !in t_method_names { methods << t_method + t_method_names << t_method.name } } @@ -7989,7 +8016,11 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}* styp := g.cc_type(method.params[0].typ, true) mut method_call := '${styp}_${name}' if !method.params[0].typ.is_ptr() { - method_call = '${cctype}_${name}' + if method.name !in aliased_method_names { + method_call = '${cctype}_${name}' + } else { + method_call = '${styp}_${name}' + } // inline void Cat_speak_Interface_Animal_method_wrapper(Cat c) { return Cat_speak(*c); } iwpostfix := '_Interface_${interface_name}_method_wrapper' methods_wrapper.write_string('static inline ${g.ret_styp(method.return_type)} ${cctype}_${name}${iwpostfix}(') diff --git a/vlib/v/tests/fns/aliased_interface_methods_test.v b/vlib/v/tests/fns/aliased_interface_methods_test.v new file mode 100644 index 00000000000000..a953c4f74a6665 --- /dev/null +++ b/vlib/v/tests/fns/aliased_interface_methods_test.v @@ -0,0 +1,32 @@ +import x.encoding.asn1 + +struct AExample { + a asn1.OctetString +} + +fn (a AExample) tag() asn1.Tag { + return asn1.default_sequence_tag +} + +fn (a AExample) payload() ![]u8 { + mut out := []u8{} + out << asn1.encode(a.a)! + return out +} + +// BExample is aliased type, without redefined methods of AExample +type BExample = AExample + +fn test_main() { + exa := AExample{ + a: asn1.OctetString.new('hi')! + } + exb := BExample(exa) + assert '${exa.tag()}' == 'universal-true-16' + assert exa.payload()!.len == 4 + assert asn1.encode(exa)!.len == 6 + + assert '${exb.tag()}' == 'universal-true-16' + assert exb.payload()!.len == 4 + assert asn1.encode(exb)!.len == 6 +}