Bug 89529 - [plan][1.5][compiler] improve warnings for raw types
Summary: [plan][1.5][compiler] improve warnings for raw types
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M3   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 98491 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-03-30 08:27 EST by Martin Aeschlimann CLA
Modified: 2006-10-03 06:19 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Aeschlimann CLA 2005-03-30 08:27:38 EST
20050329

When using this 1.4 code with 5.0 JRE and 5.0 compliance you get warnings that
are more confusing than helping:
1       ArrayList ar = new ArrayList();
2       while ((line = br.readLine()) != null)
3           ar.add(line);     << Type safety: The method add(Object) belongs to
                                 the raw type ArrayList. References to generic 
                                 type ArrayList<E> should be parameterized

What is the problem of using add(Object) when ArrayList is raw? How should I
make  parametrized reference at this point?

IMO the problem is line 1, the declaration that uses ArrayList raw. It would be
more helpful to warn on line 1:
'References to generic type ArrayList<E> should be parameterized'

In code with 5.0 compliance it is bad style to use raw types. But once you
really want to use a raw type, using it's raw methods is not a problem.

This would be a style warning, and should not be mixed with type safety warning.
Comment 1 Philipe Mulet CLA 2005-04-07 09:26:17 EDT
Deferring post 3.1
Comment 2 Philipe Mulet CLA 2005-09-26 03:58:52 EDT
Reopening for consideration.
Comment 3 Philipe Mulet CLA 2005-09-26 04:00:50 EDT
Proposing extra compiler warning:
* COMPILER / Reporting Raw Type Reference
*    When enabled, the compiler will signal references to raw types.
*    The severity of the problem is controlled with option
"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation".
*     - option id:         "org.eclipse.jdt.core.compiler.problem.rawTypeReference"
*     - possible values:   { "enabled", "disabled" }
*     - default:           "disabled"

This actually considers it as some type safety issue, making it super sensitive. 
Martin - why did you think this has nothing to do with type safety warnings ?
Comment 4 Martin Aeschlimann CLA 2005-09-26 04:25:19 EDT
Depends on what you think is the 'reference to a raw type'.

What I suggested is that we should warn whenever you have a raw type in a
declaration e.g. a variable declaration, but not anymore when you use such a
variable.

ArrayList a= new ArrayList<String>();
a.add(x);
a.add(y);

The problem is here is the first line, the user shouldn't use 'ArrayList', but
add parameterization. -> Warning at 'ArrayList': References to generic 
                                 type ArrayList<E> should be parameterized
Add warnings at a.put(x) is just confusing, as there's nothing you can change
with the access after the 'unprecice' declaration.

Comment 5 Philipe Mulet CLA 2005-09-26 04:57:57 EDT
Warnings on #add(...) are mandated by the JLS 3rd edition, when unchecked
warnings are to be detected (-Xlint:unchecked).

We are offering extra warnings on explicit raw type references (ArrayList a =
...), which are likely the primary cause for the subsequent unchecked warnings.

Will currently disable this extra diagnostic by default, but may reconsider once
we start using it.
Comment 6 Philipe Mulet CLA 2005-09-27 04:38:08 EDT
*** Bug 98491 has been marked as a duplicate of this bug. ***
Comment 7 Martin Aeschlimann CLA 2005-10-04 05:57:23 EDT
Note that I added the UI for the new option to I20051004
Comment 8 Markus Keller CLA 2005-10-05 10:34:45 EDT
I don't think it's a good idea to subsume the new "reference to raw type"
warning as part of the JLS3 unchecked warnings. Let's take this example:

    void m(Collection<Integer> input) {
        List raw= new ArrayList(input);
        raw.add(null);
    }

With the new -warn:+allUnchecked option enabled, I20051004-0800 issues
additional type safety warnings:
----------
1. WARNING in C:\e\w\development\zz1.5\src\xy\Try.java
 (at line 9)
	List raw= new ArrayList(input);
	^^^^
Type safety: List is a raw type. References to generic type List<E> should be
parameterized
----------
...
----------
3. WARNING in C:\e\w\development\zz1.5\src\xy\Try.java
 (at line 9)
	List raw= new ArrayList(input);
	              ^^^^^^^^^
Type safety: ArrayList is a raw type. References to generic type ArrayList<E>
should be parameterized
----------

But those references are not type safety problems (in contrast to JLS3's
unchecked warnings, which could be the source of type safety problems).

Therefore, I think the "reference to raw type" option should be completely
separate from the "unchecked type operation" option. It shoould also not
generate messages that start with "Type Safety:", but rather start with
something more neutral like "Raw Type:".
Comment 9 Philipe Mulet CLA 2005-10-10 11:04:50 EDT
Agreed. Tuned compiler implementation to make it a separate problem, as it makes
more sense there. Note that I left @SuppressWarnings("unchecked") silencing
these as well, as we want to minimize the amount of warning tokens.
Comment 10 Markus Keller CLA 2005-10-11 08:18:41 EDT
Cool. I agree that @SuppressWarnings("unchecked") should suppress both problems.

