| /* |
| * @test /nodynamiccopyright/ |
| * @bug 8030741 |
| * @summary Inference: implement eager resolution of return types, consistent with JDK-8028800 |
| * @compile/fail/ref=EagerReturnTypeResolutionTestb.out -XDrawDiagnostics EagerReturnTypeResolutionTestb.java |
| * @author Dan Smith |
| */ |
| |
| import java.util.List; |
| |
| public class EagerReturnTypeResolutionTestb { |
| interface I<S> {} |
| interface J<S> extends I<S> {} |
| interface K extends I<String> {} |
| interface L<S> extends I {} |
| |
| <T> T lower(List<? extends T> l) { return null; } |
| <T> T lower2(List<? extends T> l1, List<? extends T> l2) { return null; } |
| |
| <T> T upper(List<? super T> l) { return null; } |
| <T> T upper2(List<? super T> l1, List<? super T> l2) { return null; } |
| |
| <T> T eq(List<T> l) { return null; } |
| <T> T eq2(List<T> l1, List<T> l2) { return null; } |
| |
| <X> void takeI(I<X> i) {} |
| void takeIString(I<String> i) {} |
| I<String> iStringField; |
| |
| void takeLong(long arg) {} |
| long longField; |
| |
| void testSimpleCaptureOK(List<I<?>> i1) { |
| takeI(lower(i1)); // ok* |
| takeI(eq(i1)); // ok* |
| takeI(upper(i1)); // ok, no capture |
| takeIString(upper(i1)); // ok |
| iStringField = upper(i1); // ok |
| } |
| |
| void testSimpleCaptureKO(List<I<?>> i1) { |
| takeIString(lower(i1)); // ERROR |
| takeIString(eq(i1)); // ERROR |
| iStringField = lower(i1); // ERROR |
| iStringField = eq(i1); // ERROR |
| } |
| |
| void testMultiCaptureOK(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3, |
| List<J<String>> j1, List<J<Integer>> j2, List<K> k1) { |
| /* Lines marked with JDK-8029002 should be uncommented once this bug is |
| * fixed |
| */ |
| takeI(lower2(i1, i2)); // ok* |
| takeI(lower2(i1, i3)); // ok* |
| takeI(upper2(i1, i3)); // ok, no capture* JDK-8029002 |
| |
| takeIString(upper2(i1, i3)); // ok, no capture |
| iStringField = upper2(i1, i3); // ok, no capture |
| |
| takeI(lower2(j1, j2)); // ok* |
| takeI(lower2(j1, k1)); // ok, no capture |
| takeI(upper2(j1, k1)); // ok, no capture* JDK-8029002 |
| |
| takeIString(lower2(j1, k1)); // ok, no capture |
| takeIString(upper2(j1, k1)); // ok, no capture |
| |
| iStringField = lower2(j1, k1); // ok, no capture |
| iStringField = upper2(j1, k1); // ok, no capture |
| takeI(lower2(j2, k1)); // ok* |
| } |
| |
| void testMultiCaptureKO(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3, |
| List<J<String>> j1, List<J<Integer>> j2, List<K> k1) { |
| takeI(eq2(i1, i2)); // ERROR, bad bounds |
| takeI(upper2(i1, i2)); // ERROR, bad bounds |
| |
| takeIString(lower2(i1, i2)); // ERROR |
| takeIString(eq2(i1, i2)); // ERROR, bad bounds |
| takeIString(upper2(i1, i2)); // ERROR, bad bounds |
| |
| iStringField = lower2(i1, i2); // ERROR |
| iStringField = eq2(i1, i2); // ERROR, bad bounds |
| iStringField = upper2(i1, i2); // ERROR, bad bounds |
| |
| takeI(eq2(i1, i3)); // ERROR, bad bounds |
| takeIString(lower2(i1, i3)); // ERROR |
| takeIString(eq2(i1, i3)); // ERROR, bad bounds |
| |
| iStringField = lower2(i1, i3); // ERROR |
| iStringField = eq2(i1, i3); // ERROR, bad bounds |
| takeI(eq2(j1, j2)); // ERROR, bad bounds |
| takeI(upper2(j1, j2)); // ERROR, bad bounds |
| |
| takeIString(lower2(j1, j2)); // ERROR |
| takeIString(eq2(j1, j2)); // ERROR, bad bounds |
| takeIString(upper2(j1, j2)); // ERROR, bad bounds |
| |
| iStringField = lower2(j1, j2); // ERROR |
| iStringField = eq2(j1, j2); // ERROR, bad bounds |
| iStringField = upper2(j1, j2); // ERROR, bad bounds |
| |
| takeI(eq2(j1, k1)); // ERROR, bad bounds |
| takeIString(eq2(j1, k1)); // ERROR, bad bounds |
| iStringField = eq2(j1, k1); // ERROR, bad bounds |
| takeI(eq2(j2, k1)); // ERROR, bad bounds |
| takeI(upper2(j2, k1)); // ERROR, bad bounds; actual: no error, see JDK-8037474 |
| |
| takeIString(lower2(j2, k1)); // ERROR |
| takeIString(eq2(j2, k1)); // ERROR, bad bounds |
| takeIString(upper2(j2, k1)); // ERROR, bad bounds |
| |
| iStringField = lower2(j2, k1); // ERROR |
| iStringField = eq2(j2, k1); // ERROR, bad bounds |
| iStringField = upper2(j2, k1); // ERROR, bad bounds |
| } |
| |
| void testRawOK(List<I> i1, List<J> j1, List<L<String>> l1) { |
| takeI(lower(i1)); // ok, unchecked |
| takeI(eq(i1)); // ok, unchecked |
| takeI(upper(i1)); // ok, no capture, not unchecked |
| |
| takeIString(lower(i1)); // ok, unchecked |
| takeIString(eq(i1)); // ok, unchecked |
| takeIString(upper(i1)); // ok, no capture, not unchecked |
| |
| iStringField = lower(i1); // ok, unchecked |
| iStringField = eq(i1); // ok, unchecked |
| iStringField = upper(i1); // ok, no capture, not unchecked |
| |
| takeI(lower(j1)); // ok, unchecked |
| takeI(eq(j1)); // ok, unchecked |
| takeI(upper(j1)); // bad bounds? -- spec is unclear |
| |
| takeIString(lower(j1)); // ok, unchecked |
| takeIString(eq(j1)); // ok, unchecked |
| takeIString(upper(j1)); // bad bounds? -- spec is unclear |
| |
| iStringField = lower(j1); // ok, unchecked |
| iStringField = eq(j1); // ok, unchecked |
| iStringField = upper(j1); // bad bounds? -- spec is unclear |
| |
| takeI(lower(l1)); // ok, unchecked |
| takeI(eq(l1)); // ok, unchecked |
| takeI(upper(l1)); // bad bounds? -- spec is unclear |
| |
| takeIString(lower(l1)); // ok, unchecked |
| takeIString(eq(l1)); // ok, unchecked |
| takeIString(upper(l1)); // bad bounds? -- spec is unclear |
| |
| iStringField = lower(l1); // ok, unchecked |
| iStringField = eq(l1); // ok, unchecked |
| iStringField = upper(l1); // bad bounds? -- spec is unclear |
| } |
| |
| void testPrimOK(List<Integer> i1, List<Long> l1, List<Double> d1) { |
| takeLong(lower(i1)); // ok |
| takeLong(eq(i1)); // ok |
| takeLong(upper(i1)); // ok* |
| |
| longField = lower(i1); // ok |
| longField = eq(i1); // ok |
| longField = upper(i1); // ok* |
| |
| takeLong(lower(l1)); // ok |
| takeLong(eq(l1)); // ok |
| takeLong(upper(l1)); // ok |
| |
| longField = lower(l1); // ok |
| longField = eq(l1); // ok |
| longField = upper(l1); // ok |
| } |
| |
| void testPrimKO(List<Integer> i1, List<Long> l1, List<Double> d1) { |
| takeLong(lower(d1)); // ERROR |
| takeLong(eq(d1)); // ERROR |
| takeLong(upper(d1)); // ERROR |
| |
| longField = lower(d1); // ERROR |
| longField = eq(d1); // ERROR |
| longField = upper(d1); // ERROR |
| } |
| } |