Skip to content

Commit 5b9b1a4

Browse files
committed
Allow colon lambdas as operands of infix operations
We already allow `: indent` there. For consistency we should allow `: params => indent` as well.
1 parent 2143474 commit 5b9b1a4

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,13 @@ object Parsers {
984984
recur(top)
985985
}
986986

987+
/** True if we are seeing a lambda argument after a colon of the form:
988+
* : (params) =>
989+
* body
990+
*/
991+
def isColonLambda =
992+
in.fewerBracesEnabled && in.token == COLONfollow && followingIsLambdaAfterColon()
993+
987994
/** operand { infixop operand | MatchClause } [postfixop],
988995
*
989996
* respecting rules of associativity and precedence.
@@ -998,24 +1005,25 @@ object Parsers {
9981005
val base = opStack
9991006

10001007
def recur(top: Tree): Tree =
1001-
val isType = kind == ParseKind.Type
1002-
if (isIdent && isOperator) {
1008+
def isType = kind == ParseKind.Type
1009+
def maybePostfix = kind == ParseKind.Expr && in.postfixOpsEnabled
1010+
if isIdent && isOperator then
10031011
val op = if isType then typeIdent() else termIdent()
10041012
val top1 = reduceStack(base, top, precedence(op.name), !op.name.isRightAssocOperatorName, op.name, isType)
10051013
opStack = OpInfo(top1, op, in.offset) :: opStack
10061014
colonAtEOLOpt()
10071015
newLineOptWhenFollowing(canStartOperand)
1008-
val maybePostfix = kind == ParseKind.Expr && in.postfixOpsEnabled
1009-
if (maybePostfix && !canStartOperand(in.token)) {
1016+
if isColonLambda then
1017+
in.nextToken()
1018+
recur(expr(Location.InColonArg))
1019+
else if maybePostfix && !canStartOperand(in.token) then
10101020
val topInfo = opStack.head
10111021
opStack = opStack.tail
10121022
val od = reduceStack(base, topInfo.operand, 0, true, in.name, isType)
10131023
atSpan(startOffset(od), topInfo.offset) {
10141024
PostfixOp(od, topInfo.operator)
10151025
}
1016-
}
10171026
else recur(operand(location))
1018-
}
10191027
else
10201028
val t = reduceStack(base, top, minPrec, leftAssoc = true, in.name, isType)
10211029
if !isType && in.token == MATCH then recurAtMinPrec(matchClause(t))
@@ -2399,7 +2407,7 @@ object Parsers {
23992407
makeParameter(name.asTermName, typedOpt(), Modifiers(), isBackquoted = isBackquoted(id))
24002408
}
24012409
case _ => t
2402-
else if in.fewerBracesEnabled && in.token == COLONfollow && followingIsLambdaAfterColon() then
2410+
else if isColonLambda then
24032411
val app = atSpan(startOffset(t), in.skipToken()) {
24042412
Apply(t, expr(Location.InColonArg) :: Nil)
24052413
}

tests/neg/closure-args.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import language.experimental.fewerBraces
22

3-
val x = List().map: (x: => Int) => // error
3+
val x = List(1).map: (x: => Int) => // error
44
???
5-
val y = List() map: x => // error
6-
x + 1 // error
7-
val z = List().map: + => // ok
5+
val z = List(1).map: + => // ok
86
???
97

108
val xs = List(1)

tests/pos/closure-args.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ object Test1:
44
val xs = List(1, 2, 3)
55
val ys = xs.map: x =>
66
x + 1
7+
val ys1 = List(1) map: x =>
8+
x + 1
79
val x = ys.foldLeft(0): (x, y) =>
810
x + y
911
val y = ys.foldLeft(0): (x: Int, y: Int) =>

0 commit comments

Comments
 (0)