Opened bug 112190, since "-warn:+allUnchecked" does not work any more.
Comment 11 Martin Aeschlimann CLA 2005-10-11 08:21:51 EDT
The UI has also been updated for I20051011
Comment 12 Olivier Thomann CLA 2005-10-28 13:45:55 EDT
(In reply to comment #8)
> I don't think it's a good idea to subsume the new "reference to raw type"
> warning as part of the JLS3 unchecked warnings. Let's take this example:
> 
>     void m(Collection<Integer> input) {
>         List raw= new ArrayList(input);
>         raw.add(null);
>     }
> 
> With the new -warn:+allUnchecked option enabled, I20051004-0800 issues
> additional type safety warnings:
> ----------
> 1. WARNING in C:\e\w\development\zz1.5\src\xy\Try.java
>  (at line 9)
> 	List raw= new ArrayList(input);
> 	^^^^
> Type safety: List is a raw type. References to generic type List<E> should be
> parameterized
> ----------
> ...
> ----------
> 3. WARNING in C:\e\w\development\zz1.5\src\xy\Try.java
>  (at line 9)
> 	List raw= new ArrayList(input);
> 	              ^^^^^^^^^
> Type safety: ArrayList is a raw type. References to generic type ArrayList<E>
> should be parameterized
> ----------

We know report:
----------
1. WARNING in D:\tests_sources\X.java
 (at line 5)
	List raw= new ArrayList(input);
	^^^^
List is a raw type. References to generic type List<E> should be parameterized
----------
2. WARNING in D:\tests_sources\X.java
 (at line 5)
	List raw= new ArrayList(input);
	          ^^^^^^^^^^^^^^^^^^^^
Type safety: The constructor ArrayList(Collection) belongs to the raw type
ArrayList. References to generic type ArrayList<E> should be parameterized
----------
3. WARNING in D:\tests_sources\X.java
 (at line 5)
	List raw= new ArrayList(input);
	              ^^^^^^^^^
ArrayList is a raw type. References to generic type ArrayList<E> should be
parameterized
----------
4. WARNING in D:\tests_sources\X.java
 (at line 6)
	raw.add(null);
	^^^^^^^^^^^^^
Type safety: The method add(Object) belongs to the raw type List. References to
generic type List<E> should be parameterized
----------
4 problems (4 warnings)

with -warn:raw,unchecked

Verified for 3.2 M3 using build I20051025-0800+JDT/Core v_618a
Comment 13 Robert Will CLA 2006-09-23 05:55:19 EDT
I have another example which shows how dissatisfying the current situation is (still in Eclipse Version 3.2.0).

public class IndirectComparator<T extends Comparable> implements Comparator<Integer> // should be <T extends Comparable<T>>
{
protected T[] weight;

public int compare(Integer i, Integer j)
{
	return (weight[i].compareTo(weight[j]));   // gives a warning here
}
}

Indeed, I did not realize that my error leading to the warning was in the first line until I found this bug description here.

There should really be a warning in the first line!

After studying this bus comments, I have changed the Eclipse compiler settings to include a warning on "usage of raw types". Then, I am correctly pointed at my programming error in the first line.

Perhaps this should be the default setting? I know that it would not be right for legacy code, but perhaps there is a better compromise?
Comment 14 Philipe Mulet CLA 2006-09-25 03:51:20 EDT
Raw type warnings are not mandated by the spec. This is why we added them, and I agree they could be made more proeminent to avoid wasting time tracking bugs or understanding unchecked warnings down the road.

Will think about making the warning on by default.
Comment 15 Eric Rizzo CLA 2006-10-02 23:32:35 EDT
In the interest of equal voice to both sides of this decision, I'll chime in with my $0.02 from the related newsgroup thread. Please take a moment to actually _think about_ what I'm saying here, because I understand that it is borderline heresy to speak ill against parameterized types...

I would not want to see this type of warning enabled by default. Parameterized types are not a universally embraced feature (see Bruce Eckel and others on the subject), and even if you like the implementation in Java, they should probably only be used when some benefit is provided. By enabling such warnings by default, it would send the message that there is some problem with NOT using them. Like saying, "Hey, you're not using generics! I don't care that it is not needed for your situation, you'd better use them anyway." That is not a message I'd want the tool sending to me (or, even less so, to some less-experienced programmers who are overly eager to use every language feature or pattern, however appropriate or inappropriate).

I understand that it is borderline heresy to speak ill against parameterized types, but I think it is dangerous to nudge programmers towards a feature just because it is there.
My primary point is not that parameterized types are good or bad, but that they are not mandatory in every programming situation. If this warning were enabled by default, it would send a message to users: "You really should be using parameterized types ALL the time" - but I see no evidence that it is the case that parameterized types are appropriate for all, or even most, situations.
There is a great danger and the results can be painful when we get suckered into a "because its there" mindset when it comes to this language feature - just look at the numerous bug reports and puzzling questions about parameterized types that populate the Net.
Comment 16 Eric Rizzo CLA 2006-10-02 23:33:08 EDT
Forgot this important part:
As an alternative, I would embrace a default warning if raw usage is detected AND there are other generics-related warnings/errors in the nearby code that are likely related to the fact that the raw type was declared originally. If that can be done, I would see it as the most helpful option since it is being intelligent about its recommendation to use parameterized types.
Comment 17 Philipe Mulet CLA 2006-10-03 03:50:54 EDT
Based on discussions in JDT newsgroup (see there), we will enable the warning by default, also see bug 159456.

Eric: your point is well taken, and we will see if this becomes a strong requirement from the community. I think most users so far rather reported they wanted to know about ALL raw types. Also if you read the spec, they mention that raw types are discouraged, and in future versions of the language they could even be forbidden... along these lines, people converting to 5.0 should not leave any raw type behind; or manually turn off the warning if they don't have the cycles to address them anyway (why even bother now), same would apply for unchecked warnings etc...
Comment 18 Robert Will CLA 2006-10-03 06:19:59 EDT
I agree with Eric, because I think the reasing for the warning on the raw type is not that raw types are "bad" or erroneous, but because the usage of one and the same variable in a generic _and_ raw fashion is likely to contain an error.

In another programming language (I forgot which one), I have seen warnings of the kind "error XX in line YY. (Object ZZ declared in line ZZ.)"
So as another alternative, the second (ambiguous) warning could be changed to refer to the first warning.