JDK-7144506 : Attr.checkMethod should be called after inference variables have been fixed
  • Type: Sub-task
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: unknown
  • Submitted: 2012-02-10
  • Updated: 2016-01-22
  • Resolved: 2012-04-20
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.
8 b30Fixed
Related Reports
Relates :  
Relates :  
Relates :  
The method check routine Attr.checkMethod is called when inference variables are still around; by doing so - it is sometimes possible to get spurious diagnostics containing inference variables.

After this patch programs like: --------------------------------------------------------------------------------------------- import java.util.List; class ReproOne { static class Baz<T> { public static List<Baz<Object>> getElements(Baz<Object> transcoder) { return null; } } private static void bar(Baz arg) { Baz element = Baz.getElements(arg).get(0); } } //based on a code provided by cushon@google.com at compiler-dev list ------------------------------------------------------------------------------------- which is accepted with warnings by javac 7, are not accepted anymore by javac 8. The javac 8 output for this code is: ReproOne.java:12: error: incompatible types: Object cannot be converted to Baz Baz element = Baz.getElements(arg).get(0); ^ Note: ReproOne.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error What is happening here is that a raw type is being passed to the getElements(Baz<Object>) method which is applicable by subtyping (see the JLS, Java SE 7 Edition, section, so an unchecked conversion is necessary for the method to be applicable, so it's return type is erased (see the JLS, Java SE 7 Edition, section, in this case the return type of getElements(Baz<Object>) will be java.util.List instead of java.util.List<Baz<Object>> and thus the return type of get(int) will be Object which is not assignment-compatible with Baz. The original discussion and more examples can be found at: http://mail.openjdk.java.net/pipermail/compiler-dev/2013-October/007726.html

SUGGESTED FIX A webrev of this fix is available at the following URL: http://hg.openjdk.java.net/jdk8/tl/langtools/rev/48ee63caaa93

EVALUATION Attr.checkMethod is a routine that gets called at the end of a successful overload resolution process - when a most specific method has been found. Since the routine internally uses the method applicability check routine to retrieve a method type, there can be three cases: *) the method is a non-generic method - no inference variable is around and the check method routine can be applied here *) method is a generic method - all inference variables have been fixed as a result of (during method applicability check) - again, since in the resulting method type there are no inference variables, it is safe to peform ithe checks in checkMethod() *) method is a generic method - there are some uninferred variables that needs to be fixed by looking at the expecetd type. In this case we should defer the checks in Attr.checkMethod until such variables are fixed. Note that in the case of (3), we already do something inside Infer.instantiateMethod to add some deferred checking after all inference variables have been fixed - so it's simply matter of splitting the existing checkMethod routine into two parts, and have Infer.instantiateMethod call the second part once all inference variables have been fixed.