Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d94c344

Browse files
committed
Allow single case clauses as expressions
1 parent 97208f8 commit d94c344

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

‎compiler/src/dotty/tools/dotc/parsing/Parsers.scala‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,6 +2378,7 @@ object Parsers {
23782378

23792379
/** Expr ::= [`implicit'] FunParams (‘=>’ | ‘?=>’) Expr
23802380
* | TypTypeParamClause ‘=>’ Expr
2381+
* | ExprCaseClause
23812382
* | Expr1
23822383
* FunParams ::= Bindings
23832384
* | id
@@ -2429,6 +2430,8 @@ object Parsers {
24292430
val arrowOffset = accept(ARROW)
24302431
val body = expr(location)
24312432
makePolyFunction(tparams, body, "literal", errorTermTree(arrowOffset), start, arrowOffset)
2433+
case CASE =>
2434+
singleCaseMatch()
24322435
case _ =>
24332436
val saved = placeholderParams
24342437
placeholderParams = Nil
@@ -2492,9 +2495,8 @@ object Parsers {
24922495
if in.token == CATCH then
24932496
val span = in.offset
24942497
in.nextToken()
2495-
(if in.token == CASE then Match(EmptyTree, caseClause(exprOnly = true) :: Nil)
2496-
else subExpr(),
2497-
span)
2498+
(if in.token == CASE then singleCaseMatch() else subExpr(),
2499+
span)
24982500
else (EmptyTree, -1)
24992501

25002502
handler match {
@@ -3188,9 +3190,9 @@ object Parsers {
31883190
case ARROW => atSpan(in.skipToken()):
31893191
if exprOnly then
31903192
if in.indentSyntax && in.isAfterLineEnd && in.token != INDENT then
3191-
warning(em"""Misleading indentation: this expression forms part of the preceding catch case.
3193+
warning(em"""Misleading indentation: this expression forms part of the preceding case.
31923194
|If this is intended, it should be indented for clarity.
3193-
|Otherwise, if the handler is intended to be empty, use a multi-line catch with
3195+
|Otherwise, if the handler is intended to be empty, use a multi-line match or catch with
31943196
|an indented case.""")
31953197
expr()
31963198
else block()
@@ -3206,6 +3208,9 @@ object Parsers {
32063208
CaseDef(pat, grd1, body)
32073209
}
32083210

3211+
def singleCaseMatch() =
3212+
Match(EmptyTree, caseClause(exprOnly = true) :: Nil)
3213+
32093214
/** TypeCaseClause ::= ‘case’ (InfixType | ‘_’) ‘=>’ Type [semi]
32103215
*/
32113216
def typeCaseClause(): CaseDef = atSpan(in.offset) {

‎docs/_docs/internals/syntax.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ CapFilter ::= ‘.’ ‘as’ ‘[’ QualId ’]’
243243
```ebnf
244244
Expr ::= FunParams (‘=>’ | ‘?=>’) Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr)
245245
| TypTypeParamClause ‘=>’ Expr PolyFunction(ts, expr)
246+
| ExprCaseClause
246247
| Expr1
247248
BlockResult ::= FunParams (‘=>’ | ‘?=>’) Block
248249
| TypTypeParamClause ‘=>’ Block
@@ -295,6 +296,8 @@ SimpleExpr ::= SimpleRef
295296
| XmlExpr -- to be dropped
296297
ColonArgument ::= colon [LambdaStart]
297298
indent (CaseClauses | Block) outdent
299+
| colon LambdaStart expr ENDlambda -- ENDlambda is inserted for each production at next EOL
300+
-- does not apply if enclosed in parens
298301
LambdaStart ::= FunParams (‘=>’ | ‘?=>’)
299302
| TypTypeParamClause ‘=>’
300303
Quoted ::= ‘'’ ‘{’ Block ‘}’

‎tests/run/single-case-expr.scala‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
case class Foo(x: Int, y: Int)
2+
@main def Test =
3+
val f: List[Int] => Int = case y :: ys => y
4+
val xs = List(1, 2, 3)
5+
assert(f(xs) == 1)
6+
7+
val g: Foo => Int = identity(case Foo(a, b) => a)
8+
val foo = Foo(1, 2)
9+
assert(g(foo) == 1)
10+
11+
val a1 = Seq((1, 2), (3, 4)).collect(case (a, b) if b > 2 => a)
12+
assert(a1 == Seq(3))
13+
14+
var a2 = Seq((1, 2), (3, 4)).collect(
15+
case (a, b) =>
16+
println(b)
17+
a
18+
)
19+
assert(a2 == Seq(1, 3))
20+
21+
val partial: PartialFunction[(Int, Int), Int] = case (a, b) if b > 2 => a

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /