If you expect this to be changed, the same would be expected e.g. from ?: expression. This also would create some kind of confusion: the switch expression cannot be inside the expression statement, but the expression statement is mostly associated with void-type expression.
Btw, there's another place where void-expression is allowed: update clause in for statement: for(int i=0; i<10; switch(i) {case 1 -> System.out.println(i++);default -> i++;}) {} Should this work? Your example assumes more changes to the switch expression, not just the 'void' type. You also assume that the block can omit the yield statement, and in this case the resulting type of the corresponding rule is considered to be 'void'. Also, what will be the resulting type of switch expression in case if different branches have different void-ness? E.g.: (i, consumer) -> switch(i) { case A a -> consumer.accept(a); // void branch case B b -> myList.add(b); // boolean branch } I don't think we already have result type rules for void & boolean (JLS 15.28.1). Should we set the resulting type as 'void'? This might be confusing and error-prone. E.g., I have two method overloads (think of ExecutorService.submit(Runnable) and ExecutorService.submit(Callable)). I may assume that the result is used but in fact it's not because I forget yield in one of the branches, so the rule type is set to void, this changes the type of the whole switch expression to the 'void', so the results of all other branches are ignored, lambda becomes void-compatible and we resolve to submit(Runnable) instead of submit(Callable). Sounds not very good. With best regards, Tagir Valeev. On Mon, Sep 27, 2021 at 2:11 AM Remi Forax <fo...@univ-mlv.fr> wrote: > > There is a bad interaction between a lambda and a switch expression, > a lambda allows its expression to be typed void but a switch expression can > not be typed void, > so the following code does not compile > > sealed interface I permits A, B {} > record A() {} > record B() {} > > public Optional<A> findOneA(List<I> list) { > return list.stream() > .<A>mapMulti((i, consumer) -> switch(i) { > case A a -> consumer.accept(a); > case B b -> {} > }) > .findFirst(); > } > > This bug occurs for with any methods that takes a Consumer has parameter (so > stream.forEach/peek, Iterator.forEachRemaining etc). > > The workaound is to add a pair of curly braces around the switch to transform > it to a switch statement. > > For me, it should be possible to have a switch expression typed void. This is > a backward compatible change given that the code does not compile otherwise. > > regards, > RĂ©mi