| Summary: | [compiler][1.7] Name clash not reported by ecj but fails with javac 1.7 | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Marcin Wisnicki <mwisnicki> |
| Component: | Core | Assignee: | JDT-Core-Inbox <jdt-core-inbox> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | stephan.herrmann |
| Version: | 4.3 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | All | ||
| Whiteboard: | stalebug | ||
The actual erased return types are of course boolean and Object. trying different version of javac and ecj, only javac >= 1.7 report this error.
It would be good to know the Oracle bug by which javac has change in this regard.
OTOH, the following test main (compiled with javac 1.6- or ecj) runs just fine:
public static void main(String[] args) {
Nameclash n = new Nameclash();
for (Method m: n.apply(Nameclash.class)) {
System.out.println(m);
}
if (n.apply(Nameclash.class.getMethods()[0])) {
System.out.println("yes");
}
Function<Class<?>, List<Method>> f = n;
for (Method m: f.apply(Nameclash.class)) {
System.out.println(m);
}
Predicate<Method> p = n;
if (p.apply(Nameclash.class.getMethods()[0])) {
System.out.println("yes");
}
}
So at first glance I see no reason to reject the program.
Maybe this was an unintended change in javac??
Only when looking into the compiled bytecode I see two conflicting bridge methods:
public volatile synthetic Object apply(Object arg1)
public volatile synthetic boolean apply(Object arg1)
In source code, return types are not used for overload resolution, yet the JVM
seems to be able to pick the right bridge method.
(in reply to comment 0):
> I don't know who to blame but behaviour should be consistent
So far I don't know either. First of all I'd like the behavior to be consistent
with the JLS => more investigation needed.
Bug: https://bugs.openjdk.java.net/browse/JDK-6182950 Commit: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/5caa6c45936a I'm not sure their analysis applies in this case, since the clash occurs between synthetic bridge methods which are not accessible from within Nameclash class (JLS8.4.8.3). (In reply to Marcin Wisnicki from comment #3) > Bug: https://bugs.openjdk.java.net/browse/JDK-6182950 > Commit: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/5caa6c45936a > > I'm not sure their analysis applies in this case, since the clash occurs > between synthetic bridge methods which are not accessible from within > Nameclash class (JLS8.4.8.3). Thanks for digging this out. Unfortunately, our case here is more complex. We don't know yet if the change regarding our example was an (accidental?) side-effect of the bug you cited or if yet another bug fix in javac is involved. This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. |
javac: 1.7.0_25 <code> import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; public class Nameclash implements Function<Class<?>, List<Method>>, Predicate<Method> { @Override public boolean apply(Method input) { return true; } @Override public List<Method> apply(Class<?> input) { return Arrays.asList(input.getMethods()); } } interface Function<F, T> { T apply(F input); } interface Predicate<T> { boolean apply(T input); } </code> javac complains that: <pre> Nameclash.java:10: error: name clash: apply(Method) in Nameclash overrides a method whose erasure is the same as another method, yet neither overrides the other public boolean apply(Method input) { ^ first method: apply(F) in Function second method: apply(T#2) in Predicate where F,T#1,T#2 are type-variables: F extends Object declared in interface Function T#1 extends Object declared in interface Function T#2 extends Object declared in interface Predicate Nameclash.java:15: error: name clash: apply(Class<?>) in Nameclash overrides a method whose erasure is the same as another method, y et neither overrides the other public List<Method> apply(Class<?> input) { ^ first method: apply(T#1) in Predicate second method: apply(F) in Function where T#1,F,T#2 are type-variables: T#1 extends Object declared in interface Predicate F extends Object declared in interface Function T#2 extends Object declared in interface Function 2 errors </pre> Erased methods actually differ by return type (boolean vs List) so I don't know who to blame but behaviour should be consistent.