Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8273328: Compiler implementation for Pattern Matching for switch (Second Preview) #6209

Closed
wants to merge 3 commits into from

Conversation

lahodaj
Copy link
Contributor

@lahodaj lahodaj commented Nov 2, 2021

The specification for pattern matching for switch (preview)[1] has been updated with two changes:
-any type of pattern (including guarded patterns) dominates constant cases. Dominance across pattern/non-constant cases is unchanged. (See the change in Attr.java.)
-for sealed hierarchies, it may happen some of the subtypes are impossible (not castable) to the selector type. Like, for example:

sealed interface I<T> {}
final class A implements I<String> {}
final class B<T> implements I<T> {}
...
I<Integer> i = ...;
switch (i) {
     case A a -> {} //case not allowed as I<Integer> is not castable to A
     case B b -> {}
}

But, the exhaustiveness checks in JDK 17 required all the permitted subclasses, including A, are covered by the switch, which forced a default clause in place of case A a for cases like this. The updated specification excludes such impossible permitted subclasses from exhaustiveness checks, so the default is no longer needed and this:

I<Integer> i = ...;
switch (i) {
     case B b -> {}
}

compiles OK.
(See the change in Flow.java.)

[1] http://cr.openjdk.java.net/~gbierman/jep420/jep420-20211020/specs/patterns-switch-jls.html


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8273328: Compiler implementation for Pattern Matching for switch (Second Preview)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/6209/head:pull/6209
$ git checkout pull/6209

Update a local copy of the PR:
$ git checkout pull/6209
$ git pull https://git.openjdk.java.net/jdk pull/6209/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 6209

View PR using the GUI difftool:
$ git pr show -t 6209

Using diff file

Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/6209.diff

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Nov 2, 2021

👋 Welcome back jlahoda! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr label Nov 2, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Nov 2, 2021

@lahodaj The following label will be automatically applied to this pull request:

  • compiler

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the compiler label Nov 2, 2021
@mlbridge
Copy link

@mlbridge mlbridge bot commented Nov 2, 2021

Webrevs

Copy link
Contributor

@vicente-romero-oracle vicente-romero-oracle left a comment

looks good to me

@openjdk
Copy link

@openjdk openjdk bot commented Nov 2, 2021

@lahodaj This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8273328: Compiler implementation for Pattern Matching for switch (Second Preview)

Reviewed-by: vromero, mcimadamore

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 237 new commits pushed to the master branch:

  • 9160743: 8276058: Some swing test fails on specific CI macos system
  • 8193800: 8274179: AArch64: Support SVE operations with encodable immediates
  • b8453eb: 8275007: Java fails to start with null charset if LC_ALL is set to certain locales
  • 231fb61: 8276970: Default charset for PrintWriter that wraps PrintStream
  • 29e552c: 8272358: Some tests may fail when executed with other locales than the US
  • ce4471f: 8277346: ProblemList 7 serviceability/sa tests on macosx-x64
  • 45a60db: 8277045: G1: Remove unnecessary set_concurrency call in G1ConcurrentMark::weak_refs_work
  • 6bb0462: 8277224: sun.security.pkcs.PKCS9Attributes.toString() throws NPE
  • d8c0280: 8277316: ciReplay: dump_replay_data is not thread-safe
  • 007ad7c: 8277303: Terminology mismatch between JLS17-3.9 and SE17's javax.lang.model.SourceVersion method specs
  • ... and 227 more: https://git.openjdk.java.net/jdk/compare/5bb1992b8408a0d196b1afa308bc00d007458dbd...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready label Nov 2, 2021
Copy link
Contributor

@mcimadamore mcimadamore left a comment

Looks good. Left one comment about the logic in Flow.

@@ -784,7 +784,7 @@ private void transitiveCovers(Set<Symbol> covered) {
}
}

