FULL PRODUCT VERSION :
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10586]
A DESCRIPTION OF THE PROBLEM :
This code gives a compiler error:
import java.util.List;
import java.util.function.Function;
class Test {
interface Mapper<T, U extends MapperProvider<U>> extends Function<T, U> {}
interface MapperProvider<V> {
Mapper<V, ?> provide();
}
private <V extends MapperProvider<V>> void use(V c) {
use2(c.provide().apply(c));
}
private <W extends MapperProvider<W>> void use2(W c) {
}
}
When I wrap U and W in a List<>, the code compiles without error:
import java.util.List;
import java.util.function.Function;
class Test {
interface Mapper<T, U extends MapperProvider<U>> extends Function<T, List<U>> {}
interface MapperProvider<V> {
Mapper<V, ?> provide();
}
private <V extends MapperProvider<V>> void use(V c) {
use2(c.provide().apply(c));
}
private <W extends MapperProvider<W>> void use2(List<W> c) {
}
}
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile each of the code samples.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both code samples should yield the same compiler status.
ACTUAL -
Different compiler status.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Teust.java:12: error: method use2 in class Test cannot be applied to given types;
use2(c.provide().apply(c));
^
required: W
found: CAP#1
reason: inference variable W has incompatible bounds
equality constraints: CAP#1
lower bounds: MapperProvider<CAP#1>
where W is a type-variable:
W extends MapperProvider<W> declared in method <W>use2(W)
where CAP#1 is a fresh type-variable:
CAP#1 extends MapperProvider<CAP#1> from capture of ?
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.List;
import java.util.function.Function;
class Test {
interface Mapper<T, U extends MapperProvider<U>> extends Function<T, U> {}
interface MapperProvider<V> {
Mapper<V, ?> provide();
}
private <V extends MapperProvider<V>> void use(V c) {
use2(c.provide().apply(c));
}
private <W extends MapperProvider<W>> void use2(W c) {
}
}
import java.util.List;
import java.util.function.Function;
class Test {
interface Mapper<T, U extends MapperProvider<U>> extends Function<T, List<U>> {}
interface MapperProvider<V> {
Mapper<V, ?> provide();
}
private <V extends MapperProvider<V>> void use(V c) {
use2(c.provide().apply(c));
}
private <W extends MapperProvider<W>> void use2(List<W> c) {
}
}
---------- END SOURCE ----------