Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 401796 - [1.8][compiler] don't treat default methods as overriding an independent inherited abstract method
Summary: [1.8][compiler] don't treat default methods as overriding an independent inhe...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.8   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: BETA J8   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 383966
  Show dependency tree
 
Reported: 2013-02-26 09:45 EST by Stephan Herrmann CLA
Modified: 2013-03-03 11:38 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2013-02-26 09:45:22 EST
Consider this example:

public interface I1 {
	default void m() { }
}
public abstract class C1 {
	public abstract void m();
}
public class C2 extends C1 implements I1 { }

I read the spec 0.6.1 part H, 8.4.8 as saying:
- I1.m is inherited because C1.m does not override it from C1
- C1.m is inherited because I1.m does not override it from I1

In 8.4.8.4 none of the sentences starting with "It is a compile-time error" apply.

This puts the following sentence to action:
"Otherwise, the set of override-equivalent methods consists of at least one abstract method and zero or more default methods; then the class is necessarily an abstract class and is considered to inherit all the methods."

Thus we should issue an error because C2 is not abstract. This error is not reported currently.
Comment 1 Stephan Herrmann CLA 2013-03-03 11:33:37 EST
Observations from re-checking all of DefaultMethodTest against the current spec and against javac b74:

- in cases like our testAbstract02() javac first complains
  "C is not abstract and does not override abstract method test() in I1"
  Only after this is fixed by marking C as abstract the conflict between I1.test() and I2.test() is reported.
  By contrast, ECJ starts with reporting that conflict, thus avoiding to suggest a bogus fix.
  BTW, MethodVerifyTest.test043() reports a similar difference between compilers, which, however, seems obsolete as of b74 (see also bug 402237).

- testAnnotation1 triggered request for clarification bug 402236
  -> handled by marking the test with JavacTestOptions.JavacHasABug.Javac8AcceptsDefaultMethodInAnnotationType

- conflict between two independent default methods could be signaled more explicitly, done by new IProblem.DuplicateInheritedDefaultMethods


After my initial implementation in bug 383966 tree, both the spec and my understanding thereof have changed.
My patch-in-preparation will bring some changes that reflect these changes:

- solution from bug 401246 now applies in more situations, notably where only one non-abstract method exists, still an abstract class method resolves a conflict

- as a special case for the trumping behaviour of bug 401246 a check for abstractness has been added, which is needed because the regular analysis considers the inherited default method as sufficient to cover all override-equivalent inherit methods.

- conflict between an inherited default method and another method was not detected against abstract interface methods, whereas the current spec makes no difference between abstract or default interface method.
This particular change is realized by calling checkInheritedDefaultMethods() from a more central location (MethodVerifier15.checkInheritedMethods(MethodBinding[], int, boolean[])).
The change required updates of the tests testAbstract02(), testAbstract02a()  -> change override to conflict
Comment 2 Stephan Herrmann CLA 2013-03-03 11:38:47 EST
Released via commit ddff16f6a6b8fee88d497b4653d14d58ccda81b4 including some fixes for Bug 402237.