Skip to content

Commit dbd3d2a

Browse files
committed
cgen: interface method fix
1 parent 4fa8167 commit dbd3d2a

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

vlib/v/gen/c/fn.v

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,13 @@ fn (mut g Gen) is_used_by_main(node ast.FnDecl) bool {
671671
if receiver_type !in impl_types {
672672
continue
673673
}
674-
if isym.has_method(node.name) || isym.has_method_with_generic_parent(node.name) {
674+
mut interface_requires_method := false
675+
if interface_method := isym.find_method(node.name) {
676+
interface_requires_method = interface_method.no_body
677+
} else if interface_method := isym.find_method_with_generic_parent(node.name) {
678+
interface_requires_method = interface_method.no_body
679+
}
680+
if interface_requires_method {
675681
is_used_by_main = true
676682
break
677683
}

vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,56 @@ fn test_skip_unused_prunes_unused_generic_fn_instantiations() {
3535
assert res.output.contains('VV_LOC Map_u8_u32 main__new_T_u32(void)')
3636
assert !res.output.contains('VV_LOC Map_u8_int main__new_T_int(void)')
3737
}
38+
39+
fn test_skip_unused_does_not_emit_impl_methods_for_interface_extensions() {
40+
tmp_dir := os.join_path(os.vtmp_dir(), 'v_skip_unused_interface_extension_collision')
41+
os.mkdir_all(tmp_dir) or { panic(err) }
42+
defer {
43+
os.rmdir_all(tmp_dir) or {}
44+
}
45+
source_path := os.join_path(tmp_dir, 'interface_extension_collision.v')
46+
source := [
47+
'module main',
48+
'',
49+
'import crypto.internal.subtle',
50+
'',
51+
'interface Elem {}',
52+
'',
53+
'struct Thing {}',
54+
'',
55+
'struct Holder {',
56+
'\titems []Elem',
57+
'}',
58+
'',
59+
'fn (el Elem) equal(_ Elem) bool {',
60+
'\treturn true',
61+
'}',
62+
'',
63+
'fn (t Thing) equal(_ Thing) bool {',
64+
'\treturn subtle.constant_time_compare([u8(1)], [u8(1)]) == 1',
65+
'}',
66+
'',
67+
'fn (h Holder) ok() bool {',
68+
'\tfor i, item in h.items {',
69+
'\t\tfor j, obj in h.items {',
70+
'\t\t\tif i == j {',
71+
'\t\t\t\treturn item.equal(obj)',
72+
'\t\t\t}',
73+
'\t\t}',
74+
'\t}',
75+
'\treturn false',
76+
'}',
77+
'',
78+
'fn main() {',
79+
'\th := Holder{items: [Elem(Thing{}), Elem(Thing{})]}',
80+
'\tprintln(h.ok())',
81+
'}',
82+
].join('\n')
83+
os.write_file(source_path, source) or { panic(err) }
84+
res := os.execute('${os.quoted_path(vexe)} -o - ${os.quoted_path(source_path)}')
85+
if res.exit_code != 0 {
86+
panic(res.output)
87+
}
88+
assert res.output.contains('VV_LOC bool main__Elem_equal(')
89+
assert !res.output.contains('main__Thing_equal(')
90+
}

0 commit comments

Comments
 (0)