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