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 97208f8

Browse files
committed
Small tweaks
1 parent 29b3909 commit 97208f8

File tree

5 files changed

+38
-17
lines changed

5 files changed

+38
-17
lines changed

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

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,9 +1085,19 @@ object Parsers {
10851085
}
10861086

10871087
/** Is the token sequence following the current `:` token classified as a lambda?
1088-
* This is the case if the input starts with an identifier, a wildcard, or
1089-
* something enclosed in (...) or [...], and this is followed by a `=>` or `?=>`
1090-
* and an INDENT.
1088+
* If yes return a defined parsing function to parse the lambda body, if not
1089+
* return None. The case is triggered in two :if the input starts with an identifier,
1090+
* a wildcard, or something enclosed in (...) or [...], this is followed by a
1091+
* `=>` or `?=>`, one one of the following two cases applies:
1092+
* 1. The next token is an indent. In this case the return parsing function parses
1093+
* an Expr in location Location.InColonArg.
1094+
* 2. The next token is on the same line and the enclosing region is not `(...)`.
1095+
* In this case the parsing function parses an Expr in location Location.InColonArg
1096+
* enclosed in a SingleLineLambda region, and then eats the ENDlambda token
1097+
* generated by the Scanner at the end of that region.
1098+
* The reason for excluding (2) in regions enclosed in parentheses is to avoid
1099+
* an ambiguity with type ascription `(x: A => B)`, where function types are only
1100+
* allowed inside parentheses.
10911101
*/
10921102
def followingIsLambdaAfterColon(): Option[() => Tree] =
10931103
val lookahead = in.LookaheadScanner(allowIndent = true)
@@ -1101,7 +1111,7 @@ object Parsers {
11011111
Some: () =>
11021112
val t = inSepRegion(SingleLineLambda(_)):
11031113
expr(Location.InColonArg)
1104-
accept(ENDLAMBDA)
1114+
accept(ENDlambda)
11051115
t
11061116
else None
11071117
else None
@@ -1178,11 +1188,14 @@ object Parsers {
11781188
case _ => infixOp
11791189
}
11801190

1181-
/** True if we are seeing a lambda argument after a colon of the form:
1191+
/** Optionally, if we are seeing a lambda argument after a colon of the form
11821192
* : (params) =>
11831193
* body
1194+
* or a single-line lambda
1195+
* : (params) => body
1196+
* then return the function used to parse `body`.
11841197
*/
1185-
def isColonLambda: Option[() => Tree] =
1198+
def detectColonLambda: Option[() => Tree] =
11861199
if sourceVersion.enablesFewerBraces && in.token == COLONfollow
11871200
then followingIsLambdaAfterColon()
11881201
else None
@@ -1209,7 +1222,7 @@ object Parsers {
12091222
opStack = OpInfo(top1, op, in.offset) :: opStack
12101223
colonAtEOLOpt()
12111224
newLineOptWhenFollowing(canStartOperand)
1212-
isColonLambda match
1225+
detectColonLambda match
12131226
case Some(parseExpr) =>
12141227
in.nextToken()
12151228
recur(parseExpr())
@@ -2778,6 +2791,7 @@ object Parsers {
27782791
* | SimpleExpr1 ColonArgument
27792792
* ColonArgument ::= colon [LambdaStart]
27802793
* indent (CaseClauses | Block) outdent
2794+
* | colon LambdaStart expr ENDlambda -- under experimental.relaxedLambdaSyntax
27812795
* LambdaStart ::= FunParams (‘=>’ | ‘?=>’)
27822796
* | TypTypeParamClause ‘=>’
27832797
* ColonArgBody ::= indent (CaseClauses | Block) outdent
@@ -2860,7 +2874,7 @@ object Parsers {
28602874
makeParameter(name.asTermName, typedOpt(), Modifiers(), isBackquoted = isBackquoted(id))
28612875
}
28622876
case _ => t
2863-
else isColonLambda match
2877+
else detectColonLambda match
28642878
case Some(parseExpr) =>
28652879
val app =
28662880
atSpan(startOffset(t), in.skipToken()):

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -617,8 +617,8 @@ object Scanners {
617617
&& !statCtdTokens.contains(lastToken)
618618
&& !isTrailingBlankLine
619619

620-
if currentRegion.closedBy == ENDLAMBDA then
621-
insert(ENDLAMBDA, lineOffset)
620+
if currentRegion.closedBy == ENDlambda then
621+
insert(ENDlambda, lineOffset)
622622
else if newlineIsSeparating
623623
&& canEndStatTokens.contains(lastToken)
624624
&& canStartStatTokens.contains(token)
@@ -1685,7 +1685,7 @@ object Scanners {
16851685
case class InParens(prefix: Token, outer: Region) extends Region(prefix + 1)
16861686
case class InBraces(outer: Region) extends Region(RBRACE)
16871687
case class InCase(outer: Region) extends Region(OUTDENT)
1688-
case class SingleLineLambda(outer: Region) extends Region(ENDLAMBDA)
1688+
case class SingleLineLambda(outer: Region) extends Region(ENDlambda)
16891689

16901690
/** A class describing an indentation region.
16911691
* @param width The principal indentation width

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ object Tokens extends TokensCommon {
203203
// A `:` recognized as starting an indentation block
204204
inline val SELFARROW = 90; enter(SELFARROW, "=>") // reclassified ARROW following self-type
205205

206-
inline val ENDLAMBDA = 99; enter(ENDLAMBDA, "end of single-line lambda")
206+
inline val ENDlambda = 99; enter(ENDlambda, "end of single-line lambda")
207207

208208
/** XML mode */
209209
inline val XMLSTART = 100; enter(XMLSTART, "$XMLSTART$<") // TODO: deprecate
@@ -269,7 +269,7 @@ object Tokens extends TokensCommon {
269269
final val canStartStatTokens3: TokenSet = canStartExprTokens3 | mustStartStatTokens | BitSet(
270270
AT, CASE, END)
271271

272-
final val canEndStatTokens: TokenSet = atomicExprTokens | BitSet(TYPE, GIVEN, RPAREN, RBRACE, RBRACKET, OUTDENT, ENDLAMBDA)
272+
final val canEndStatTokens: TokenSet = atomicExprTokens | BitSet(TYPE, GIVEN, RPAREN, RBRACE, RBRACKET, OUTDENT, ENDlambda)
273273

274274
/** Tokens that stop a lookahead scan search for a `<-`, `then`, or `do`.
275275
* Used for disambiguating between old and new syntax.

‎tests/neg/closure-args.check‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414
| Illegal start of toplevel definition
1515
|
1616
| longer explanation available when compiling with `-explain`
17-
-- [E018] Syntax Error: tests/neg/closure-args.scala:18:46 -------------------------------------------------------------
18-
18 |val fs: List[List[Int] => Int] = xs.map: x => case y :: ys => y case Nil => -1 // error
19-
| ^^^^
20-
| expression expected but case found
17+
-- [E018] Syntax Error: tests/neg/closure-args.scala:18:20 -------------------------------------------------------------
18+
18 |val e = xs.map: y => // error
19+
| ^
20+
| expression expected but end of single-line lambda found
2121
|
2222
| longer explanation available when compiling with `-explain`
23+
-- [E040] Syntax Error: tests/neg/closure-args.scala:21:64 -------------------------------------------------------------
24+
21 |val fs: List[List[Int] => Int] = xs.map: x => case y :: ys => y case Nil => -1 // error
25+
| ^^^^
26+
| end of single-line lambda expected, but 'case' found
2327
-- [E008] Not Found Error: tests/neg/closure-args.scala:10:4 -----------------------------------------------------------
2428
8 |val b: Int = xs
2529
9 | .map: x => x

‎tests/neg/closure-args.scala‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ val d = xs
1515

1616
val c = List(xs.map: y => y + y) // error // error // error // error
1717

18+
val e = xs.map: y => // error
19+
y + 1
20+
1821
val fs: List[List[Int] => Int] = xs.map: x => case y :: ys => y case Nil => -1 // error

0 commit comments

Comments
(0)

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