private boolean isTransitivelyCovered(Symbol sealed, Set<Symbol> covered) {
private boolean isTransitivelyCovered(Type seltype, Symbol sealed, Set<Symbol> covered) {
DeferredCompletionFailureHandler.Handler prevHandler =
Copy link
Contributor

@mcimadamore mcimadamore Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to guard against completion failures here in Flow?

Copy link
Contributor Author

@lahodaj lahodaj Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider a case like this:

sealed interface I permits A, B {}
//A and B defined
...
I i = null;
switch (i) {
     case A -> {}
}

This will produce an error, because the switch is not exhaustive. Now, consider, in addition, that B is missing. It feels a bit harsh to produce an error about the missing B permitted subclass (possibly producing that error instead of the exhaustiveness error), as it seems plausible permitted subclasses may be missing during compilation.

Copy link
Contributor

@mcimadamore mcimadamore Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm - I get what you say. But isn't sealing meant to be used within a single maintenance domain? If B is missing, how the heck did we get to Flow in the first place (since for sealed classes we check that permitted subclasses extend the sealed class being defined)

Copy link
Contributor

@mcimadamore mcimadamore Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm - I get what you say. But isn't sealing meant to be used within a single maintenance domain? If B is missing, how the heck did we get to Flow in the first place (since for sealed classes we check that permitted subclasses extend the sealed class being defined)

Ok - maybe you are considering the case where I is used in a compilation unit which did not defined it. And which cannot (for some reason) see B. Seems cornery, but what I'm mostly worried about is that it's not (I think) uniform with the rest of the javac code dealing with sealed classes. For instance, look at the cast conversion rules in Types::areDisjoint - in that case there's no protection against missing types.

I think the compiler code should be consistent in how we reason about sealed permitted types?

Copy link
Contributor Author

@lahodaj lahodaj Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the case is where the sealed class/interface is used from some other project. It is somewhat cornery, but might happen even for us - consider an sealed API interface in the JDK, which has permitted classes that are in an implementation package. The --release data normally do not include non-API packages, so when looking at the API interface, we may encounter a class that does not exist.

I didn't realize there is the same issue with areDisjoint, but you are right it suffers from the problem and that it should be consistent. I'll take a look at that, possibly separately, if that's OK.

Copy link
Contributor

@mcimadamore mcimadamore Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep - fine to postpone!

@lahodaj
Copy link
Contributor Author

@lahodaj lahodaj commented Nov 5, 2021

/csr needed

@openjdk openjdk bot added the csr label Nov 5, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Nov 5, 2021

@lahodaj this pull request will not be integrated until the CSR request JDK-8275408 for issue JDK-8273328 has been approved.

@openjdk openjdk bot removed the ready label Nov 5, 2021
@openjdk openjdk bot added ready and removed csr labels Nov 18, 2021
@lahodaj
Copy link
Contributor Author

@lahodaj lahodaj commented Nov 24, 2021

/integrate

@openjdk
Copy link

@openjdk openjdk bot commented Nov 24, 2021

Going to push as commit d085c2b.
Since your change was applied there have been 322 commits pushed to the master branch:

  • 6d73460: 8277399: ZGC: Move worker thread logging out of gc+phase=debug
  • 712b875: 8277397: ZGC: Add JFR event for temporary latency measurements
  • 7b2d823: 8277503: compiler/onSpinWait/TestOnSpinWaitAArch64DefaultFlags.java failed with "OnSpinWaitInst with the expected value 'isb' not found."
  • 7cb56a2: 8265796: vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects002/referringObjects002.java fails when running with JEP 416
  • 24e586a: 8276764: Enable deterministic file content ordering for Jar and Jmod
  • ea85e01: 8271623: Omit enclosing instance fields from inner classes that don't use it
  • 0320672: 8277451: java.lang.reflect.Field::set on static field with invalid argument type should throw IAE
  • e8acac2: 8277350: runtime/jni/checked/TestPrimitiveArrayCriticalWithBadParam.java times out
  • 8a44e09: 8268725: jshell does not support the --enable-native-access option
  • 7b67a49: 8261847: performance of java.lang.Record::toString should be improved
  • ... and 312 more: https://git.openjdk.java.net/jdk/compare/5bb1992b8408a0d196b1afa308bc00d007458dbd...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot closed this Nov 24, 2021
@openjdk openjdk bot added integrated and removed ready rfr labels Nov 24, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Nov 24, 2021

@lahodaj Pushed as commit d085c2b.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler integrated
3 participants