RFR: 8334722: Error emitted when switch expression does not yield any value lacks reasoning [v3]

Jan Lahoda jlahoda at openjdk.org
Mon Jun 24 10:21:20 UTC 2024


On Sun, 23 Jun 2024 21:04:41 GMT, Evemose <duke at openjdk.org> wrote:

>> Please review this trivial enhancement to informativity of error emiited when switch expression does not yield value in any branch lacks reasoning.
>> 
>> Issue body: 
>> Currently, when switch expression does not yield any value, compiler emits following error: "switch expression does not have any result expressions". While this gives information on how to solve the issue, the exact reason of this error stays unclear, expecially because switch *statements* do not have same requirement. Recently, there even were question about this in one of jdk mailing lists.
>> 
>> The source of issue becomes obvious if we look where this error is reported: it is emmited in Attr class when javac is unable to assign type to switch expression. Therefore, I propose to change the emitted error text to following: "Unable to determine switch expression type: no branch that yields value found".
>> 
>> If anyone have ideas on how to furthernore improve this error message, please feel free to share.
>
> Evemose has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision:
> 
>  - Merge branch 'openjdk:master' into improved-switch-expr-error
>  - fix typo
>  - init

[snip]

> Now with this said, I guess it would be appropriate to identify problem more formally. I would formulate it as something as following: "Switch expression have requirement to contain at least one branch that results in value yielded at least in one of possible execution execution scenarios, unlike the switch statements. The previous error, _while provides explanation on how to fix this compilation error_, does not explain why it is reported. It _is_ confusing due to inconsistency between switch expression and statement".

Technically speaking, the immediate reason for this error is the assertion in the JLS. And while saying "the error is reported because the type of the switch expression cannot be determined" may be a convenient informal explanation (and it was, I think, part of the consideration why the switch expressions without any result expressions are illegal), it is not technically correct. Please see below.

[snip]

> To yield part: im not sure if it is strictly correct, but I always thought of non-void one-expression lambdas as ones that imolecitly return the value. Moreover, if you look into decompiled sources, generated return statements is exactly what you will see. That's why I also have always thought that whether yield keyword is specified explicitly or not, value is always _yielded_.

I probably didn't use the best example. Let me try with a new one:

    private void c() {
        test(switch (0) {
            default -> { yield ""; }
        });
    }

    private void test(CharSequence cs) {}


The type of the switch expression here is not determined by the `yield` statement at all. The switch expression is a poly expression here, and its type is determined by the target type, which is `java.lang.CharSequence` here. The expressions inside the `yield` statements are attributed against the target type, but whether or not there are any `yield` statements (or expressions that are expanded to `yield` statements) is not important for determining the type of the expression.

In other words, there are (I think) multiple reasons why code like this is illegal:

    private void c() {
        test(switch (0) {
            default -> throw new RuntimeException();
        });
    }

    private void test(CharSequence cs) {}


but inability to determine the type of the switch expression is not one of them. The type of this switch expression would still be `java.lang.CharSequence`.

The types of the expressions inside the `yield` statements are AFAIK only important for determining the type of the switch expression if the switch expression is standalone. Like:

        (switch (0) {
            default -> { yield ""; }
        }).length();

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

PR Comment: https://git.openjdk.org/jdk/pull/19837#issuecomment-2186198411


More information about the compiler-dev mailing list