On 7 Apr 2022, at 20:41, Brian Goetz 
<brian.go...@oracle.com<mailto:brian.go...@oracle.com>> wrote:



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.

Will have a think about that.

It is a compile-time error if a when expression has the value false.

... is a constant expression and has the value false ?

Corrected.


  *   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.

Actually it’s a typo, it’s supposed to read “applicable” instead of assignable! 
Corrected


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?


We could do. I wasn’t sure that we had settled on that design - there was some 
discussion on this list.


 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?

Corrected.

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.

Let me have a think about that.


 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.

Corrected.


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".

Corrected.

whose type names R

missing a word

Corrected.



  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?


  1.  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?

I think perhaps you are misreading this section. This is just determining which 
label applies (none applies is a good answer too). The dealing with the 
consequences is taken care of in sections 14.11.3 for switch statements and 
15.28.2 for switch expressions.


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"

Ack.

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)`.

Corrected.


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?

So any patterns are not included in these compile-time analyses - they are an 
artefact of resolving patterns, which takes places afterwards.

Thanks,
Gavin

Reply via email to