Bug 282141 - [1.5][compiler] Raw type warning on instanceof
Summary: [1.5][compiler] Raw type warning on instanceof
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.5   Edit
Hardware: PC Windows Vista
: P3 minor with 1 vote (vote)
Target Milestone: 3.6 M7   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-07-01 08:04 EDT by Markus Heiden CLA
Modified: 2010-04-26 14:20 EDT (History)
6 users (show)

See Also:


Attachments
Plausible patch (6.33 KB, patch)
2010-03-31 06:22 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 Heiden CLA 2009-07-01 08:04:33 EDT
Build ID: 20090621-0832

Steps To Reproduce:
if (a instanceof Comparable) ...


More information:
In "if (a instanceof Comparable) ..." there is a warning for Comparable to be a raw type. Because of the type erasure one cannot fix this problem: "if (a instanceof Comparable<X>) ..." is not allowed. I suggest to not generate warnings in this case, because type safety is not the problem here.
Comment 1 Rémi Forax CLA 2009-07-16 17:00:26 EDT
This bug is a dup of 252120 :
https://bugs.eclipse.org/bugs/show_bug.cgi?id=252120

Rémi
Comment 2 Mauro Molinari CLA 2009-07-23 09:47:17 EDT
I think it is not a really duplicate of #252120 because it says that the fix for that bug introduced this one.

