1 /*
2 * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import jdk.incubator.code.Reflect;
25 import java.util.List;
26
27 /*
28 * @test
29 * @summary Smoke test for non-denotable types in IR type descriptors
30 * @modules jdk.incubator.code
31 * @build DenotableTypesTest
32 * @build CodeReflectionTester
33 * @run main CodeReflectionTester DenotableTypesTest
34 */
35
36 public class DenotableTypesTest {
37 static <X extends Number & Runnable> X m1(X x) { return null; }
38 @Reflect
39 @IR("""
40 func @"test1" ()java.type:"void" -> {
41 %0 : java.type:"java.lang.Number" = constant @null;
42 %1 : java.type:"java.lang.Number" = invoke %0 @java.ref:"DenotableTypesTest::m1(java.lang.Number):java.lang.Number";
43 return;
44 };
45 """)
46 static void test1() {
47 m1(null);
48 }
49
50 @Reflect
51 @IR("""
52 func @"test2" ()java.type:"void" -> {
53 %0 : java.type:"int" = constant @1;
54 %1 : java.type:"java.lang.Integer" = invoke %0 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
55 %2 : java.type:"double" = constant @3.0d;
56 %3 : java.type:"java.lang.Double" = invoke %2 @java.ref:"java.lang.Double::valueOf(double):java.lang.Double";
57 %4 : java.type:"java.util.List<? extends java.lang.Number>" = invoke %1 %3 @java.ref:"java.util.List::of(java.lang.Object, java.lang.Object):java.util.List";
58 return;
59 };
60 """)
61 static void test2() {
62 List.of(1, 3d); // infinite type! (List<Object & Serializable & Comparable<...>>)
63 }
64
65 static <X extends Throwable> X m2(X x) throws X { return null; }
66
67 @Reflect
68 @IR("""
69 func @"test3" ()java.type:"void" -> {
70 %0 : java.type:"java.lang.RuntimeException" = constant @null;
71 %1 : java.type:"java.lang.RuntimeException" = invoke %0 @java.ref:"DenotableTypesTest::m2(java.lang.Throwable):java.lang.Throwable";
72 return;
73 };
74 """)
75 static void test3() { // @@@ cast?
76 m2(null);
77 }
78
79 interface A { }
80 interface B { }
81 static class C implements A, B { }
82 static class D implements A, B { }
83
84 static <Z> Z pick(Z z1, Z z2) { return null; }
85
86 @Reflect
87 @IR("""
88 func @"test4" ()java.type:"void" -> {
89 %0 : java.type:"java.lang.Object" = constant @null;
90 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
91 %2 : java.type:"java.lang.Object" = constant @null;
92 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
93 %4 : java.type:"DenotableTypesTest$A" = invoke %1 %3 @java.ref:"DenotableTypesTest::pick(java.lang.Object, java.lang.Object):java.lang.Object";
94 return;
95 };
96 """)
97 static void test4() { // @@@ cast?
98 pick((C)null, (D)null);
99 }
100
101 @Reflect
102 @IR("""
103 func @"test5" ()java.type:"void" -> {
104 %0 : java.type:"java.util.List<? extends java.lang.Number>" = constant @null;
105 %1 : Var<java.type:"java.util.List<? extends java.lang.Number>"> = var %0 @"l";
106 %2 : java.type:"java.util.List<? extends java.lang.Number>" = var.load %1;
107 %3 : java.type:"int" = constant @0;
108 %4 : java.type:"java.lang.Number" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object";
109 return;
110 };
111 """)
112 static void test5() { // @@@ cast?
113 List<? extends Number> l = null;
114 l.get(0);
115 }
116
117 @Reflect
118 @IR("""
119 func @"test6" ()java.type:"void" -> {
120 %0 : java.type:"java.util.List<? super java.lang.Number>" = constant @null;
121 %1 : Var<java.type:"java.util.List<? super java.lang.Number>"> = var %0 @"l";
122 %2 : java.type:"java.util.List<? super java.lang.Number>" = var.load %1;
123 %3 : java.type:"int" = constant @0;
124 %4 : java.type:"java.lang.Object" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object";
125 return;
126 };
127 """)
128 static void test6() {
129 List<? super Number> l = null;
130 l.get(0);
131 }
132
133 static void consume(Runnable r) { }
134
135 @Reflect
136 @IR("""
137 func @"test7" ()java.type:"void" -> {
138 %0 : java.type:"&DenotableTypesTest::test7():void::<X>" = constant @null;
139 %1 : Var<java.type:"&DenotableTypesTest::test7():void::<X>"> = var %0 @"x";
140 %2 : java.type:"&DenotableTypesTest::test7():void::<X>" = var.load %1;
141 %3 : java.type:"java.lang.Runnable" = cast %2 @java.type:"java.lang.Runnable";
142 invoke %3 @java.ref:"DenotableTypesTest::consume(java.lang.Runnable):void";
143 return;
144 };
145 """)
146 static <X extends Object & Runnable> void test7() {
147 X x = null;
148 consume(x);
149 }
150
151 @Reflect
152 @IR("""
153 func @"test8" ()java.type:"&DenotableTypesTest::test8():java.lang.Object::<X>" -> {
154 %0 : java.type:"&DenotableTypesTest::test8():java.lang.Object::<X>" = constant @null;
155 %1 : Var<java.type:"&DenotableTypesTest::test8():java.lang.Object::<X>"> = var %0 @"x";
156 %2 : java.type:"&DenotableTypesTest::test8():java.lang.Object::<X>" = var.load %1;
157 %3 : java.type:"java.lang.Runnable" = cast %2 @java.type:"java.lang.Runnable";
158 invoke %3 @java.ref:"DenotableTypesTest::consume(java.lang.Runnable):void";
159 %4 : java.type:"&DenotableTypesTest::test8():java.lang.Object::<X>" = var.load %1;
160 return %4;
161 };
162 """)
163 static <X extends Object & Runnable> X test8() {
164 X x = null;
165 consume(x);
166 return x;
167 }
168
169 interface Adder<X> {
170 void add(Adder<X> adder);
171 }
172
173 @Reflect
174 @IR("""
175 func @"test8" (%0 : java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>")java.type:"void" -> {
176 %1 : Var<java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>"> = var %0 @"list";
177 %2 : java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>" = var.load %1;
178 %3 : java.type:"int" = constant @0;
179 %4 : java.type:"DenotableTypesTest$Adder<java.lang.Integer>" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object";
180 %5 : java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>" = var.load %1;
181 %6 : java.type:"int" = constant @1;
182 %7 : java.type:"DenotableTypesTest$Adder<java.lang.Integer>" = invoke %5 %6 @java.ref:"java.util.List::get(int):java.lang.Object";
183 invoke %4 %7 @java.ref:"DenotableTypesTest$Adder::add(DenotableTypesTest$Adder):void";
184 return;
185 };
186 """)
187 static void test8(List<? extends Adder<Integer>> list) {
188 list.get(0).add(list.get(1));
189 }
190
191 static class Box<X> {
192 X x;
193 }
194
195 @Reflect
196 @IR("""
197 func @"test9" (%0 : java.type:"java.util.List<? extends DenotableTypesTest$Box<java.lang.Integer>>")java.type:"void" -> {
198 %1 : Var<java.type:"java.util.List<? extends DenotableTypesTest$Box<java.lang.Integer>>"> = var %0 @"list";
199 %2 : java.type:"java.util.List<? extends DenotableTypesTest$Box<java.lang.Integer>>" = var.load %1;
200 %3 : java.type:"int" = constant @0;
201 %4 : java.type:"DenotableTypesTest$Box<java.lang.Integer>" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object";
202 %5 : java.type:"java.lang.Integer" = field.load %4 @java.ref:"DenotableTypesTest$Box::x:java.lang.Object";
203 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
204 return;
205 };
206 """)
207 static void test9(List<? extends Box<Integer>> list) {
208 Integer i = list.get(0).x;
209 }
210
211 interface E {
212 void m();
213 }
214
215 static class XA extends Exception implements E {
216 public void m() { }
217 }
218
219 static class XB extends Exception implements E {
220 public void m() { }
221 }
222
223 static void g() throws XA, XB { }
224
225 @Reflect
226 @IR("""
227 func @"test10" ()java.type:"void" -> {
228 java.try @Tuple<Tuple<java.type:"DenotableTypesTest$XA", java.type:"DenotableTypesTest$XB">>
229 ()java.type:"void" -> {
230 invoke @java.ref:"DenotableTypesTest::g():void";
231 yield;
232 }
233 (%0 : java.type:"java.lang.Exception")java.type:"void" -> {
234 %1 : Var<java.type:"java.lang.Exception"> = var %0 @"x";
235 %2 : java.type:"java.lang.Exception" = var.load %1;
236 %3 : java.type:"DenotableTypesTest$E" = cast %2 @java.type:"DenotableTypesTest$E";
237 invoke %3 @java.ref:"DenotableTypesTest$E::m():void";
238 yield;
239 };
240 return;
241 };
242 """)
243 static void test10() {
244 try {
245 g();
246 } catch (XA | XB x) {
247 x.m();
248 }
249 }
250
251 static <Z> List<Z> pickInv(Z z1, Z z2) { return null; }
252 static <Z> List<? extends Z> pickExt(Z z1, Z z2) { return null; }
253 static <Z> List<? super Z> pickSup(Z z1, Z z2) { return null; }
254
255 // test intersections
256
257 @Reflect
258 @IR("""
259 func @"test11" ()java.type:"void" -> {
260 %0 : java.type:"java.lang.Object" = constant @null;
261 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
262 %2 : java.type:"java.lang.Object" = constant @null;
263 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
264 %4 : java.type:"java.util.List<? extends DenotableTypesTest$A>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickInv(java.lang.Object, java.lang.Object):java.util.List";
265 return;
266 };
267 """)
268 static void test11() {
269 pickInv((C)null, (D)null);
270 }
271
272 @Reflect
273 @IR("""
274 func @"test12" ()java.type:"void" -> {
275 %0 : java.type:"java.lang.Object" = constant @null;
276 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
277 %2 : java.type:"java.lang.Object" = constant @null;
278 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
279 %4 : java.type:"java.util.List<? extends DenotableTypesTest$A>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickExt(java.lang.Object, java.lang.Object):java.util.List";
280 return;
281 };
282 """)
283 static void test12() {
284 pickExt((C)null, (D)null);
285 }
286
287 @Reflect
288 @IR("""
289 func @"test13" ()java.type:"void" -> {
290 %0 : java.type:"java.lang.Object" = constant @null;
291 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
292 %2 : java.type:"java.lang.Object" = constant @null;
293 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
294 %4 : java.type:"java.util.List<?>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickSup(java.lang.Object, java.lang.Object):java.util.List";
295 return;
296 };
297 """)
298 static void test13() {
299 pickSup((C)null, (D)null);
300 }
301
302 static <Z> List<Z[]> pickInvArr(Z z1, Z z2) { return null; }
303 static <Z> List<? extends Z[]> pickExtArr(Z z1, Z z2) { return null; }
304 static <Z> List<? super Z[]> pickSupArr(Z z1, Z z2) { return null; }
305
306 // test arrays of intersections
307
308 @Reflect
309 @IR("""
310 func @"test14" ()java.type:"void" -> {
311 %0 : java.type:"java.lang.Object" = constant @null;
312 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
313 %2 : java.type:"java.lang.Object" = constant @null;
314 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
315 %4 : java.type:"java.util.List<? extends DenotableTypesTest$A[]>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickInvArr(java.lang.Object, java.lang.Object):java.util.List";
316 return;
317 };
318 """)
319 static void test14() {
320 pickInvArr((C)null, (D)null);
321 }
322
323 @Reflect
324 @IR("""
325 func @"test15" ()java.type:"void" -> {
326 %0 : java.type:"java.lang.Object" = constant @null;
327 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
328 %2 : java.type:"java.lang.Object" = constant @null;
329 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
330 %4 : java.type:"java.util.List<? extends DenotableTypesTest$A[]>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickExtArr(java.lang.Object, java.lang.Object):java.util.List";
331 return;
332 };
333 """)
334 static void test15() {
335 pickExtArr((C)null, (D)null);
336 }
337
338 @Reflect
339 @IR("""
340 func @"test16" ()java.type:"void" -> {
341 %0 : java.type:"java.lang.Object" = constant @null;
342 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
343 %2 : java.type:"java.lang.Object" = constant @null;
344 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
345 %4 : java.type:"java.util.List<?>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickSupArr(java.lang.Object, java.lang.Object):java.util.List";
346 return;
347 };
348 """)
349 static void test16() {
350 pickSupArr((C)null, (D)null);
351 }
352
353 interface F<X> { }
354 interface G<X> { }
355 static class H<X> implements F<X>, G<X> { }
356 static class I<X> implements F<X>, G<X> { }
357
358 static <Z> H<Z> pickH(Z z1, Z z2) { return null; }
359 static <Z> I<Z> pickI(Z z1, Z z2) { return null; }
360
361 // test intersections of intersections
362
363 @Reflect
364 @IR("""
365 func @"test17" ()java.type:"void" -> {
366 %0 : java.type:"java.lang.Object" = constant @null;
367 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
368 %2 : java.type:"java.lang.Object" = constant @null;
369 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
370 %4 : java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickH(java.lang.Object, java.lang.Object):DenotableTypesTest$H";
371 %5 : Var<java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>"> = var %4 @"fst";
372 %6 : java.type:"java.lang.Object" = constant @null;
373 %7 : java.type:"DenotableTypesTest$C" = cast %6 @java.type:"DenotableTypesTest$C";
374 %8 : java.type:"java.lang.Object" = constant @null;
375 %9 : java.type:"DenotableTypesTest$D" = cast %8 @java.type:"DenotableTypesTest$D";
376 %10 : java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>" = invoke %7 %9 @java.ref:"DenotableTypesTest::pickI(java.lang.Object, java.lang.Object):DenotableTypesTest$I";
377 %11 : Var<java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>"> = var %10 @"snd";
378 %12 : java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>" = var.load %5;
379 %13 : java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>" = var.load %11;
380 %14 : java.type:"java.util.List<? extends DenotableTypesTest$F<? extends DenotableTypesTest$A>>" = invoke %12 %13 @java.ref:"DenotableTypesTest::pickInv(java.lang.Object, java.lang.Object):java.util.List";
381 return;
382 };
383 """)
384 static void test17() {
385 var fst = pickH((C)null, (D)null);
386 var snd = pickI((C)null, (D)null);
387 pickInv(fst, snd);
388 }
389
390 @Reflect
391 @IR("""
392 func @"test18" ()java.type:"void" -> {
393 %0 : java.type:"java.lang.Object" = constant @null;
394 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
395 %2 : java.type:"java.lang.Object" = constant @null;
396 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
397 %4 : java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickH(java.lang.Object, java.lang.Object):DenotableTypesTest$H";
398 %5 : Var<java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>"> = var %4 @"fst";
399 %6 : java.type:"java.lang.Object" = constant @null;
400 %7 : java.type:"DenotableTypesTest$C" = cast %6 @java.type:"DenotableTypesTest$C";
401 %8 : java.type:"java.lang.Object" = constant @null;
402 %9 : java.type:"DenotableTypesTest$D" = cast %8 @java.type:"DenotableTypesTest$D";
403 %10 : java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>" = invoke %7 %9 @java.ref:"DenotableTypesTest::pickI(java.lang.Object, java.lang.Object):DenotableTypesTest$I";
404 %11 : Var<java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>"> = var %10 @"snd";
405 %12 : java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>" = var.load %5;
406 %13 : java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>" = var.load %11;
407 %14 : java.type:"java.util.List<? extends DenotableTypesTest$F<? extends DenotableTypesTest$A>>" = invoke %12 %13 @java.ref:"DenotableTypesTest::pickExt(java.lang.Object, java.lang.Object):java.util.List";
408 return;
409 };
410 """)
411 static void test18() {
412 var fst = pickH((C)null, (D)null);
413 var snd = pickI((C)null, (D)null);
414 pickExt(fst, snd);
415 }
416
417 @Reflect
418 @IR("""
419 func @"test19" ()java.type:"void" -> {
420 %0 : java.type:"java.lang.Object" = constant @null;
421 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C";
422 %2 : java.type:"java.lang.Object" = constant @null;
423 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D";
424 %4 : java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>" = invoke %1 %3 @java.ref:"DenotableTypesTest::pickH(java.lang.Object, java.lang.Object):DenotableTypesTest$H";
425 %5 : Var<java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>"> = var %4 @"fst";
426 %6 : java.type:"java.lang.Object" = constant @null;
427 %7 : java.type:"DenotableTypesTest$C" = cast %6 @java.type:"DenotableTypesTest$C";
428 %8 : java.type:"java.lang.Object" = constant @null;
429 %9 : java.type:"DenotableTypesTest$D" = cast %8 @java.type:"DenotableTypesTest$D";
430 %10 : java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>" = invoke %7 %9 @java.ref:"DenotableTypesTest::pickI(java.lang.Object, java.lang.Object):DenotableTypesTest$I";
431 %11 : Var<java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>"> = var %10 @"snd";
432 %12 : java.type:"DenotableTypesTest$H<? extends DenotableTypesTest$A>" = var.load %5;
433 %13 : java.type:"DenotableTypesTest$I<? extends DenotableTypesTest$A>" = var.load %11;
434 %14 : java.type:"java.util.List<?>" = invoke %12 %13 @java.ref:"DenotableTypesTest::pickSup(java.lang.Object, java.lang.Object):java.util.List";
435 return;
436 };
437 """)
438 static void test19() {
439 var fst = pickH((C)null, (D)null);
440 var snd = pickI((C)null, (D)null);
441 pickSup(fst, snd);
442 }
443
444 @Reflect
445 @IR("""
446 func @"test20" (%0 : java.type:"DenotableTypesTest$Box<? extends java.lang.Number>")java.type:"java.lang.Number" -> {
447 %1 : Var<java.type:"DenotableTypesTest$Box<? extends java.lang.Number>"> = var %0 @"box";
448 %2 : java.type:"DenotableTypesTest$Box<? extends java.lang.Number>" = var.load %1;
449 %3 : java.type:"java.lang.Number" = field.load %2 @java.ref:"DenotableTypesTest$Box::x:java.lang.Object";
450 return %3;
451 };
452 """)
453 static Number test20(Box<? extends Number> box) {
454 return box.x;
455 }
456
457 @Reflect
458 @IR("""
459 func @"test21" (%0 : java.type:"DenotableTypesTest$Box<? super java.lang.Number>")java.type:"java.lang.Object" -> {
460 %1 : Var<java.type:"DenotableTypesTest$Box<? super java.lang.Number>"> = var %0 @"box";
461 %2 : java.type:"DenotableTypesTest$Box<? super java.lang.Number>" = var.load %1;
462 %3 : java.type:"java.lang.Object" = field.load %2 @java.ref:"DenotableTypesTest$Box::x:java.lang.Object";
463 return %3;
464 };
465 """)
466 static Object test21(Box<? super Number> box) {
467 return box.x;
468 }
469
470 static class Base<T extends Base<T>> {}
471
472 static <T extends Base<T>> T produce() {
473 return null;
474 }
475
476 @Reflect
477 @IR("""
478 func @"test22" ()java.type:"void" -> {
479 %0 : java.type:"DenotableTypesTest$Base<?>" = invoke @java.ref:"DenotableTypesTest::produce():DenotableTypesTest$Base";
480 %1 : java.type:"java.lang.Runnable" = cast %0 @java.type:"java.lang.Runnable";
481 invoke %1 @java.ref:"DenotableTypesTest::consume(java.lang.Runnable):void";
482 return;
483 };
484 """)
485 static void test22() {
486 consume(produce());
487 }
488 }