> On Mar 28, 2018, at 1:37 PM, Dan Smith <daniel.sm...@oracle.com> wrote:
> 
> At this point, we've got a choice:
> A) Fully mimic the conditional behavior in switch expressions
> B) Do target typing (when available) for all switch expressions, diverging 
> from conditionals
> C) Do target typing (when available) for all switches and conditionals, 
> accepting the incompatibilities

The consensus of this thread seemed to be (B) or (C), which means we know what 
we want to do for switch expressions, and can spin off potential changes to 
conditionals as a separate task. (TODO: To address that task, I may drill 
deeper into usage statistics and refine my scanning tool.)

To formalize the typing rules for switch expressions, here's a proposed 
specification. Some notes:

- The goal is fidelity with conditional expressions: a standalone switch 
expression has the same type as an equivalent standalone conditional 
expression. Also, of course, the result must not be order-dependent for cases 
with more than 2 result expressions (test case: (int, double, 
Comparable<Double>)).

- A proposed new rule that hasn't been previously discussed: to facilitate 
typing, there must be at least one result expression. (For example, all cases 
could throw, and this would be a compiler error.)

- We'll need to identify all the places that poly conditional expressions get 
special treatment (overload resolution, inference, conditional expression 
classification, ...) and update them to support switch expressions too.

------------

A switch expression is a poly expression if it appears in an assignment context 
or an invocation context ([5.2], [5.3]). Otherwise, it is a standalone 
expression.

The _result expressions_ of a switch expression are ...

It is a compile-time error if a switch expression has no result expressions.

[Design note: without at least one result expression, there's not a 
particularly good choice for the standalone type of the expression. It could 
still work as a poly expression, but for consistency it's probably better to 
reject the expression in all contexts.]

Where a poly switch expression appears in a context of a particular kind with 
target type _T_, its result expressions similarly appear in a context of the 
same kind with target type _T_.

A poly switch expression is compatible with a target type _T_ if each of its 
result expressions is compatible with _T_.

The type of a poly switch expression is the same as its target type.

The type of a standalone switch expression is determined as follows:

- If the result expressions all have the same type (which may be the null 
type), then that is the type of the switch expression.

- Otherwise, if the type of each result expression is `boolean` or `Boolean`, 
unboxing conversion ([5.1.8]) is applied to each result expression of type 
`Boolean`, and the switch expression has type `boolean`.

- Otherwise, if the type of each result expression is convertible to a numeric 
type ([5.1.8]), the type of the switch expression is given by conditional 
numeric promotion ([5.6.3]) applied to the result expressions.

- Otherwise, boxing conversion ([5.1.7]) is applied to each result expression 
that has a primitive type, after which the type of the switch expression is the 
least upper bound ([4.10.4]) of the types of the result expressions.


------

5.6.3 Conditional numeric promotion

[Design note: this introduces a new n-ary variety of numeric promotion. The 
rules for conditional expression typing would be revised to refer to it. I'm 
not sure what to call it, don't love this name but it's what I've come up with 
for now.

Another approach—more invasive but perhaps cleaner—would be to use this for 
_all_ numeric promotions, and ask clients to specify if they want `int` as a 
"minimum type" (as is the case for all primitive operators).]

When a conditional expression or switch expression applies conditional numeric 
promotion to a set of result expressions, each of which must denote a value 
that is convertible to a numeric type, the following rules apply, in order:

- If any result expression is of a reference type, it is subjected to unboxing 
conversion.

- Widening primitive conversion and narrowing primitive conversion are applied 
to some result expressions as specified by the follow rules:

   - If any result expression is of type double, the others are widened, as 
necessary, to double.
   - Otherwise, if any result expression is of type float, the others are 
widened, as necessary, to float.
   - Otherwise, if any result expression is of type long, the others are 
widened, as necessary, to long.
   - Otherwise, if any result expression is of type int and is not a constant 
expression, the others are widened, as necessary, to int.
   - Otherwise, if any result expression is of type char, and every other 
result expression is either of type char, or of type byte, or a constant 
expression of type int with a value that is representable in the type char, 
then the byte results are widened to char and the int results are narrowed to 
char.
   - Otherwise, if any result expression is of type short, and every other 
result expression is either of type short, or of type byte, or a constant 
expression of type int with a value that is representable in the type short, 
then the byte results are widened to short and the int results are narrowed to 
short.
   - Otherwise, if any result expression is of type byte, and every other 
result expression is either of type byte or a constant expression of type int 
with a value that is representable in the type byte, then the int results are 
narrowed to byte.
   - Otherwise, all the results are widened, as necessary, to int.

After the conversion(s), if any, value set conversion ([5.1.13]) is then 
applied to each operand.

Reply via email to