Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 348956 - [1.7] ITypeBinding#isAssignmentCompatible(ITypeBinding) returns different result
Summary: [1.7] ITypeBinding#isAssignmentCompatible(ITypeBinding) returns different result
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.7.1   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 347426
Blocks:
  Show dependency tree
 
Reported: 2011-06-09 16:21 EDT by Markus Keller CLA
Modified: 2011-08-05 02:54 EDT (History)
3 users (show)

See Also:


Attachments
Patch under consideration (2.19 KB, patch)
2011-06-17 02:21 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Patch under consideration (2.11 KB, patch)
2011-06-17 03:13 EDT, Srikanth Sankaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2011-06-09 16:21:43 EDT
BETA_JAVA7

The fix for 347426 makes our TypeEnvironmentTests#testCaptureAssignments() fail.

The test tests ITypeBinding#isAssignmentCompatible(ITypeBinding) with bindings from here:

package xy;

import java.util.ArrayList;
import java.util.List;

public class Try15 {
	void m(List<?> list) {
		list= new ArrayList<List<? extends String>>();
		list= new ArrayList<String>();
	}
}

If you take the resolved type binding of the first ClassInstanceCreation as 'this' and the resolved type binding of the Assignment node as the argument, then isAssignmentCompatible(..) used to return false but now returns true.

The question is whether an ArrayList<List<? extends String>> can be assigned to a List<capture-of ?>. I couldn't find a way to express this test in source code, but the new behavior of the API feels wrong.