I think this is actually a bug: I can't understand why:
a instanceof Comparable
should be identified as an error/warning. The test is about the runtime type of a, which has nothing to do with generics. So, the expression
a instanceof Comparable<?>
sounds even wrong to me.
Comment 3 Mauro Molinari CLA 2009-07-23 09:49:02 EDT
Also, there's no option to disable this new warning (which was not present in Ganymede)! :-((
Comment 4 Rémi Forax CLA 2009-07-23 09:57:07 EDT
(In reply to comment #2)
> I think it is not a really duplicate of #252120 because it says that the fix
> for that bug introduced this one.
> 
> I think this is actually a bug: I can't understand why:
> a instanceof Comparable
> should be identified as an error/warning. The test is about the runtime type of
> a, which has nothing to do with generics. So, the expression
> a instanceof Comparable<?>
> sounds even wrong to me.
> 

instanceof needs a reified type (JLS3 15.20.2),
Comparable<?> is a reified type, so a instanceof Comparable<?>
is not wrong.

Now, the warning is about raw type, Comparable is a raw type,
so the eclipse compiler should raise a warning.

Please also note that javac raises a warning in that case too.

Rémi
Comment 5 Mauro Molinari CLA 2009-07-23 10:43:00 EDT
(In reply to comment #4)
> instanceof needs a reified type (JLS3 15.20.2),
> Comparable<?> is a reified type, so a instanceof Comparable<?>
> is not wrong.

Comparable (raw) is a reified type, too, so "a instanceof Comparable" is not an error either. And, in this particular case, it isn't either a potential error.

> Now, the warning is about raw type, Comparable is a raw type,
> so the eclipse compiler should raise a warning.

A warning should warn the user that he is doing something "risky" or something that could lead to a problem not identifiable by the compiler, shouldn't it? Otherwise it wouldn't be called "warning"...

So, which risky operation am I doing by typing "a instanceof Comparable" that Eclipse is warning me about? Which error may lead me to do?

> Please also note that javac raises a warning in that case too.

javac of Java 5 and javac of Java 6 do not give any warning. Anyway, even if javac of Java 7 does, IMHO this is not a good reason for which Eclipse compiler shouldn't be "smarter". So, the best way to handle this could be:
- disable by default the warning for 1.5 and 1.6 compiler compliance levels
- enable, if you want, by default the warning for 1.7 compiler compliance level, but leave the user the oportunity to disable it.
Comment 6 T. Orf CLA 2009-11-27 10:20:56 EST
I'd also like to disable that warning.

In his book Effective Java, Bloch calls the use of the raw type in instanceof "legitimate" and the "preferred way".
Comment 7 Will Horn CLA 2010-03-16 18:04:56 EDT
Is this a dup of http://bugs.eclipse.org/259378 which was closed as WONTFIX?
Comment 8 Mauro Molinari CLA 2010-03-17 04:43:17 EDT
Maybe, but the existance of this demonstrates that this topic is still subject for discussion...
Comment 9 Srikanth Sankaran CLA 2010-03-31 02:08:04 EDT
After reviewing the discussion in this defect as well as
bug#252120 and bug#259378 and going through the blog entry
that discusses the original javac side implementor's thoughts,
I am personally inclined to suppress this raw type usage warning
in the case of instanceof. IMO, depending upon one's viewpoint,
this warning is either ultra pedantic or ultra nitpicking in
nature and serves no practical purpose. 

I also don't see any value/worth to adding an option and exposing
it to the user.

It is worth noting that the javac developer mentions that he is
collecting a list of proposals for places where the raw types
warning should be automatically suppressed and the instanceof
check is one of them.

Olivier, if there is agreement, I'll work on a patch to take this
forward.
Comment 10 Srikanth Sankaran CLA 2010-03-31 06:22:11 EDT
Created attachment 163510 [details]
Plausible patch
Comment 11 Rémi Forax CLA 2010-03-31 06:38:58 EDT
(In reply to comment #10)
> Created an attachment (id=163510) [details]
> Plausible patch

I don't agree with the idea to not generate a warning.
Currently, because generics aren't reified,
instanceof Foo and instanceof Foo<?> are equivalent.

But this is no more true if generics are reified.

Example, if Foo is declared like this:
class Foo<T> {

}

instanceof Foo is equivalent to instanceof Foo<?>.

now suppose that I modify Foo as below and
forget to recompile the code creating a Foo<String>.

class Foo<T extends Number> { }

now the two instanceof haven't the same semantics:

instanceof Foo     // no problem
instanceof Foo<?>  // should raise an IncompatibleClassChangeError

Rémi
Comment 12 Srikanth Sankaran CLA 2010-03-31 08:10:51 EDT
(In reply to comment #11)
> (In reply to comment #10)

[...]

> I don't agree with the idea to not generate a warning.
> Currently, because generics aren't reified,
> instanceof Foo and instanceof Foo<?> are equivalent.
> 
> But this is no more true if generics are reified.

My personal take is to put the horse firmly ahead of
the cart and cross the bridge when we get to it.

That said I am ok with letting sleeping dogs lie (status quo)
or letting there be different strokes for different folks
(i.e expose an option)

(Trying hard not to mix up my metaphor :-))
Comment 13 Mauro Molinari CLA 2010-03-31 08:16:07 EDT
> instanceof Foo     // no problem
> instanceof Foo<?>  // should raise an IncompatibleClassChangeError

I'm not a theory/compiler expert, but it would surprise me to have an "IncompatibleClassChangeError" here. AFAIK, generics are resolved at compile time, so once erased the two expressions should be equivalent, shouldn't them? 

Anyway, I still can't find any harm of using "instanceof Foo" instead of "instanceof Foo<?>". First of all because in most cases I would prefer the first choice (i.e. no errors), since I'm testing the runtime type of an object and, if my code is safe, I shouldn't do any further assumption on the generic type parameter. Secondly, even if the second expression gives an error that the first wouldn't highlight, if in the first case I do the assumption that <?> could be <String> and I don't recompile, I would have a ClassCastException somewhere else. So, two "equivalent" runtime errors.

Why should "instanceof Foo<?>" be more safe then? Because it may remember me (only at runtime) that I did a *potentially* incompatible change on a class declaration, rather than having a ClassCastException telling me I *really* did that?

Mauro.
Comment 14 Olivier Thomann CLA 2010-03-31 09:36:55 EDT
(In reply to comment #9)
> Olivier, if there is agreement, I'll work on a patch to take this
> forward.
I don't see what the warning really adds right now. So I don't mind if we suppress the warning in this case.
Comment 15 Srikanth Sankaran CLA 2010-04-13 02:25:25 EDT
Released in HEAD for 3.6M7
Comment 16 Olivier Thomann CLA 2010-04-26 14:14:58 EDT
(In reply to comment #11)
> I don't agree with the idea to not generate a warning.
> Currently, because generics aren't reified,
> instanceof Foo and instanceof Foo<?> are equivalent.
> But this is no more true if generics are reified.
This will be revisited once this is done.
Comment 17 Olivier Thomann CLA 2010-04-26 14:20:09 EDT
Verified for 3.6M7 using I20100425-2000