JDK-7022054 : Invalid compiler error on covariant overriding methods with the same erasure
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2011-02-24
  • Updated: 2012-03-20
  • Resolved: 2011-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.
JDK 7
7 b134Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b130)
Java HotSpot(TM) Server VM (build 21.0-b02, mixed mode)


A DESCRIPTION OF THE PROBLEM :
Attached source code does not compile

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the attached source code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should compile
ACTUAL -
The code does not compile.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
name clash: <T>clone() in JavacBug and clone() in Superclass have the same erasure, yet neither overrides the other

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package bugs;

public abstract class JavacBug extends Superclass
{
	abstract <T extends JavacBug> T clone () throws CloneNotSupportedException;
}

class Superclass
{
	@Override
	public Superclass clone () throws CloneNotSupportedException
	{
		return (Superclass) super.clone ();
	}
}

---------- END SOURCE ----------

Comments
SUGGESTED FIX A webrev of this fix is available at the following URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/32565546784b
03-03-2011

EVALUATION This is a regression introduced by the new override clash logic. The algorithm in itself is perfectly fine and what it does is 100% covered by the JLS - however javac used to be a little bit more liberal in cases like the following: class A { A m(String s) { ... } } class B extends A { <X extends B> X m(String s) { ... } } For the JLS - section 8.4.2, B.m is not a subsigature of A.m - simply because they have different number of type-parameters - I think this is actually a bug in the spec, and that somehow, the JLS should be able to 'see' that those two methods indeed are override equivalent. But the spec curently doesn't, and the same does javac. More specifically, Types.isSubsignature returns false in this case - which means the checks I've recently implemented will give an error in this case (no override equivalent - same erasure). The fix is to 'conditionally' relax the check in Types.isSubsignature, by making it a little bit smarter in the case when a generic method is compared against a non-generic one. The tweaked version of the method is only called when performing the override clash, which leads to a behavior which is compatible with JDK 6 (and a bit different w.r.t. the JLS check described in 8.4.8.3 which relies on 'true' subsignature check which, however is too restrictive and doesn't work in this case).
03-03-2011