Bug 170318 - [1.5][compiler] improve message on nameclash when overriding method with "wildcard" parameter
Summary: [1.5][compiler] improve message on nameclash when overriding method with "wil...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows 2000
: P3 minor (vote)
Target Milestone: 3.3 M5   Edit
Assignee: Maxime Daniel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-01-12 08:27 EST by Ilja Preuss CLA
Modified: 2007-02-05 12:04 EST (History)
4 users (show)

See Also:


Attachments
Suggested fix (2.19 KB, patch)
2007-01-23 04:40 EST, Maxime Daniel CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ilja Preuss CLA 2007-01-12 08:27:15 EST
Build ID: I20061102-1715

Steps To Reproduce:
Try to compile the following source code, with compiler compliance level set to 5.0:

import java.util.List;

class Super<T> {
  public void accepts(final List<?> list) {
  }
}

class Sub extends Super {
  public void accepts(final List<?> list) {
    super.accepts(list);
  }
}

You will get the compiler error:

Name clash: The method accepts(List<?>) of type Sub has the same erasure as accepts(List<?>) of type Super<T> but does not override it


More information:
The code compiles fine when you remove the generic type parameter T from the Super class.
Comment 1 Maxime Daniel CLA 2007-01-12 09:22:35 EST
javac agrees with us on this test case (1.5.10 and 6 b104, not tested b105
yet).
Released GenericTypeTest#test1100 in HEAD and R3_2_maintenance.
Comment 2 Ilja Preuss CLA 2007-01-12 10:40:20 EST
Sorry for not trying with javac first...

So are you saying that it is the correct behaviour according to the Java specification, or that it is a Sun bug that Eclipse emulates?
Comment 3 Maxime Daniel CLA 2007-01-12 11:20:18 EST
So far, I simply looked at javac and did not give much thought to the spec. I'll have a second look at it next week.
Comment 4 Ilja Preuss CLA 2007-01-15 03:44:31 EST
(In reply to comment #3)
> So far, I simply looked at javac and did not give much thought to the spec.
> I'll have a second look at it next week.
> 

That's great, thanks!
Comment 5 Maxime Daniel CLA 2007-01-18 04:23:51 EST
Interesting indeed.
Super#accepts and Sub#accepts clearly have the same erasure.
Sub extending of Super#RAW makes it a raw type. Consequently, Sub#accepts signature is, per p 59, void accepts(List#RAW), which, per p. 213, is not the same as a void accepts(List<?>), but is a subsignature of it. Hence, per p. 224, Sub#accepts should override Super#accepts.
Philippe, did I miss something?
Comment 6 Philipe Mulet CLA 2007-01-19 11:27:48 EST
Since Super is a generic class, when used as a raw supertype, a raw conversion is performed on all its non-static members. So the hierarchy of Sub looks like:

Super
 +- accepts(List)

Sub
 +- accepts(List<?>)

which is expected to raise a nameclash. 

If you remove the type param from Super, then no raw conversion is performed any longer, and thus you end up comparing:

Super
 +- accepts(List<?>)

Sub
 +- accepts(List<?>)


To confuse you even more, observe the following testcase:
import java.util.List;

class Super<T> {
  public void accepts(final List<Exception> list) {
  }
}
class Sub extends Super {
  public void accepts(final List<Thread> list) {
    super.accepts(list);
  }
}

Note that the nameclash is diagnosed as expected, but check out the line 
"super.accepts(list);". No error is flagged there, but a warning about using a raw method. The super method invoked is #accepts(List) not #accepts(List<Thread>) any longer.

BTW, our error message about nameclash is quite misleading. It should surface the raw method instead of showing the generic methods.

i.e. instead of telling:
Name clash: The method accepts(List<?>) of type Sub has the same erasure as
accepts(List<?>) of type Super<T> but does not override it

it should tell:
Name clash: The method accepts(List<?>) of type Sub has the same erasure as
accepts(List) of type Super but does not override it
Comment 7 Philipe Mulet CLA 2007-01-19 11:28:20 EST
Kent - look at the error msg issue pls
Comment 8 Maxime Daniel CLA 2007-01-22 01:53:04 EST
(In reply to comment #5)
> Philippe, did I miss something?
What I missed was that Sub extending Super#RAW does not make it a raw type.  
Hence we're right to match accepts(List<?>) against accepts(List#RAW), and to complain.

Comment 9 Kent Johnson CLA 2007-01-22 15:55:59 EST
The error message is produced by MethodVerifier15.detectNameClash().

We could change it to:

boolean detectNameClash(MethodBinding current, MethodBinding inherited) {
 MethodBinding original = inherited.original(); // can be the same as inherited
 if (!current.areParameterErasuresEqual(original) || current.returnType.erasure() != original.returnType.erasure()) return false;

 problemReporter(current).methodNameClash(current, inherited); <<< was original
 return true;
}

4 other tests besides 1100 are affected (298, 355, 397 & 435).

Please take a look at those tests to make sure that this change makes sense.
Comment 10 Maxime Daniel CLA 2007-01-23 04:33:17 EST
Reopening to improve the message.
Comment 11 Maxime Daniel CLA 2007-01-23 04:35:13 EST
Tuning the severity as well, since we are right to complain.
Comment 12 Maxime Daniel CLA 2007-01-23 04:40:44 EST
Created attachment 57329 [details]
Suggested fix

Along the lines Kent suggested, but a bit more restrictive. In that patch, I hold on the original method unless the inherited one has a raw type as its declaring type. This should not change the situations where both types are raw, nor those where we do not rawify inherited (in which case the choice of the original method must have been deliberate, and seems better in that it refers to the method as it can be read in its declaring type). Bringing the raw types up in case we had to rawify should remove the oddity of this peculiar test case, and help the user understand that some magic happened that made the method signature change.
Patch currently under test (other test cases may see parts of their messages change).
Comment 13 Maxime Daniel CLA 2007-01-23 09:55:55 EST
Fixed a few more test messages.
Released for 3.3 M5.
Comment 14 David Audel CLA 2007-02-05 12:04:29 EST
Verified for 3.3 M5 using warm-up build I20070205-0009