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