From bbb1c6064ad0e61e86d389467e5b73d76afbe0f5 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 20 Nov 2025 21:01:49 -0800 Subject: [PATCH 1/2] Single line case lambda gets a region --- .../src/dotty/tools/dotc/parsing/Parsers.scala | 6 +++++- tests/neg/i24496.scala | 12 ++++++++++++ tests/pos/i24496.scala | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i24496.scala create mode 100644 tests/pos/i24496.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index f44703a562f1..7bdc34bd7a7c 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1137,7 +1137,11 @@ object Parsers { lookahead.skipParens() isArrowIndent() else if lookahead.token == CASE && in.featureEnabled(Feature.relaxedLambdaSyntax) then - Some(() => singleCaseMatch()) + Some: () => + inSepRegion(SingleLineLambda(_)): + singleCaseMatch() + .tap: _ => + accept(ENDlambda) else None isParamsAndArrow() diff --git a/tests/neg/i24496.scala b/tests/neg/i24496.scala new file mode 100644 index 000000000000..d8a86cc87924 --- /dev/null +++ b/tests/neg/i24496.scala @@ -0,0 +1,12 @@ +import scala.language.experimental.relaxedLambdaSyntax + +@main def Test = + val list = List(1, 2, 3) + + val three = list + .collect: case x => + (x, x + 1) // error not a member of tuple + .toMap + + val huh = list + .collect: x => case y => (y, y + 1) // error expecting case at x diff --git a/tests/pos/i24496.scala b/tests/pos/i24496.scala new file mode 100644 index 000000000000..0cd358a8d87f --- /dev/null +++ b/tests/pos/i24496.scala @@ -0,0 +1,15 @@ +import scala.language.experimental.relaxedLambdaSyntax + +@main def Test = + val list = List(1, 2, 3) + + val two = list + .collect: x => (x, x + 1) + .toMap + + val one = list + .collect: case x => (x, x + 1) + .toMap + + //val huh = list + // .collect: x => case y => (y, y + 1) correctly errors expecting case at x From 5a24b2a93a28e3e7a4afdda5fc8ca5674f71b38f Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sun, 23 Nov 2025 00:57:24 -0800 Subject: [PATCH 2/2] Permit indented RHS of single line case --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 3 +++ compiler/src/dotty/tools/dotc/parsing/Scanners.scala | 2 +- tests/neg/i24496.scala | 4 ++-- tests/pos/i24496.scala | 9 ++++++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 7bdc34bd7a7c..d37ab3afc31c 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3232,6 +3232,9 @@ object Parsers { val body = tok match case ARROW => atSpan(in.skipToken()): if exprOnly then + if in.token == ENDlambda then + in.token = NEWLINE + in.observeIndented() if in.indentSyntax && in.isAfterLineEnd && in.token != INDENT then warning(em"""Misleading indentation: this expression forms part of the preceding case. |If this is intended, it should be indented for clarity. diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index ec246f7a3742..82c87152be96 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -596,7 +596,7 @@ object Scanners { lastWidth = r.width newlineIsSeparating = lastWidth <= nextWidth || r.isOutermost indentPrefix = r.prefix - case _: InString => () + case _: InString | _: SingleLineLambda => () case r => indentIsSignificant = indentSyntax r.proposeKnownWidth(nextWidth, lastToken) diff --git a/tests/neg/i24496.scala b/tests/neg/i24496.scala index d8a86cc87924..4d5ae7d7d6d5 100644 --- a/tests/neg/i24496.scala +++ b/tests/neg/i24496.scala @@ -5,8 +5,8 @@ import scala.language.experimental.relaxedLambdaSyntax val three = list .collect: case x => - (x, x + 1) // error not a member of tuple - .toMap + (x, x + 1) + .toMap // error value toMap is not a member of (Int, Int) val huh = list .collect: x => case y => (y, y + 1) // error expecting case at x diff --git a/tests/pos/i24496.scala b/tests/pos/i24496.scala index 0cd358a8d87f..bdef831863a6 100644 --- a/tests/pos/i24496.scala +++ b/tests/pos/i24496.scala @@ -3,6 +3,12 @@ import scala.language.experimental.relaxedLambdaSyntax @main def Test = val list = List(1, 2, 3) + val three = list + .collect: case x => + val y = x + 1 + (x, y) + .toMap + val two = list .collect: x => (x, x + 1) .toMap @@ -10,6 +16,3 @@ import scala.language.experimental.relaxedLambdaSyntax val one = list .collect: case x => (x, x + 1) .toMap - - //val huh = list - // .collect: x => case y => (y, y + 1) correctly errors expecting case at x