Bug 334493

Summary: [1.7][compiler] Difference in behavior with Javac7
Product: [Eclipse Project] JDT Reporter: Srikanth Sankaran <srikanth_sankaran>
Component: CoreAssignee: Srikanth Sankaran <srikanth_sankaran>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: amj87.iitr, Olivier_Thomann
Version: 3.5   
Target Milestone: 3.7 M7   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Proposed fix
none
Proposed fix none

Description Srikanth Sankaran CLA 2011-01-17 03:22:05 EST
HEAD.

On the following code, we issue an error:
"Cannot cast from S<Integer> to T". while
this matches javac5,6 behavior, javac7 (b123)
compiles this code fine. 

Needs to be investigated.
Comment 1 Srikanth Sankaran CLA 2011-01-17 03:22:51 EST
Test case:

interface Super<P> {}

class Y<C> implements Super<Integer>{}
interface II extends Super<Double>{}

class S<A> extends Y<Byte> {}
interface T<B> extends II{}

@SuppressWarnings("unchecked")
public class X {
	public static void main(String argv[]) {
		S<Integer> s = null;
		T<Integer> t = null;
		t = (T) s;          //casting to raw type, no error
		System.out.println(t);
	}
}
Comment 2 Olivier Thomann CLA 2011-03-03 12:16:56 EST
Targetting M7. This might be released only in the Java 7 branch and a research has to be done to see why this behavior has changed since 1.6.
I might have a patch, but I first need to see why it makes sense not to fail at compile time.
The new behavior means that some code can fail at runtime with a ClassCastException.
Comment 3 Olivier Thomann CLA 2011-03-09 09:20:32 EST
Created attachment 190755 [details]
Proposed fix

I am still investigating why this is allowed.
Comment 4 Olivier Thomann CLA 2011-03-30 12:22:04 EDT
In fact as long as the class S is not final, this is fine at compile time even if there is no obvious relationship between S and T. A subclass of S might implements T.
So this patch just makes the "generic" case consistent with non generic case.

Srikanth, I let you have a look at it. And we should release it soon.
Comment 5 Olivier Thomann CLA 2011-03-30 12:23:21 EDT
Created attachment 192207 [details]
Proposed fix

Just make sure the last version is used. Regression test will be required once the patch is fine.
Comment 6 Srikanth Sankaran CLA 2011-03-31 02:54:54 EDT
(In reply to comment #5)
> Created attachment 192207 [details]
> Proposed fix
> 
> Just make sure the last version is used. Regression test will be required once
> the patch is fine.

See sun bugs : 6542952 and 6559182. Agree with the analysis.
Olivier, shouldn't be the fix be restricted to the cast type
interfaces ? With that in mind, the second set of diffs look
incorrect to me. This change reconsidered, this looks good for
HEAD and JAVA7 branch.
Comment 7 Srikanth Sankaran CLA 2011-03-31 03:06:27 EDT
Regression test:

// https://bugs.eclipse.org/bugs/show_bug.cgi?id=334493 
public void test334493() {
	this.runNegativeTest(
		new String[] {
			"X.java",
			"interface Super<P> {}\n" +
			"class Y<C> implements Super<Integer>{}\n" +
			"interface II extends Super<Double>{}\n" +
			"class S<A> extends Y<Byte> {}\n" +
			"interface T<B> extends II{}\n" +
			"public class X {\n" +
			"    public static void main(String argv[]) {\n" +
			"        S<Integer> s = null;\n" +
			"        T<Integer> t = null;\n" +
			"        t = (T) s;          //casting to raw type, no error\n" +
			"        System.out.println(t);\n" +
			"    }\n" +
			"}\n"
		},
		this.complianceLevel < ClassFileConstants.JDK1_7 ?
		"----------\n" + 
		"1. ERROR in X.java (at line 10)\n" + 
		"	t = (T) s;          //casting to raw type, no error\n" + 
		"	    ^^^^^\n" + 
		"Cannot cast from S<Integer> to T\n" + 
		"----------\n" + 
		"2. WARNING in X.java (at line 10)\n" + 
		"	t = (T) s;          //casting to raw type, no error\n" + 
		"	    ^^^^^\n" + 
		"Type safety: The expression of type T needs unchecked conversion to conform to T<Integer>\n" + 
		"----------\n" : 
			"----------\n" + 
				"1. WARNING in X.java (at line 10)\n" + 
				"	t = (T) s;          //casting to raw type, no error\n" + 
				"	    ^^^^^\n" + 
				"Type safety: The expression of type T needs unchecked conversion to conform to T<Integer>\n" + 
				"----------\n" + 
				"2. WARNING in X.java (at line 10)\n" + 
				"	t = (T) s;          //casting to raw type, no error\n" + 
				"	     ^\n" + 
				"T is a raw type. References to generic type T<B> should be parameterized\n" + 
				"----------\n");
}
Comment 8 Srikanth Sankaran CLA 2011-03-31 04:38:04 EDT
(In reply to comment #6)

> Olivier, shouldn't be the fix be restricted to the cast type
> interfaces ? With that in mind, the second set of diffs look
> incorrect to me. 

Sorry, that was muddled thinking, patch looks good.

Patch and test released in HEAD for 3.7 M7
Comment 9 Ayushman Jain CLA 2011-04-26 07:06:55 EDT
Verified for 3.7M7 using build I20110425-1800.
Comment 10 Srikanth Sankaran CLA 2011-06-03 05:43:05 EDT
*** Bug 346051 has been marked as a duplicate of this bug. ***