Draft Spec for Third Preview of Pattern Matching for Switch and Record Patterns (JEP 405) now available
Brian Goetz
brian.goetz at oracle.com
Thu Apr 7 19:41:02 UTC 2022
> http://cr.openjdk.java.net/~gbierman/PatternSwitchPlusRecordPatterns/PatternSwitchPlusRecordPatterns-20220407/specs/patterns-switch-jls.html
>
>
> Comments welcome!
The execution of an exhaustive|switch|can fail with a linkage error
(an|IncompatibleClassChangeError|is thrown) if it encounters an instance
of a permitted direct subclass that was not known at compile time
(14.11.3
<http://cr.openjdk.java.net/~gbierman/PatternSwitchPlusRecordPatterns/PatternSwitchPlusRecordPatterns-20220407/specs/patterns-switch-jls.html#jls-14.11.3>,15.28.2
<http://cr.openjdk.java.net/~gbierman/PatternSwitchPlusRecordPatterns/PatternSwitchPlusRecordPatterns-20220407/specs/patterns-switch-jls.html#jls-15.28.2>).
Strictly speaking, the linkage error is not flagging a binary
incompatible change of the|sealed|class, but more accurately a/migration
incompatible/change of the|sealed|class.
I think we should back away from ICCE here as well, and put this in the
MatchException bucket too. Then:
- a switch throws NPE if the operand is null;
- an _enum switch_ throws ICCE when encountering a novel constant;
- all other remainder errors are MatchException.
File away for future use, that these clauses will have to be extended to
include other exhaustive pattern-aware constructs, like let.
14.11.1 Switch Blocks
The grammar for CaseOrDefaultLabel seems like it could be profitably
refactored to reflect more of the restrictions:
CaseOrDefaultLabel
case (null | CaseConstant) {, CaseConstant }
case [null, ] Pattern { WhenClause }
case [null, ] default
default
and then you don't have to enumerate as many of the restrictions of what
can combine with what.
It is a compile-time error if a|when|expression has the value|false|.
... is a constant expression and has the value false ?
*
A pattern case element/p/is switch compatible with/T/if/p/is
assignable to type/T/(14.30.3
<http://cr.openjdk.java.net/~gbierman/PatternSwitchPlusRecordPatterns/PatternSwitchPlusRecordPatterns-20220407/specs/patterns-switch-jls.html#jls-14.30.3>).
Isn't this cast-convertible? If the selector is String and the pattern
is `Object o`, o is not assignable to String, but it is cast-convertible.
A switch label is said to/dominate/another switch label
Can we say that in a pattern switch, default dominates everything, which
has the effect of forcing the default to the bottom?
if there are values for which both apply and there is not an obvious
preference
Is this really what we mean? Don't we really mean that the first one
matches everything the second one does?
A set of case elements is exhaustive
This is a nit, but couldn't this be its own subsection? This section is
getting long and varied.
/T/if/T/is downcast convertible to/U/
Is this right? Upcast convertibility is OK too -- you can match `Object
o` to a target of `String`, and vice versa.
If the type/R/is a raw type (4.8
<https://docs.oracle.com/javase/specs/jls/se18/html/jls-4.html#jls-4.8>)
then the type/T/must be a raw type, or vice versa; otherwise a
compile-time error occurs.
Is this the right restriction? What we want here (for this iteration)
is that if R is generic, we specify the type parameters. But this is not
the same thing. I would think we would want to say here something like
"if the class of R is a generic class, R cannot be raw".
whose type names/R/
missing a word
1.
A switch label that supports a pattern/p//applies/if the value
matches/p/(14.30.2
<http://cr.openjdk.java.net/~gbierman/PatternSwitchPlusRecordPatterns/PatternSwitchPlusRecordPatterns-20220407/specs/patterns-switch-jls.html#jls-14.30.2>).
If pattern matching completes abruptly then determining which switch
label applies completes abruptly for the same reason.
I think this is carried over from the previous round? Or do we not
resolve total type patterns to any at the top level of a switch?
2.
If no|case|label matches but there is a|default|label, then
the|default|label/matches/.*If neither of these rules apply to any
of the switch labels in the switch block, then a switch label that
supports a|default|applies.*
Don't we need a clause that says "if there is no default, a
MatchException is thrown"?
*If pattern matching completes abruptly then the process of determining
which switch label applies completes abruptly for the same reason.*
Doesn't it complete abruptly with MatchException? Or can PM only
complete abruptly with ME as well?
A type pattern that does not appear as an element in a record component
pattern list is called a/top-level type pattern/.
For future: "or array component pattern list"
The pattern variable declared by an any pattern has a type, which is a
reference type.
Is this still true? What if I have `record R(int x) {}` and `case R(var
x)`? The type of x is not a reference type. Same for `case R(int x)`.
A pattern/p/is said to be/unconditional/at a type/T/if every value of
type/T/will match/p/(after/p/has been resolved at type/T/(14.30.2
<http://cr.openjdk.java.net/~gbierman/PatternSwitchPlusRecordPatterns/PatternSwitchPlusRecordPatterns-20220407/specs/patterns-switch-jls.html#jls-14.30.2>)),
and is defined as follows:
An any pattern is unconditional at all T?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20220407/061b4778/attachment-0001.htm>
More information about the amber-spec-experts
mailing list