Skip to content

Commit

Permalink
cgen: fix codegen for alias type interface methods (fix #22901) (#22902)
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Nov 18, 2024
1 parent 0942bb2 commit faac1fd
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
35 changes: 33 additions & 2 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
}

Expand Down Expand Up @@ -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}(')
Expand Down
32 changes: 32 additions & 0 deletions vlib/v/tests/fns/aliased_interface_methods_test.v
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit faac1fd

Please sign in to comment.