@@ -2592,6 +2592,13 @@ object Parsers {
25922592 Match (t, inBracesOrIndented(caseClauses(() => caseClause())))
25932593 }
25942594
2595+ /** SubMatchClause ::= `match' `{' CaseClauses `}'
2596+ */
2597+ def subMatchClause (t : Tree ): SubMatch = atSpan(startOffset(t), accept(MATCH )):
2598+ val cases = inBracesOrIndented(caseClauses(() => caseClause()))
2599+ if ! in.isNestedEnd then acceptStatSep() // else is sub sub match
2600+ SubMatch (t, cases)
2601+
25952602 /** `match' <<< TypeCaseClauses >>>
25962603 */
25972604 def matchType (t : Tree ): MatchTypeTree =
@@ -3092,24 +3099,27 @@ object Parsers {
30923099 buf.toList
30933100 }
30943101
3095- /** CaseClause ::= ‘case’ Pattern [Guard] `=>' Block
3096- * ExprCaseClause ::= ‘case’ Pattern [Guard] ‘=>’ Expr
3102+ /** CaseClause ::= ‘case’ Pattern [Guard] (‘with’ SimpleExpr SubMatchClause | `=>' Block)
3103+ * ExprCaseClause ::= ‘case’ Pattern [Guard] (‘with’ SimpleExpr SubMatchClause | `=>' Expr)
30973104 */
30983105 def caseClause (exprOnly : Boolean = false ): CaseDef = atSpan(in.offset) {
30993106 val (pat, grd) = inSepRegion(InCase ) {
31003107 accept(CASE )
31013108 (withinMatchPattern(pattern()), guard())
31023109 }
3103- CaseDef (pat, grd, atSpan(accept(ARROW )) {
3104- if exprOnly then
3105- if in.indentSyntax && in.isAfterLineEnd && in.token != INDENT then
3106- warning(em """ Misleading indentation: this expression forms part of the preceding catch case.
3107- |If this is intended, it should be indented for clarity.
3108- |Otherwise, if the handler is intended to be empty, use a multi-line catch with
3109- |an indented case. """ )
3110- expr()
3111- else block()
3112- })
3110+ val body =
3111+ if in.token == WITH && in.featureEnabled(Feature .matchWithSubCases) then atSpan(in.skipToken()):
3112+ subMatchClause(simpleExpr(Location .ElseWhere ))
3113+ else atSpan(accept(ARROW )):
3114+ if exprOnly then
3115+ if in.indentSyntax && in.isAfterLineEnd && in.token != INDENT then
3116+ warning(em """ Misleading indentation: this expression forms part of the preceding catch case.
3117+ |If this is intended, it should be indented for clarity.
3118+ |Otherwise, if the handler is intended to be empty, use a multi-line catch with
3119+ |an indented case. """ )
3120+ expr()
3121+ else block()
3122+ CaseDef (pat, grd, body)
31133123 }
31143124
31153125 /** TypeCaseClause ::= ‘case’ (InfixType | ‘_’) ‘=>’ Type [semi]
0 commit comments