When you do the same test with second ClassInstanceCreation, then isAssignmentCompatible(..) still returns false (can't assign ArrayList<String> to List<capture-of ?>). This shows that the API is inconsistent now.

In the ASTView, you can see the difference with these steps:
- select type binding of first Assignment node
- context menu > Add to Comparison Tray
- select the type bindings of a ClassInstanceCreation node
Comment 1 Markus Keller CLA 2011-06-09 16:23:52 EDT
D'oh! Must learn to write "bug" in front of bug number: Bug 347426.
Comment 2 Srikanth Sankaran CLA 2011-06-12 22:18:32 EDT
(In reply to comment #0)
> BETA_JAVA7
> 
> The fix for 347426 makes our TypeEnvironmentTests#testCaptureAssignments()
> fail.

Markus, thanks for the report. Is it known if this is the only failure
in your test suite caused at this point by JDT/Core changes ?
Comment 3 Deepak Azad CLA 2011-06-12 22:22:47 EDT
(In reply to comment #2)
> Markus, thanks for the report. Is it known if this is the only failure
> in your test suite caused at this point by JDT/Core changes ?

Yes.
Comment 4 Srikanth Sankaran CLA 2011-06-12 22:31:13 EDT
(In reply to comment #3)
> (In reply to comment #2)
> > Markus, thanks for the report. Is it known if this is the only failure
> > in your test suite caused at this point by JDT/Core changes ?
> 
> Yes.

Is it yes and yes ? :) Thanks.
Comment 5 Deepak Azad CLA 2011-06-12 22:44:36 EDT
This is the only failure in JDT/UI in BETA_JAVA7 branch at this point :)
Comment 6 Srikanth Sankaran CLA 2011-06-14 05:55:25 EDT
Released (disabled) junit org.eclipse.jdt.core.tests.dom.ASTConverter15Test._test0353() embodying
the comment#0 scenario.

Passes on HEAD and fails on JAVA7 branch along the lines described in
comment# 0.

Under investigation.
Comment 7 Markus Keller CLA 2011-06-14 09:21:49 EDT
More precisely, there's just 1 failing test in JDT/UI. The test creates a bunch of bindings and then compares the TTypes results with the ITypeBinding results for all combinations.

The given case is just the first difference that makes the test fail. To see all discrepancies, change the body of TypeEnvironmentTests#checkCanAssignTo(..) to:

	boolean coreResult= rhsBinding.isAssignmentCompatible(lhsBinding);
	boolean uiResult= rhs.canAssignTo(lhs);
//		assertEquals("Different assignment rule(" +
//			PrettySignatures.get(lhsBinding) +
//			"= " + PrettySignatures.get(rhsBinding) +
//			"): ", coreResult, uiResult);
	
	// see bug 348956
	if (coreResult != uiResult) {
		System.out.println("Different assignment rule(" +
			PrettySignatures.get(lhsBinding) +
			"= " + PrettySignatures.get(rhsBinding) +
			"): Bindings<" + coreResult +
			"> TType<" + uiResult + ">");
	}

There are 12 differences, but all of them have a variable of type Collection or List<capture-of ? ...> and a List<List<...>> or a List<ArrayList<...>> as RHS.
Comment 8 Srikanth Sankaran CLA 2011-06-17 02:21:28 EDT
Created attachment 198158 [details]
Patch under consideration


Looking at the fix for bug 347426, we are on something of a slippery
slope there, this being an underspecified area and having to track the
reference compiler instead which has changed its mind once going from
JDK5 to JDK6 and yet again from JDK6 to JDK7.

At the moment, I have simply tightened the fix for bug 347426 to avoid
side effects: So, given class A<T extends B<?>>, we recognize that A<?>
cannot be the universe of all parameterizations of A, but only those
that also comform to the bounds specified, while for given class A<T>,
A<?> can be. 

Deepak, Can I request you to run TypeEnvironmentTests#testCaptureAssignments
and if that passes, then to run all tests and report any issues here ? TIA.
Comment 9 Deepak Azad CLA 2011-06-17 02:43:02 EDT
(In reply to comment #8)
> Created attachment 198158 [details] [diff]
> Patch under consideration
Srikanth, with this patch there are 4 differences

- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.List<? extends java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.ArrayList<java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.List<? extends java.lang.Object>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.List<java.lang.String>>): Bindings<true> TType<false>

The original 12 differences for reference
- Different assignment rule(java.util.List<capture-of ?>= java.util.List<java.util.List<? extends java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.List<? extends java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.Collection<capture-of ?>= java.util.List<java.util.List<? extends java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ?>= java.util.List<java.util.ArrayList<java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.ArrayList<java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.Collection<capture-of ?>= java.util.List<java.util.ArrayList<java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ?>= java.util.List<java.util.List<? extends java.lang.Object>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.List<? extends java.lang.Object>>): Bindings<true> TType<false>
- Different assignment rule(java.util.Collection<capture-of ?>= java.util.List<java.util.List<? extends java.lang.Object>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ?>= java.util.List<java.util.List<java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.List<capture-of ? extends java.lang.Object>= java.util.List<java.util.List<java.lang.String>>): Bindings<true> TType<false>
- Different assignment rule(java.util.Collection<capture-of ?>= java.util.List<java.util.List<java.lang.String>>): Bindings<true> TType<false>
Comment 10 Srikanth Sankaran CLA 2011-06-17 03:13:25 EDT
Created attachment 198160 [details]
Patch under consideration

Is this patch better ?
Comment 11 Deepak Azad CLA 2011-06-17 03:24:03 EDT
(In reply to comment #10)
> Created attachment 198160 [details] [diff]
> Patch under consideration
> 
> Is this patch better ?

Yes, it is! TypeEnvironmentTests#testCaptureAssignments passes with this patch.
Comment 12 Srikanth Sankaran CLA 2011-06-17 05:06:40 EDT
Passes all JDT/Core tests including the enabled regression test.
Comment 13 Deepak Azad CLA 2011-06-17 08:51:17 EDT
All JDT/UI tests also pass.
Comment 14 Srikanth Sankaran CLA 2011-06-17 09:00:46 EDT
Thanks Deepak. Patch and test released in BETA_JAVA7 branch.

I'll continue to test this area some more, as admittedly this is
a bit of tinker - any issues discovered will be addressed via
follow up defects.
Comment 15 Satyam Kandula CLA 2011-07-01 08:48:56 EDT
Verified using Eclipse Java 7 Support(Beta) feature patch v20110623-0900.