Skip to content

Commit 66b6280

Browse files
committed
Add syntax for dependent function types
1 parent 8558b4d commit 66b6280

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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())

docs/docs/internals/syntax.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ Type ::= [‘implicit’] FunArgTypes ‘=>’ Type
122122
| InfixType
123123
FunArgTypes ::= InfixType
124124
| ‘(’ [ FunArgType {‘,’ FunArgType } ] ‘)’
125+
| '(' TypedFunParam {',' TypedFunParam } ')'
126+
TypedFunParam ::= id ':' Type
125127
InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
126128
RefinedType ::= WithType {[nl] Refinement} RefinedTypeTree(t, ds)
127129
WithType ::= AnnotType {‘with’ AnnotType} (deprecated)

0 commit comments

Comments
 (0)