@@ -735,6 +735,7 @@ object Parsers {
735735 * | InfixType
736736 * FunArgTypes ::= InfixType
737737 * | `(' [ FunArgType {`,' FunArgType } ] `)'
738+ * | '(' TypedFunParam {',' TypedFunParam } ')'
738739 */
739740 def typ (): Tree = {
740741 val start = in.offset
@@ -745,6 +746,16 @@ object Parsers {
745746 val t = typ()
746747 if (isImplicit) new ImplicitFunction (params, t) else Function (params, t)
747748 }
749+ def funArgTypesRest (first : Tree , following : () => Tree ) = {
750+ val buf = new ListBuffer [Tree ] += first
751+ while (in.token == COMMA ) {
752+ in.nextToken()
753+ buf += following()
754+ }
755+ buf.toList
756+ }
757+ var isValParamList = false
758+
748759 val t =
749760 if (in.token == LPAREN ) {
750761 in.nextToken()
@@ -754,10 +765,19 @@ object Parsers {
754765 }
755766 else {
756767 openParens.change(LPAREN , 1 )
757- val ts = commaSeparated(funArgType)
768+ val paramStart = in.offset
769+ val ts = funArgType() match {
770+ case Ident (name) if name != tpnme.WILDCARD && in.token == COLON =>
771+ isValParamList = true
772+ funArgTypesRest(
773+ typedFunParam(paramStart, name.toTermName),
774+ () => typedFunParam(in.offset, ident()))
775+ case t =>
776+ funArgTypesRest(t, funArgType)
777+ }
758778 openParens.change(LPAREN , - 1 )
759779 accept(RPAREN )
760- if (isImplicit || in.token == ARROW ) functionRest(ts)
780+ if (isImplicit || isValParamList || in.token == ARROW ) functionRest(ts)
761781 else {
762782 for (t <- ts)
763783 if (t.isInstanceOf [ByNameTypeTree ])
@@ -790,6 +810,12 @@ object Parsers {
790810 }
791811 }
792812
813+ /** TypedFunParam ::= id ':' Type */
814+ def typedFunParam (start : Offset , name : TermName ): Tree = atPos(start) {
815+ accept(COLON )
816+ makeParameter(name, typ(), Modifiers (Param ))
817+ }
818+
793819 /** InfixType ::= RefinedType {id [nl] refinedType}
794820 */
795821 def infixType (): Tree = infixTypeRest(refinedType())
0 commit comments