@@ -444,9 +444,12 @@ object Parsers {
444
444
445
445
/** Convert tree to formal parameter
446
446
*/
447
- def convertToParam (tree : Tree , mods : Modifiers , expected : String = " formal parameter" ): ValDef = tree match {
447
+ def convertToParam (tree : Tree , mods : Modifiers , expected : String = " formal parameter" ): ValDef = tree match
448
+ case param : ValDef =>
449
+ param.withMods(param.mods | mods.flags)
448
450
case id @ Ident (name) =>
449
451
makeParameter(name.asTermName, TypeTree (), mods, isBackquoted = isBackquoted(id)).withSpan(tree.span)
452
+ // the following three cases are needed only for 2.x parameters without enclosing parentheses
450
453
case Typed (_, tpt : TypeBoundsTree ) =>
451
454
syntaxError(s " not a legal $expected" , tree.span)
452
455
makeParameter(nme.ERROR , tree, mods)
@@ -455,7 +458,6 @@ object Parsers {
455
458
case _ =>
456
459
syntaxError(s " not a legal $expected" , tree.span)
457
460
makeParameter(nme.ERROR , tree, mods)
458
- }
459
461
460
462
/** Convert (qual)ident to type identifier
461
463
*/
@@ -913,6 +915,21 @@ object Parsers {
913
915
}
914
916
}
915
917
918
+ /** When encountering a `:`, is that in the first binding of a lambda?
919
+ * @pre location of the enclosing expression is `InParens`, so there is am open `(`.
920
+ */
921
+ def followingisLambdaParams () =
922
+ val lookahead = in.LookaheadScanner ()
923
+ lookahead.nextToken()
924
+ while lookahead.token != RPAREN && lookahead.token != EOF do
925
+ if lookahead.token == LPAREN then lookahead.skipParens()
926
+ else lookahead.nextToken()
927
+ lookahead.token == RPAREN
928
+ && {
929
+ lookahead.nextToken()
930
+ lookahead.isArrow
931
+ }
932
+
916
933
/* --------- OPERAND/OPERATOR STACK --------------------------------------- */
917
934
918
935
var opStack : List [OpInfo ] = Nil
@@ -2292,7 +2309,7 @@ object Parsers {
2292
2309
placeholderParams = param :: placeholderParams
2293
2310
atSpan(start) { Ident (pname) }
2294
2311
case LPAREN =>
2295
- atSpan(in.offset) { makeTupleOrParens(inParens(exprsInParensOpt ())) }
2312
+ atSpan(in.offset) { makeTupleOrParens(inParens(exprsInParensOrBindings ())) }
2296
2313
case LBRACE | INDENT =>
2297
2314
canApply = false
2298
2315
blockExpr()
@@ -2362,7 +2379,17 @@ object Parsers {
2362
2379
val app = applyToClosure(t, in.offset, convertToParams(termIdent()))
2363
2380
simpleExprRest(app, location, canApply = true )
2364
2381
case _ =>
2365
- t
2382
+ t match
2383
+ case id @ Ident (name)
2384
+ if in.isColon() && location == Location .InParens && followingisLambdaParams() =>
2385
+ if name.is(WildcardParamName ) then
2386
+ assert(name == placeholderParams.head.name)
2387
+ placeholderParams = placeholderParams.tail
2388
+ atSpan(startOffset(id)) {
2389
+ makeParameter(name.asTermName, typedOpt(), Modifiers (), isBackquoted = isBackquoted(id))
2390
+ }
2391
+ case _ =>
2392
+ t
2366
2393
}
2367
2394
}
2368
2395
@@ -2396,9 +2423,20 @@ object Parsers {
2396
2423
}
2397
2424
2398
2425
/** ExprsInParens ::= ExprInParens {`,' ExprInParens}
2426
+ * Bindings ::= Binding {`,' Binding}
2399
2427
*/
2400
- def exprsInParensOpt (): List [Tree ] =
2401
- if (in.token == RPAREN ) Nil else commaSeparated(exprInParens)
2428
+ def exprsInParensOrBindings (): List [Tree ] =
2429
+ if in.token == RPAREN then Nil
2430
+ else in.currentRegion.withCommasExpected {
2431
+ var isFormalParams = false
2432
+ def exprOrBinding () =
2433
+ if isFormalParams then binding(Modifiers ())
2434
+ else
2435
+ val t = exprInParens()
2436
+ if t.isInstanceOf [ValDef ] then isFormalParams = true
2437
+ t
2438
+ commaSeparatedRest(exprOrBinding(), exprOrBinding)
2439
+ }
2402
2440
2403
2441
/** ParArgumentExprs ::= `(' [‘using’] [ExprsInParens] `)'
2404
2442
* | `(' [ExprsInParens `,'] PostfixExpr `*' ')'
0 commit comments