Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 405706 - Eclipse compiler fails to give compiler error when return type is a inferred generic
Summary: Eclipse compiler fails to give compiler error when return type is a inferred ...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.2.1   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 4.3 M7   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-04-15 06:29 EDT by Piotr Findeisen CLA
Modified: 2013-04-30 06:16 EDT (History)
2 users (show)

See Also:


Attachments
TypeUnsafe class (328 bytes, application/octet-stream)
2013-04-15 06:29 EDT, Piotr Findeisen CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Piotr Findeisen CLA 2013-04-15 06:29:08 EDT
Created attachment 229715 [details]
TypeUnsafe class

Steps to reproduce
 * using Eclipse Indigo SR2 or Eclipse Juno SR1
 * compile the following code

----------------------------------------------------------------------
import java.util.Collection;

public class TypeUnsafe {
	public static <Type,
			CollectionType extends Collection<Type>>
			CollectionType
			nullAsCollection(Class<Type> clazz) {
		return null;
	}

	public static void main(String[] args) {
		Collection<Integer> integers = nullAsCollection(String.class);
	}
}
----------------------------------------------------------------------

Expected
 * compilation *error* like the one below, produced by javac 1.7.0_09

----------------------------------------------------------------------
TypeUnsafe.java:13: error: invalid inferred types for CollectionType; inferred type does not conform to declared bound(s)
                Collection<Integer> integers = nullAsCollection(String.class);
                                                               ^
    inferred: Collection<Integer>
    bound(s): Collection<String>
  where CollectionType,Type are type-variables:
    CollectionType extends Collection<Type> declared in method <Type,CollectionType>nullAsCollection(Class<Type>)
    Type extends Object declared in method <Type,CollectionType>nullAsCollection(Class<Type>)
1 error
----------------------------------------------------------------------

Observed
 * code compiles without error or warning
Comment 1 Jay Arthanareeswaran CLA 2013-04-15 06:39:06 EDT
Stephan, please take a look, thanks!
Comment 2 Sebastian Zarnekow CLA 2013-04-15 07:40:45 EDT
I can confirm that the problem is still present in the latest milestone of Kepler.
Comment 3 Stephan Herrmann CLA 2013-04-15 21:43:12 EDT
ecj up-to 3.7 reports:

Bound mismatch: The generic method nullAsCollection(Class<Type>) of type TypeUnsafe is not applicable for the arguments (Class<String>). The inferred type Collection<Integer> is not a valid substitute for the bounded parameter <CollectionType extends Collection<Type>>


Unfortunately, 3.7.1 was a big change (introducing Java 7 support).
Comment 4 Stephan Herrmann CLA 2013-04-18 09:31:08 EDT
Regression seems to be caused by the fix for bug 341795.

Before that, the method was inferred to 
  Type=String
  CollectionType=Collection<Integer>
with that fix we get:
  Type=String
  CollectionType=Collection<Integer>&Collection<String>

In the former case boundCheck on the second type variable would yield mismatch.
In the latter case we no longer get that mismatch.

Either the fix in bug 341795 needs to be more cautious to prevent creating
empty intersection types, or boundCheck should detect this unsatisfiable
"solution".
Comment 5 Stephan Herrmann CLA 2013-04-18 10:28:52 EDT
Refusing to create unsatisfiable intersection types seems to do the trick.
Now we only need a precise definition of "unsatisfiable intersection type".
For this bug I'll focus on incompatibility due to type arguments.
Comment 6 Stephan Herrmann CLA 2013-04-18 12:10:29 EDT
I couldn't find any rule in the JLS that would help me, but using the
following rules we can fix this bug without causing any regressions in
our tests:

The glb of a set of types is invalid (signalled by null) if for any pair
of types:
1. the types themselves are not compatible in either direction.
2. both types are parameterized types
3. the original of one type is compatible to the original of the other

I interpret the conjunction of 1-3 as indication that types are incompatible
due to mismatching type arguments, which is exactly the thing we need to
detect for this bug.

I had been playing also with isProvablyDistinct for 1., but couldn't find
a clear indication which is better.
Comment 7 Stephan Herrmann CLA 2013-04-18 13:00:18 EDT
Released for 4.3 M7 via commit 57dec4f97ab62d03709eb0f38c04abeae05153fc
Comment 8 Jay Arthanareeswaran CLA 2013-04-30 06:16:24 EDT
Verified for 4.3 M7 with build I20130428-2000