@@ -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)
@@ -457,7 +460,6 @@ object Parsers {
457
460
case _ =>
458
461
syntaxError(s " not a legal $expected" , tree.span)
459
462
makeParameter(nme.ERROR , tree, mods)
460
- }
461
463
462
464
/** Convert (qual)ident to type identifier
463
465
*/
@@ -915,6 +917,21 @@ object Parsers {
915
917
}
916
918
}
917
919
920
+ /** When encountering a `:`, is that in the first binding of a lambda?
921
+ * @pre location of the enclosing expression is `InParens`, so there is am open `(`.
922
+ */
923
+ def followingisLambdaParams () =
924
+ val lookahead = in.LookaheadScanner ()
925
+ lookahead.nextToken()
926
+ while lookahead.token != RPAREN && lookahead.token != EOF do
927
+ if lookahead.token == LPAREN then lookahead.skipParens()
928
+ else lookahead.nextToken()
929
+ lookahead.token == RPAREN
930
+ && {
931
+ lookahead.nextToken()
932
+ lookahead.isArrow
933
+ }
934
+
918
935
/* --------- OPERAND/OPERATOR STACK --------------------------------------- */
919
936
920
937
var opStack : List [OpInfo ] = Nil
@@ -2283,7 +2300,7 @@ object Parsers {
2283
2300
placeholderParams = param :: placeholderParams
2284
2301
atSpan(start) { Ident (pname) }
2285
2302
case LPAREN =>
2286
- atSpan(in.offset) { makeTupleOrParens(inParens(exprsInParensOpt ())) }
2303
+ atSpan(in.offset) { makeTupleOrParens(inParens(exprsInParensOrBindings ())) }
2287
2304
case LBRACE | INDENT =>
2288
2305
canApply = false
2289
2306
blockExpr()
@@ -2353,7 +2370,17 @@ object Parsers {
2353
2370
val app = applyToClosure(t, in.offset, convertToParams(termIdent()))
2354
2371
simpleExprRest(app, location, canApply = true )
2355
2372
case _ =>
2356
- t
2373
+ t match
2374
+ case id @ Ident (name)
2375
+ if in.isColon() && location == Location .InParens && followingisLambdaParams() =>
2376
+ if name.is(WildcardParamName ) then
2377
+ assert(name == placeholderParams.head.name)
2378
+ placeholderParams = placeholderParams.tail
2379
+ atSpan(startOffset(id)) {
2380
+ makeParameter(name.asTermName, typedOpt(), Modifiers (), isBackquoted = isBackquoted(id))
2381
+ }
2382
+ case _ =>
2383
+ t
2357
2384
}
2358
2385
}
2359
2386
@@ -2387,9 +2414,20 @@ object Parsers {
2387
2414
}
2388
2415
2389
2416
/** ExprsInParens ::= ExprInParens {`,' ExprInParens}
2417
+ * Bindings ::= Binding {`,' Binding}
2390
2418
*/
2391
- def exprsInParensOpt (): List [Tree ] =
2392
- if (in.token == RPAREN ) Nil else commaSeparated(exprInParens)
2419
+ def exprsInParensOrBindings (): List [Tree ] =
2420
+ if in.token == RPAREN then Nil
2421
+ else in.currentRegion.withCommasExpected {
2422
+ var isFormalParams = false
2423
+ def exprOrBinding () =
2424
+ if isFormalParams then binding(Modifiers ())
2425
+ else
2426
+ val t = exprInParens()
2427
+ if t.isInstanceOf [ValDef ] then isFormalParams = true
2428
+ t
2429
+ commaSeparatedRest(exprOrBinding(), exprOrBinding)
2430
+ }
2393
2431
2394
2432
/** ParArgumentExprs ::= `(' [‘using’] [ExprsInParens] `)'
2395
2433
* | `(' [ExprsInParens `,'] PostfixExpr `*' ')'
0 commit comments