-
Sub-task
-
Resolution: Delivered
-
P4
-
9
-
Verified
Reporting previously silent errors found during incorporation, JLS 8 §18.3, was supposed to be a clean-up with performance only implications. But consider the test case:
```
import java.util.Arrays;
import java.util.List;
class Klass {
public static <A> List<List<A>> foo(List<? extends A>... lists) {
return foo(Arrays.asList(lists));
}
public static <B> List<List<B>> foo(List<? extends List<? extends B>> lists) {
return null;
}
}
```
This code was not accepted before the patch for [1], but after this patch the compiler is accepting it. Accepting this code is the right behavior as not reporting incorporation errors was a bug in the compiler.
While determining the applicability of method:
```
<B> List<List<B>> foo(List<? extends List<? extends B>> lists)
```
For which we have the constraints:
```
b <: Object
t <: List<? extends B>
t<: Object
List<? extends A> <: t
```
First, inference variable b is selected for instantiation:
```
b = CAP1 of ? extends A
```
so this implies that:
```
t <: List<? extends CAP1 of ? extends A>
t<: Object
List<? extends A> <: t
```
Now all the bounds are checked for consistency. While checking if List<? extends A> is a subtype of List<? extends CAP1 of ? extends A> a bound error is reported. Before the compiler was just swallowing it. As now the error is reported while inference variable b is being instantiated, the bound set is rolled back to it's initial state, 'b' is instantiated to Object, and with this instantiation the constraint set is solvable, the method is applicable, it's the only applicable one and the code is accepted as correct. The compiler behavior in this case is defined at JLS 8 §18.4
This fix has source compatibility impact, right now code that wasn't being accepted is now being accepted by the javac compiler. Currently there are no reports of any other kind of incompatibility.
[1] [https://bugs.openjdk.java.net/browse/JDK-8078024](https://bugs.openjdk.java.net/browse/JDK-8078024)
```
import java.util.Arrays;
import java.util.List;
class Klass {
public static <A> List<List<A>> foo(List<? extends A>... lists) {
return foo(Arrays.asList(lists));
}
public static <B> List<List<B>> foo(List<? extends List<? extends B>> lists) {
return null;
}
}
```
This code was not accepted before the patch for [1], but after this patch the compiler is accepting it. Accepting this code is the right behavior as not reporting incorporation errors was a bug in the compiler.
While determining the applicability of method:
```
<B> List<List<B>> foo(List<? extends List<? extends B>> lists)
```
For which we have the constraints:
```
b <: Object
t <: List<? extends B>
t<: Object
List<? extends A> <: t
```
First, inference variable b is selected for instantiation:
```
b = CAP1 of ? extends A
```
so this implies that:
```
t <: List<? extends CAP1 of ? extends A>
t<: Object
List<? extends A> <: t
```
Now all the bounds are checked for consistency. While checking if List<? extends A> is a subtype of List<? extends CAP1 of ? extends A> a bound error is reported. Before the compiler was just swallowing it. As now the error is reported while inference variable b is being instantiated, the bound set is rolled back to it's initial state, 'b' is instantiated to Object, and with this instantiation the constraint set is solvable, the method is applicable, it's the only applicable one and the code is accepted as correct. The compiler behavior in this case is defined at JLS 8 §18.4
This fix has source compatibility impact, right now code that wasn't being accepted is now being accepted by the javac compiler. Currently there are no reports of any other kind of incompatibility.
[1] [https://bugs.openjdk.java.net/browse/JDK-8078024](https://bugs.openjdk.java.net/browse/JDK-8078024)