JDK-8034223 : Most-specific should not have any special treatment for boxed vs. unboxed types
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-02-11
  • Updated: 2017-05-17
  • Resolved: 2014-05-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u20Fixed 9 b14Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
The following compiles with javac 8 b121:

static void m(Object dummy, int arg) { System.out.println("int"); }
static void m(Object dummy, Integer arg) { System.out.println("Integer"); }

public static void main(String... args) {
  m(0, 23);
  m(0, Integer.valueOf(23));
}

(The first invocation prints "int"; the second prints "Integer".)

This was an experimental feature in Lambda that we ultimately agreed to undo for 8.  The return expressions of _lambdas_ should continue to get special treatment, but a top-level argument should not.  The only mechanism for treating one parameter type as better than another in this case should be subtyping.
Comments
TCK tests added: lang/LMBD/lmbd134/lmbd13402m03/lmbd13402m03.html lang/LMBD/lmbd134/lmbd13402m04/lmbd13402m04.html lang/LMBD/lmbd134/lmbd13402m05/lmbd13402m05.html lang/LMBD/lmbd134/lmbd13402m06/lmbd13402m06.html lang/LMBD/lmbd134/lmbd13402m1/lmbd13402m1.html lang/LMBD/lmbd134/lmbd13402m13/lmbd13402m13.html lang/LMBD/lmbd134/lmbd13402m14/lmbd13402m14.html lang/LMBD/lmbd134/lmbd13402m15/lmbd13402m15.html lang/LMBD/lmbd134/lmbd13402m16/lmbd13402m16.html lang/LMBD/lmbd134/lmbd13402m2/lmbd13402m2.html lang/LMBD/lmbd134/lmbd13402m22/lmbd13402m22.html lang/LMBD/lmbd134/lmbd13402m23/lmbd13402m23.html lang/LMBD/lmbd134/lmbd13402m24/lmbd13402m24.html lang/LMBD/lmbd134/lmbd13402m25/lmbd13402m25.html lang/LMBD/lmbd134/lmbd13402m26/lmbd13402m26.html lang/LMBD/lmbd134/lmbd13402m3/lmbd13402m3.html lang/LMBD/lmbd134/lmbd13402m31/lmbd13402m31.html lang/LMBD/lmbd134/lmbd13402m32/lmbd13402m32.html lang/LMBD/lmbd134/lmbd13402m33/lmbd13402m33.html lang/LMBD/lmbd134/lmbd13402m34/lmbd13402m34.html lang/LMBD/lmbd134/lmbd13402m35/lmbd13402m35.html lang/LMBD/lmbd134/lmbd13402m36/lmbd13402m36.html lang/LMBD/lmbd134/lmbd13402m4/lmbd13402m4.html lang/LMBD/lmbd134/lmbd13402m41/lmbd13402m41.html lang/LMBD/lmbd134/lmbd13402m42/lmbd13402m42.html lang/LMBD/lmbd134/lmbd13402m43/lmbd13402m43.html lang/LMBD/lmbd134/lmbd13402m44/lmbd13402m44.html lang/LMBD/lmbd134/lmbd13402m45/lmbd13402m45.html lang/LMBD/lmbd134/lmbd13402m46/lmbd13402m46.html lang/LMBD/lmbd134/lmbd13402m5/lmbd13402m5.html lang/LMBD/lmbd134/lmbd13402m51/lmbd13402m51.html lang/LMBD/lmbd134/lmbd13402m52/lmbd13402m52.html lang/LMBD/lmbd134/lmbd13402m53/lmbd13402m53.html lang/LMBD/lmbd134/lmbd13402m54/lmbd13402m54.html lang/LMBD/lmbd134/lmbd13402m55/lmbd13402m55.html lang/LMBD/lmbd134/lmbd13402m56/lmbd13402m56.html lang/LMBD/lmbd134/lmbd13402m6/lmbd13402m6.html lang/LMBD/lmbd134/lmbd13402m61/lmbd13402m61.html lang/LMBD/lmbd134/lmbd13402m62/lmbd13402m62.html lang/LMBD/lmbd134/lmbd13402m63/lmbd13402m63.html lang/LMBD/lmbd134/lmbd13402m64/lmbd13402m64.html lang/LMBD/lmbd134/lmbd13402m65/lmbd13402m65.html lang/LMBD/lmbd134/lmbd13402m66/lmbd13402m66.html lang/LMBD/lmbd134/lmbd13403m0/lmbd13403m0.html lang/LMBD/lmbd134/lmbd13403m01/lmbd13403m01.html lang/LMBD/lmbd134/lmbd13403m02/lmbd13403m02.html lang/LMBD/lmbd134/lmbd13403m03/lmbd13403m03.html lang/LMBD/lmbd134/lmbd13403m04/lmbd13403m04.html lang/LMBD/lmbd134/lmbd13403m05/lmbd13403m05.html lang/LMBD/lmbd134/lmbd13403m06/lmbd13403m06.html lang/LMBD/lmbd134/lmbd13403m1/lmbd13403m1.html lang/LMBD/lmbd134/lmbd13403m11/lmbd13403m11.html lang/LMBD/lmbd134/lmbd13403m12/lmbd13403m12.html lang/LMBD/lmbd134/lmbd13403m13/lmbd13403m13.html lang/LMBD/lmbd134/lmbd13403m14/lmbd13403m14.html lang/LMBD/lmbd134/lmbd13403m15/lmbd13403m15.html lang/LMBD/lmbd134/lmbd13403m16/lmbd13403m16.html lang/LMBD/lmbd134/lmbd13403m2/lmbd13403m2.html lang/LMBD/lmbd134/lmbd13403m21/lmbd13403m21.html lang/LMBD/lmbd134/lmbd13403m22/lmbd13403m22.html lang/LMBD/lmbd134/lmbd13403m23/lmbd13403m23.html lang/LMBD/lmbd134/lmbd13403m24/lmbd13403m24.html lang/LMBD/lmbd134/lmbd13403m25/lmbd13403m25.html lang/LMBD/lmbd134/lmbd13403m26/lmbd13403m26.html lang/LMBD/lmbd134/lmbd13403m3/lmbd13403m3.html lang/LMBD/lmbd134/lmbd13403m31/lmbd13403m31.html lang/LMBD/lmbd134/lmbd13403m32/lmbd13403m32.html lang/LMBD/lmbd134/lmbd13403m33/lmbd13403m33.html lang/LMBD/lmbd134/lmbd13403m34/lmbd13403m34.html lang/LMBD/lmbd134/lmbd13403m35/lmbd13403m35.html lang/LMBD/lmbd134/lmbd13403m36/lmbd13403m36.html lang/LMBD/lmbd134/lmbd13402m12/lmbd13402m12.html lang/LMBD/lmbd134/lmbd13402m11/lmbd13402m11.html lang/LMBD/lmbd134/lmbd13402m21/lmbd13402m21.html
07-08-2014

