Skip to content

Commit 4acddd3

Browse files
authored
markused: fix generic fn instantiation dedup key collision for identical module names (#27399)
1 parent 19d2c62 commit 4acddd3

2 files changed

Lines changed: 71 additions & 1 deletion

File tree

vlib/v/markused/walker.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ fn (mut w Walker) record_used_fn_generic_types(fkey string, concrete_types []ast
510510
fn (w &Walker) fn_generic_types_key(fkey string, concrete_types []ast.Type) string {
511511
mut parts := []string{cap: concrete_types.len}
512512
for typ in concrete_types {
513-
parts << w.table.type_to_str(typ)
513+
parts << u32(typ).str()
514514
}
515515
return '${fkey}:${parts.join('|')}'
516516
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import os
2+
3+
fn write_file(path string, content string) {
4+
os.write_file(path, content) or { panic(err) }
5+
}
6+
7+
fn test_generic_fn_dedup_collision_issue_27398() {
8+
n_pairs := 24
9+
tmp := os.join_path(os.vtmp_dir(), 'v_issue_27398_${os.getpid()}')
10+
os.rmdir_all(tmp) or {}
11+
defer {
12+
os.rmdir_all(tmp) or {}
13+
}
14+
15+
os.mkdir_all(os.join_path(tmp, 'api')) or { panic(err) }
16+
write_file(os.join_path(tmp, 'api', 'common.v'), 'module api
17+
18+
pub struct MyStruct[T] {
19+
pub:
20+
value T
21+
}
22+
23+
pub fn make_struct[T](val T) MyStruct[T] {
24+
return MyStruct[T]{value: val}
25+
}
26+
')
27+
28+
common_mod := 'module common
29+
30+
import api
31+
32+
pub struct Type_a { pub: name string }
33+
pub struct Type_b { pub: age int }
34+
35+
pub fn call_api() {
36+
a := Type_a{name: "hello"}
37+
b := Type_b{age: 42}
38+
_ = api.make_struct(a)
39+
_ = api.make_struct(b)
40+
}
41+
'
42+
43+
mut main_mod := 'module main\n\n'
44+
for i in 0 .. n_pairs {
45+
for _, s in ['a', 'b'] {
46+
dir := os.join_path(tmp, 'm${i}${s}', 'common')
47+
os.mkdir_all(dir) or { panic(err) }
48+
write_file(os.join_path(dir, 'types.v'), common_mod)
49+
main_mod += 'import m${i}${s}.common as m${i}${s}\n'
50+
}
51+
}
52+
main_mod += '\nfn main() {\n'
53+
for i in 0 .. n_pairs {
54+
for _, s in ['a', 'b'] {
55+
main_mod += '\tm${i}${s}.call_api()\n'
56+
}
57+
}
58+
main_mod += '\tprintln("ok")\n}\n'
59+
write_file(os.join_path(tmp, 'main.v'), main_mod)
60+
61+
old_wd := os.getwd()
62+
os.chdir(tmp) or { panic(err) }
63+
defer {
64+
os.chdir(old_wd) or { panic(err) }
65+
}
66+
res := os.execute('${os.quoted_path(@VEXE)} -skip-unused run .')
67+
68+
assert res.exit_code == 0, 'compilation failed:\n${res.output}'
69+
assert res.output.trim_space() == 'ok'
70+
}

0 commit comments

Comments
 (0)