v2 / vlib / v / tests / generics / generic_match_expr_test.v
173 lines · 140 sloc · 3.67 KB · 72f6f681059c7e1916c60286f022d663af1d45d9
Raw
1struct Foo[T] {
2 a T
3}
4
5fn r[T]() Foo[T] {
6 return Foo[T]{}
7}
8
9fn t[T](v T) !Foo[T] {
10 return match typeof(v).name {
11 'string' {
12 r[T]()
13 }
14 else {
15 r[T]()
16 }
17 }
18}
19
20fn test_main() {
21 t(1)!
22 t('')!
23 assert true
24}
25
26type GenericMatchSumtype[T] = GenericMatchY[T] | GenericMatchZ[T]
27
28fn (mut x GenericMatchSumtype[T]) do_it[T]() string {
29 match mut x {
30 GenericMatchY[T] { return 'doing GenericMatchY' }
31 GenericMatchZ[T] { return 'doing GenericMatchZ' }
32 }
33
34 return ''
35}
36
37struct GenericMatchY[T] {
38 name string
39 value T
40}
41
42struct GenericMatchZ[T] {
43 name string
44 value T
45}
46
47fn test_match_generic_sumtype_variant_in_generic_method() {
48 y := GenericMatchY[int]{
49 name: 'Y'
50 value: 1
51 }
52 z := GenericMatchZ[bool]{
53 name: 'Z'
54 value: true
55 }
56
57 mut x1 := GenericMatchSumtype[int](y)
58 assert x1.do_it() == 'doing GenericMatchY'
59
60 mut x2 := GenericMatchSumtype[bool](z)
61 assert x2.do_it() == 'doing GenericMatchZ'
62}
63
64type MatchedGenericMethodBox[T] = MatchedGenericMethodY[T] | MatchedGenericMethodZ[T]
65
66struct MatchedGenericMethodY[T] {
67 value T
68}
69
70struct MatchedGenericMethodZ[T] {
71 value T
72}
73
74fn (x MatchedGenericMethodBox[T]) explicit_variant_name[T]() string {
75 match x {
76 MatchedGenericMethodY[T] { return x.explicit_variant_name[T]() }
77 MatchedGenericMethodZ[T] { return x.explicit_variant_name[T]() }
78 }
79
80 return ''
81}
82
83fn (y MatchedGenericMethodY[T]) explicit_variant_name[T]() string {
84 return 'Y'
85}
86
87fn (z MatchedGenericMethodZ[T]) explicit_variant_name[T]() string {
88 return 'Z'
89}
90
91fn (x MatchedGenericMethodBox[T]) inferred_variant_name[T]() string {
92 match x {
93 MatchedGenericMethodY[T] { return x.inferred_variant_name() }
94 MatchedGenericMethodZ[T] { return x.inferred_variant_name() }
95 }
96
97 return ''
98}
99
100fn (x MatchedGenericMethodBox[T]) match_expr_variant_name[T]() string {
101 return match x {
102 MatchedGenericMethodY[T] { x.explicit_variant_name[T]() }
103 MatchedGenericMethodZ[T] { x.explicit_variant_name[T]() }
104 }
105}
106
107fn (y MatchedGenericMethodY[T]) inferred_variant_name[T]() string {
108 return 'Y'
109}
110
111fn (z MatchedGenericMethodZ[T]) inferred_variant_name[T]() string {
112 return 'Z'
113}
114
115fn test_generic_sumtype_match_calls_explicit_generic_method_on_variant() {
116 y := MatchedGenericMethodBox[int](MatchedGenericMethodY[int]{
117 value: 1
118 })
119 assert y.explicit_variant_name() == 'Y'
120
121 z := MatchedGenericMethodBox[bool](MatchedGenericMethodZ[bool]{
122 value: true
123 })
124 assert z.explicit_variant_name() == 'Z'
125}
126
127fn test_generic_sumtype_match_calls_explicit_generic_method_on_variant_reversed() {
128 z := MatchedGenericMethodBox[bool](MatchedGenericMethodZ[bool]{
129 value: true
130 })
131 assert z.explicit_variant_name() == 'Z'
132
133 y := MatchedGenericMethodBox[int](MatchedGenericMethodY[int]{
134 value: 1
135 })
136 assert y.explicit_variant_name() == 'Y'
137}
138
139fn test_generic_sumtype_match_calls_explicit_generic_method_single_instantiation() {
140 y := MatchedGenericMethodBox[string](MatchedGenericMethodY[string]{
141 value: 'one'
142 })
143 assert y.explicit_variant_name() == 'Y'
144
145 z := MatchedGenericMethodBox[string](MatchedGenericMethodZ[string]{
146 value: 'two'
147 })
148 assert z.explicit_variant_name() == 'Z'
149}
150
151fn test_generic_sumtype_match_calls_inferred_generic_method_on_variant() {
152 z := MatchedGenericMethodBox[int](MatchedGenericMethodZ[int]{
153 value: 1
154 })
155 assert z.inferred_variant_name() == 'Z'
156
157 y := MatchedGenericMethodBox[bool](MatchedGenericMethodY[bool]{
158 value: true
159 })
160 assert y.inferred_variant_name() == 'Y'
161}
162
163fn test_generic_sumtype_match_expr_calls_generic_method_on_last_variant() {
164 y := MatchedGenericMethodBox[int](MatchedGenericMethodY[int]{
165 value: 1
166 })
167 assert y.match_expr_variant_name() == 'Y'
168
169 z := MatchedGenericMethodBox[bool](MatchedGenericMethodZ[bool]{
170 value: true
171 })
172 assert z.match_expr_variant_name() == 'Z'
173}
174