[code-reflection] RFR: Unreachable method or lambda exit [v2]

Maurizio Cimadamore mcimadamore at openjdk.org
Mon Oct 21 10:22:52 UTC 2024


On Fri, 18 Oct 2024 20:54:12 GMT, Paul Sandoz <psandoz at openjdk.org> wrote:

> > Looks good. I wonder if something similar is required for switch/yield?
> > E.g.
> > ```
> > jshell> String s = switch (n) {
> >    ...>     case 3 -> { while (true);}
> >    ...>     default -> " Hello!";
> >    ...> };
> > s ==> " Hello!"
> > ```
> 
> Drat, i did briefly ponder that but did not realize such switch expressions would be legal code. Is this a bug or some sort of compromise?
> 
> This is contrary to what [JEP 361](https://openjdk.org/jeps/361) says:
> 
> > Furthermore, a switch expression must either complete normally with a value, or complete abruptly by throwing an exception. This has a number of consequences. First, the compiler checks that for every switch label, if it is matched then a value can be yielded.
> 
> This is also contrary to what the JLS states in section [15.8](https://docs.oracle.com/javase/specs/jls/se23/html/jls-15.html#jls-15.28):
> 
> > A switch expression transfers control to one of several statements or expressions, depending on the value of an expression; all possible values of that expression must be handled, and all of the several statements and expressions must produce a value for the result of the switch expression.
> 
> But digging deeper i think it comes down to this in section [15.18.1](https://docs.oracle.com/javase/specs/jls/se23/html/jls-15.html#jls-15.28):
> 
> > It is a compile-time error if the switch block of a switch expression consists of switch rules, but one or more switch rule blocks can complete normally ([§14.22](https://docs.oracle.com/javase/specs/jls/se23/html/jls-14.html#jls-14.22)).
> 
> There is a tension here. In the example the switch expression cannot complete normally with a value, or abruptly with an exception, because the while statement does not complete normally and therefore the enclosing switch rule block does not complete normally, but it also does not complete abruptly.

Another confounding (but orthogonal) factor. This compiles:


String s = switch (n) {
    case 3 -> { while (true);}
    default -> " Hello!";
};


But this doesn't:


String s = switch (n) {
       case 3 -> { while (true) { }; }
       default -> " Hello!";
};

What changes is the interpretation of `;` in the absence/presence of `{ }`. Without braces, the `;` is interpreted as part of the `while`. So everything is ok. But with the braces, `;` is no longer part of the `while`, but an (optional) empty statement following the `while` - which is unreachable :-)

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

PR Comment: https://git.openjdk.org/babylon/pull/257#issuecomment-2426250356


More information about the babylon-dev mailing list