1/*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16class A {}
17
18class B extends A {}
19
20class C extends B {}
21
22class D extends C {}
23
24class F extends B {}
25
26class GenA<K> {}
27
28class GenB<K> extends GenA<F> {}
29
30final class GenC<K, M> extends GenB<M> {}
31
32final class GenD<K, M> extends GenB<K> {}
33
34function foo(p: Object): int {
35  return 0;
36}
37
38function foo(p: GenA<A>): int {
39  return 1;
40}
41
42function foo(p: GenA<B>): int {
43  return 2;
44}
45
46function foo(p: GenB<A>): int {
47  return 3;
48}
49
50function foo(p: GenB<B>): int {
51  return 4;
52}
53
54function foo(p: GenB<C>): int {
55  return 5;
56}
57
58function foo(p: GenB<F>): int {
59  return 6;
60}
61
62function foo(p: GenC<A, A>): int {
63  return 7;
64}
65
66function foo(p: GenC<B, B>): int {
67  return 8;
68}
69
70function foo(p: GenC<C, F>): int {
71  return 9;
72}
73
74function foo(p: GenC<F, C>): int {
75  return 10;
76}
77
78function main(): void {
79  let a = true ? new GenB<C> : new GenB<F>;
80  let test_a : GenB<B> = a;
81
82  assert (foo(a) == foo(new GenB<B>));
83
84  let b = true ? new GenD<F, C> : new GenC<F, C>;
85  let test_b : GenB<in B> = b;
86
87  assert (foo(b) == 0);
88  // foo(b) would call signature 'foo(p: GenB<in B>)',
89  // but it's not declared (erased signature would
90  // clash with other foo(p: GenB<*>) signatures),
91  // so it's calling 'foo(p: Object)', which returns 0
92
93  let c = true ? new GenC<F, C> : new GenC<C, F>;
94  let test_c : GenC<B, B> = c;
95
96  assert (foo(c) == foo(new GenC<B, B>));
97
98  let d = true ? new GenA<D> : new GenB<A>;
99  let test_d : GenA<B> = d;
100
101  assert (foo(d) == foo(new GenA<B>));
102
103  let f = true ? new GenB<C> : new GenB<C>;
104  let test_f : GenB<C> = f;
105
106  assert (foo(f) == foo(new GenB<C>));
107}
108