And another bug that is fixed by the rewrite in the patch: interface UnaryOp<T> { T apply(T arg); } interface IntegerToNumber { Number apply(Integer arg); } <T> void m(UnaryOp<T> f) {} void m(IntegerToNumber f) {} Integer id(Integer arg); void test() { m(this::id); // expected: error; actual: ok }
02-05-2014

And another bug found here (this is the TargetType16 test): interface SAM1 { void m1(); } interface SAM2<X> { X m2(); } static void m(SAM1 s1) { } static <T> void m(SAM2<T> s2) { } void test() { m(() -> { throw new AssertionError(); }); // expected: ok; actual: error } SAM2 is more specific than SAM1; but two things are going wrong here that make SAM1 also considered more specific than SAM2. First, if there are no return expressions in the lambda body, we never check 'void' for compatibility with 'T'. Second, if we _do_ make that check, inference infers 'T=void'.
18-03-2014

I discovered an additional bug in the same code: interface GetInt { int get(); } interface GetInteger { Integer get(); } void m(GetInt getter) {} void m(GetInteger getter) {} void test(boolean cond) { m(cond ? () -> 26 : () -> 24); // expected: ok; actual: error } The visitor accidentally recurs on the condition expression, not just the "true" and "false" expressions.
17-03-2014

Release team: Approved for deferral.
18-02-2014

Deferral justification: a corner case -- not prominent enough to justify holding up the release.
11-02-2014