FULL PRODUCT VERSION :
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
OS X 10.11.6
A DESCRIPTION OF THE PROBLEM :
There seams to be differences in how inference is handled between "Function" and "Supplier". I would expect the two examples to conform (see "Actual Result") to the same result. Either a compile error, or not...
Note! The latest version of IntelliJ (2016.3.3) does not give me a warning on this (in the editor)...
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the provided source code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A successful compile
ACTUAL -
InferenceTest.a(
InferenceTest::c,
name -> new Builder<>(new Gamma()));
...does not compile, while:
InferenceTest.b(
InferenceTest::c,
() -> new Builder<>(new Gamma()));
...does
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Error:(8, 22) java: method a in class InferenceTest cannot be applied to given types;
required: java.util.function.Function<B,java.lang.String>,java.util.function.Function<java.lang.String,B>
found: InferenceTest::c,(name)->ne[...]ma())
reason: inferred type does not conform to upper bound(s)
inferred: InferenceTest.Builder<InferenceTest.Alfa>
upper bound(s): InferenceTest.Builder<InferenceTest.Alfa>,InferenceTest.Builder<? extends InferenceTest.Beta>
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.function.Function;
import java.util.function.Supplier;
public class InferenceTest {
public static void main(String[] args) {
//compile error
InferenceTest.a(
InferenceTest::c,
name -> new Builder<>(new Gamma()));
//successfully compiles
InferenceTest.b(
InferenceTest::c,
() -> new Builder<>(new Gamma()));
}
static <T extends Alfa, B extends Builder<T>> void a(
final Function<B, String> f1,
final Function<String, B> f2) {
}
static <T extends Alfa, B extends Builder<T>> void b(
final Function<B, String> f1,
final Supplier<B> s1) {
}
private static String c(final Builder<? extends Beta> builder){return "";}
public static class Alfa {}
public static class Beta extends Alfa {}
public static class Gamma extends Beta {}
public static class Builder<T> {
private final T t;
public Builder(T t) {
this.t = t;
}
}
}
---------- END SOURCE ----------
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
OS X 10.11.6
A DESCRIPTION OF THE PROBLEM :
There seams to be differences in how inference is handled between "Function" and "Supplier". I would expect the two examples to conform (see "Actual Result") to the same result. Either a compile error, or not...
Note! The latest version of IntelliJ (2016.3.3) does not give me a warning on this (in the editor)...
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the provided source code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A successful compile
ACTUAL -
InferenceTest.a(
InferenceTest::c,
name -> new Builder<>(new Gamma()));
...does not compile, while:
InferenceTest.b(
InferenceTest::c,
() -> new Builder<>(new Gamma()));
...does
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Error:(8, 22) java: method a in class InferenceTest cannot be applied to given types;
required: java.util.function.Function<B,java.lang.String>,java.util.function.Function<java.lang.String,B>
found: InferenceTest::c,(name)->ne[...]ma())
reason: inferred type does not conform to upper bound(s)
inferred: InferenceTest.Builder<InferenceTest.Alfa>
upper bound(s): InferenceTest.Builder<InferenceTest.Alfa>,InferenceTest.Builder<? extends InferenceTest.Beta>
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.function.Function;
import java.util.function.Supplier;
public class InferenceTest {
public static void main(String[] args) {
//compile error
InferenceTest.a(
InferenceTest::c,
name -> new Builder<>(new Gamma()));
//successfully compiles
InferenceTest.b(
InferenceTest::c,
() -> new Builder<>(new Gamma()));
}
static <T extends Alfa, B extends Builder<T>> void a(
final Function<B, String> f1,
final Function<String, B> f2) {
}
static <T extends Alfa, B extends Builder<T>> void b(
final Function<B, String> f1,
final Supplier<B> s1) {
}
private static String c(final Builder<? extends Beta> builder){return "";}
public static class Alfa {}
public static class Beta extends Alfa {}
public static class Gamma extends Beta {}
public static class Builder<T> {
private final T t;
public Builder(T t) {
this.t = t;
}
}
}
---------- END SOURCE ----------