JDK-8157994 : 8.8.7.1: Account for an inherited supertype S
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-05-26
  • Updated: 2018-08-03
  • Resolved: 2016-10-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
JLS 3 used the following phrase when defining the enclosing instance of an unqualified 'super' call:

"Let O be the innermost lexically enclosing class of which S is a member, and let n be an integer such that O is the nth lexically enclosing class of C."

JLS 7 changed it to:

"Let O be the innermost lexically enclosing class of S, and let n be an integer such that O is the nth lexically enclosing class of C."

The distinction is subtle, but by speaking of membership, we allowed for the possibility that S is inherited by a lexically enclosing class of C.  JLS 7 no longer accounted for this case.

Compare the error check appearing earlier, which continues to use the word "member":
JLS 7: "it is a compile-time error if S is not a member of a lexically enclosing class of C by declaration or inheritance"
JLS 8: "If S is an inner member class, but S is not a member of a lexically enclosing type declaration of C, then a compile-time error occurs"

All of these fail to directly address the possibility that S is a member of C.  S cannot be *declared* a member of C (per 8.1.4), but might be inherited.  Since C is the 0th lexically enclosing class of itself (8.1.3), that would imply that C == O.  But I believe the intent (and actual javac behavior) is that n >= 1.
Comments
I believe 15.9.2's determination of an immediately enclosing instance w.r.t. S is OK, because when S is an inner member class, 15.9.2 always said "Let O be the immediately enclosing class of which S is a member". And when S is a local class, there's no inheritance issue and the current text is right to "Let O be the immediately enclosing class of S".
12-10-2016

Proposed spec text for 8.8.7.1: If a superclass constructor invocation statement is unqualified, then: - If S is an inner member class, but S is not a member of a ***class enclosing*** C, then a compile-time error occurs. ... Let i be the instance being created. The immediately enclosing instance of i with respect to S (if any) must be determined: - If S is not an inner class, or if the declaration of S occurs in a static context, then no immediately enclosing instance of i with respect to S exists. - If the superclass constructor invocation is unqualified, then S is necessarily a local class or an inner member class. ***If S is a local class, then*** let O be the immediately enclosing ***type declaration*** of S, and let n be an integer ***��� 1*** such that O is the n'th lexically enclosing type declaration of C. ***If S is an inner member class, then let O be the innermost enclosing class of C of which S is a member, and let n be an integer ��� 1 such that O is the n'th lexically enclosing type declaration of C.*** The immediately enclosing instance of i with respect to S is the n'th lexically enclosing instance of this. ***[Note]: While it may be the case that S is a member of C (by inheritance), the 0th lexically enclosing instance of 'this'���that is, just 'this'���is never used as the immediately enclosing instance of i with respect to S.*** ...
11-10-2016

JDK-6708938 is a good discussion of the n=0 problem. Concluded that it should be disallowed, but we just need to adjust the spec language to *still* allow inheritance where n > 0.
04-10-2016

There may also be similar cleanup in 15.9.2.
27-05-2016

Expanding on the "S is a member of C" case. We have: class C extends S { ... } S is an inner class of some other class (not interface), OS; and the only way for C to inherit S as a member is if S is a member of itself, which means it extends OS. class OS { class S extends OS {} } Both of these declarations are reasonable, and the question is whether C can then provide an enclosing instance for its super call: class C extends OS.S { public C() { this.super(); // legal? } public C(int dummy) { super(); // implicitly infer 'this' as enclosing instance? } } javac rejects "this.super()" because 'this' can't be referenced before the super call. javac rejects unqualified "super()" because its implementation of the search requires n >= 1.
26-05-2016