v2 / vlib / v / tests / skip_unused / generic_fn_instantiation_pruning_test.v
177 lines · 172 sloc · 4.51 KB · 7596b52c1db0016d2c9a3460d58a957bd7160b07
Raw
1import os
2
3const vexe = @VEXE
4
5fn test_skip_unused_prunes_unused_generic_fn_instantiations() {
6 tmp_dir := os.join_path(os.vtmp_dir(), 'v_issue_26019')
7 os.mkdir_all(tmp_dir) or { panic(err) }
8 defer {
9 os.rmdir_all(tmp_dir) or {}
10 }
11 source_path := os.join_path(tmp_dir, 'issue_26019.v')
12 source := [
13 'module main',
14 '',
15 'fn new[T]() map[u8]T {',
16 '\tx := map[u8]T{}',
17 '\treturn x',
18 '}',
19 '',
20 'fn not_used_fn() map[u8]int {',
21 '\tx := new[int]()',
22 '\treturn x',
23 '}',
24 '',
25 'fn main() {',
26 '\tx := new[u32]()',
27 '\tdump(x)',
28 '}',
29 ].join('\n')
30 os.write_file(source_path, source) or { panic(err) }
31 res := os.execute('${os.quoted_path(vexe)} -o - ${os.quoted_path(source_path)}')
32 if res.exit_code != 0 {
33 panic(res.output)
34 }
35 assert res.output.contains('VV_LOC Map_u8_u32 main__new_T_u32(void)')
36 assert !res.output.contains('VV_LOC Map_u8_int main__new_T_int(void)')
37}
38
39fn 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}
91
92fn test_skip_unused_keeps_json2_embedded_struct_decode_helpers() {
93 tmp_dir := os.join_path(os.vtmp_dir(), 'v_issue_26928')
94 os.mkdir_all(tmp_dir) or { panic(err) }
95 defer {
96 os.rmdir_all(tmp_dir) or {}
97 }
98 source_path := os.join_path(tmp_dir, 'issue_26928.v')
99 source := [
100 'module main',
101 '',
102 'import time',
103 'import x.json2',
104 '',
105 'struct Meta {',
106 '\tcreated_at ?time.Time',
107 '}',
108 '',
109 'struct Req {',
110 '\tMeta',
111 '\tname string',
112 '}',
113 '',
114 'fn main() {',
115 '\t_ := json2.decode[Req](\'{"name":"x"}\') or { panic(err) }',
116 '}',
117 ].join('\n')
118 os.write_file(source_path, source) or { panic(err) }
119 res := os.execute('${os.quoted_path(vexe)} -w -o - ${os.quoted_path(source_path)}')
120 if res.exit_code != 0 {
121 panic(res.output)
122 }
123 assert res.output.contains('x__json2__decode_struct_key_T_main__Req')
124 assert res.output.contains('x__json2__check_required_struct_fields_T_main__Req')
125 assert res.output.contains('x__json2__create_value_from_optional_T_time__Time')
126}
127
128fn test_skip_unused_marks_dependencies_inside_generic_anon_fns() {
129 tmp_dir := os.join_path(os.vtmp_dir(), 'v_generic_anon_fn_dependencies')
130 os.mkdir_all(tmp_dir) or { panic(err) }
131 defer {
132 os.rmdir_all(tmp_dir) or {}
133 }
134 source_path := os.join_path(tmp_dir, 'generic_anon_fn_dependencies.v')
135 binary_path := os.join_path(tmp_dir, 'generic_anon_fn_dependencies')
136 source := [
137 'module main',
138 '',
139 'struct Holder[T] {',
140 '\tdata []T',
141 '}',
142 '',
143 'fn (h &Holder[T]) nmap[T](others []&Holder[T], f fn ([]T) T) T {',
144 '\treturn f([h.data[0], others[0].data[0]])',
145 '}',
146 '',
147 'fn (a &Holder[T]) subtract[T](b &Holder[T]) T {',
148 '\treturn a.nmap([b], fn [T] (xs []T) T {',
149 '\t\tx := xs[0]',
150 '\t\ty := xs[1]',
151 '\t\t$if T is string {',
152 "\t\t\treturn x.replace(y, '')",
153 '\t\t} $else {',
154 '\t\t\treturn x - y',
155 '\t\t}',
156 '\t})',
157 '}',
158 '',
159 'fn unused_string() {',
160 "\ta := &Holder[string]{data: ['abc']}",
161 "\tb := &Holder[string]{data: ['b']}",
162 '\tprintln(a.subtract(b))',
163 '}',
164 '',
165 'fn main() {',
166 '\ta := &Holder[int]{data: [1]}',
167 '\tb := &Holder[int]{data: [2]}',
168 '\tprintln(a.subtract(b))',
169 '}',
170 ].join('\n')
171 os.write_file(source_path, source) or { panic(err) }
172 res :=
173 os.execute('${os.quoted_path(vexe)} -d no_backtrace -o ${os.quoted_path(binary_path)} ${os.quoted_path(source_path)}')
174 if res.exit_code != 0 {
175 panic(res.output)
176 }
177}
178