Disallowing break label (and continue label) inside an expression switch

Brian Goetz brian.goetz at oracle.com
Fri Mar 23 18:45:41 UTC 2018


Just want to sync and make sure we're on the same page here...

Certain constructs (switch expression, switch statement, for/while/do) 
give meaning to some flavor of break.  Inside those, you can't use the 
other flavor, nor can you break "through" a construct of the opposite 
flavor.

     switch-expression {
         break / break-label not allowed;
         break-expr allowed;
         continue, return not allowed;

         if (foo) {
             break / break-label disallowed;
             break-expr allowed;
         }

         LOOP:
         for (...) {
             break, continue allowed;
             return not allowed;
             break-label allowed if within the switch expression
             break expression not allowed;
         }

         switch (e) {
             // same as for loop
             switch-expression {
                 break expr allowed
                 break, break-label, continue, return not allowed
         }
     }

More formally; we can construct a table whose rows are the control 
constructs and whose columns are the nonlocal branches, and whose 
entries are "handlers" for a nonlocal branch.  Each block has a parent 
(the immediately enclosing block.)

             break-e   break   break-l   continue   return

switch-e      L         X       X         X          X
switch-s      X         L       P         L          P
for           X         L       P         L          P
while         X         L       P         L          P
block         P         P       P         P          P
labeled       X         X L*        X          P
lambda        X         X       X         X L
method        X         X X         X          L

The handlers mean:

X -- not allowed
P -- let the parent handle it
L -- handle it and complete normally
L* -- handle it and complete normally if the labels match, otherwise P

(I might have mangled the labeled row, in which case surely Guy will 
correct me.)  The idea here is that each nested block acts as an 
"exception handler", catching some exceptions, and propagating others, 
and some contexts act as exception barriers, like trying to throw a 
"continue" out of a method.


On 3/2/2018 9:30 AM, Remi Forax wrote:
> Hi all,
> as far as i remember, the current idea to differentiate between a break label and a break value is to let the compiler figure this out,
> i wonder if it's not simpler to disallow break label (and continue label) inside an expression switch.
>
> After all, an expression switch do not exist yet, so no backward compatibility issue, it may make some refactoring impossible but had the great advantage to do not allow a lot of puzzler codes like the one below.
>
> enum Result {
>    ONE, MANY
> }
>
> Result result(String[] args) {
>    ONE: for(String s: args) {
>       return switch(s) {
>         case "several":
>         case "many":
>           break MANY;
>         case "one":
>           break ONE;
>         default:
>           continue;
>       };
>    }
>    throw ...;
> }
>
> Rémi



More information about the amber-spec-experts mailing list