RFR: 8343306: javac is failing to determine if a class and a sealed interface are disjoint [v6]
Jan Lahoda
jlahoda at openjdk.org
Thu Nov 7 14:44:52 UTC 2024
On Thu, 7 Nov 2024 14:22:05 GMT, Vicente Romero <vromero at openjdk.org> wrote:
>> src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 1697:
>>
>>> 1695: } else if (csym.isSealed()) {
>>> 1696: return areDisjoint(isym, csym.getPermittedSubclasses());
>>> 1697: } else if (isym.isSealed()) {
>>
>> where did the freely extensible check go? That part is in the spec, but there's no code for it?
>
> Jan suggested in a previous comment that: `isClassFreelyExtensible == !csym.isSealed() && !csym.isFinal()`, which I think is correct. At this point we have checked that the class is not final and not sealed so if the interface is sealed we do the check for disjoint-ness between the class and the interface's permitted subclasses
Yes, I suggested that. The idea being that even if a class has a sealed supertype, then it must be one of `final`, `sealed` and `non-sealed` itself (or a compile-time error is produced). So, basically all classes that are not freely extensible are either `final` or `sealed`, and other (legal) classes are freely extensible, unless I am missing something.
And unless I am mistaken, the `non-sealed` flag is not written to the classfiles, and is not reconstituted when reading from classfiles, so using `Symbol.isNonSealed()` is not easy, and we could only reconstitute the flag based on the fact that some of the supertypes are sealed, but the class itself is neither `final` nor `sealed.
It would be possible to implement the freely extensible check exactly as written, if desired, but it seems unnecessarily complex to me.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/21794#discussion_r1832799701
More information about the compiler-dev
mailing list