Bug 209071 - [1.5][compiler] Obvious type errors with generic types not caught at compile time
Summary: [1.5][compiler] Obvious type errors with generic types not caught at compile ...
Status: VERIFIED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.4 M4   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-11-07 13:48 EST by Eric Bodden CLA
Modified: 2007-12-11 11:46 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Bodden CLA 2007-11-07 13:48:41 EST
Build ID: I20071016-1215

Try to compile this code...

Set<List> listSet = new HashSet<List>();
Set<List> otherListSet = new HashSet<List>();
otherListSet.add((List) listSet);

Set<String> stringSet = new HashSet<String>();
Set<String> otherStringSet = new HashSet<String>();
otherStringSet.add((String) stringSet);

The first block of code compiles fine but gives a runtime error, stating that Set<String> cannot be cast to String. The second does not compile, giving the same error at compile time.

Now what I don't understand: Why, in the case of a concrete type parameter (String) is the error reported statically but not in the case of an interface type parameter?

What I even understand less: javac seems to expose the same strange behavior... How can this not be a bug?
Comment 1 Philipe Mulet CLA 2007-11-22 04:23:59 EST
The difference comes from the fact that String is a final class, so statically the compiler can tell no better subtype may show up at runtime, hence the cast is refused at compile time.

For the first case, with interface, you could imagine the runtime object to be a subtype of Set which implements List, hence the cast would be legite.
In your example, we can easily spot that HashSet doesn't implement List, hence it could statically be doomed, but the compiler is not checking based on assigned values, only using declaring types.

So, by the spec, our behavior is fine.

Added GenericTypeTest#test1221
Closing as INVALID.
Comment 2 Eric Bodden CLA 2007-11-22 10:06:32 EST
Thanks, Philippe, for the explanation. However I still have one question:

(In reply to comment #1)
> In your example, we can easily spot that HashSet doesn't implement List, hence
> it could statically be doomed, but the compiler is not checking based on
> assigned values, only using declaring types.

Even in that case the cast should be invalid. The declared type is Set<List>, which certainly is not a subtype of List. So how can this cast succeed?
Comment 3 Philipe Mulet CLA 2007-11-23 09:14:04 EST
What if later at runtime the actual value to cast is of type X, where X implements both Set<List> and List ?
Comment 4 Eric Bodden CLA 2007-11-23 09:52:56 EST
(In reply to comment #3)
> What if later at runtime the actual value to cast is of type X, where X
> implements both Set<List> and List ?
> 

Ahh, now I got it. Thanks a lot for the clarification!
Comment 5 Kent Johnson CLA 2007-12-11 11:46:56 EST
Verified for 3.4M4 using build I20071210-1800.