Skip to content

Commit 8385c17

Browse files
committed
Parsing of singleton parameters in type definitions
1 parent 900ffc4 commit 8385c17

File tree

4 files changed

+46
-24
lines changed

4 files changed

+46
-24
lines changed

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,14 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
486486
ValDef(nme.syntheticParamName(n), if (tpt == null) TypeTree() else tpt, EmptyTree)
487487
.withFlags(flags)
488488

489-
def lambdaAbstract(tparams: List[TypeDef], tpt: Tree)(implicit ctx: Context): Tree =
490-
if (tparams.isEmpty) tpt else LambdaTypeTree(tparams, tpt)
489+
def lambdaAbstract(params: List[ValDef] | List[TypeDef], tpt: Tree)(using Context): Tree =
490+
params match
491+
case Nil => tpt
492+
case (vd: ValDef) :: _ => TermLambdaTypeTree(params.asInstanceOf[List[ValDef]], tpt)
493+
case _ => LambdaTypeTree(params.asInstanceOf[List[TypeDef]], tpt)
494+
495+
def lambdaAbstractAll(paramss: List[List[ValDef] | List[TypeDef]], tpt: Tree)(using Context): Tree =
496+
paramss.foldRight(tpt)(lambdaAbstract)
491497

492498
/** A reference to given definition. If definition is a repeated
493499
* parameter, the reference will be a repeated argument.

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

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,17 +1358,17 @@ object Parsers {
13581358
case _ => false
13591359
}
13601360

1361-
/** Type ::= FunType
1362-
* | HkTypeParamClause ‘=>>’ Type
1363-
* | ‘(’ TypedFunParams ‘)’ ‘=>>’ Type
1364-
* | MatchType
1365-
* | InfixType
1366-
* FunType ::= (MonoFunType | PolyFunType)
1367-
* MonoFunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type
1368-
* PolyFunType ::= HKTypeParamClause '=>' Type
1369-
* FunArgTypes ::= InfixType
1370-
* | `(' [ [ ‘[using]’ ‘['erased'] FunArgType {`,' FunArgType } ] `)'
1371-
* | '(' [ ‘[using]’ ‘['erased'] TypedFunParam {',' TypedFunParam } ')'
1361+
/** Type ::= FunType
1362+
* | HkTypeParamClause ‘=>>’ Type
1363+
* | FunParamClause ‘=>>’ Type
1364+
* | MatchType
1365+
* | InfixType
1366+
* FunType ::= (MonoFunType | PolyFunType)
1367+
* MonoFunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type
1368+
* PolyFunType ::= HKTypeParamClause '=>' Type
1369+
* FunArgTypes ::= InfixType
1370+
* | `(' [ [ ‘[using]’ ‘['erased'] FunArgType {`,' FunArgType } ] `)'
1371+
* | '(' [ ‘[using]’ ‘['erased'] TypedFunParam {',' TypedFunParam } ')'
13721372
*/
13731373
def typ(): Tree = {
13741374
val start = in.offset
@@ -1511,10 +1511,19 @@ object Parsers {
15111511
Span(start, start + nme.IMPLICITkw.asSimpleName.length)
15121512

15131513
/** TypedFunParam ::= id ':' Type */
1514-
def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): Tree = atSpan(start) {
1515-
accept(COLON)
1516-
makeParameter(name, typ(), mods | Param)
1517-
}
1514+
def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): ValDef =
1515+
atSpan(start) {
1516+
accept(COLON)
1517+
makeParameter(name, typ(), mods | Param)
1518+
}
1519+
1520+
/** FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’
1521+
*/
1522+
def funParamClause(): List[ValDef] =
1523+
inParens(commaSeparated(() => typedFunParam(in.offset, ident())))
1524+
1525+
def funParamClauses(): List[List[ValDef]] =
1526+
if in.token == LPAREN then funParamClause() :: funParamClauses() else Nil
15181527

15191528
/** InfixType ::= RefinedType {id [nl] RefinedType}
15201529
*/
@@ -3394,15 +3403,16 @@ object Parsers {
33943403
argumentExprss(mkApply(Ident(nme.CONSTRUCTOR), argumentExprs()))
33953404
}
33963405

3397-
/** TypeDcl ::= id [TypeParamClause] TypeBounds [‘=’ Type]
3406+
/** TypeDcl ::= id [TypeParamClause] {FunParamClause} TypeBounds [‘=’ Type]
33983407
*/
33993408
def typeDefOrDcl(start: Offset, mods: Modifiers): Tree = {
34003409
newLinesOpt()
34013410
atSpan(start, nameStart) {
34023411
val nameIdent = typeIdent()
34033412
val tparams = typeParamClauseOpt(ParamOwner.Type)
3413+
val vparamss = funParamClauses()
34043414
def makeTypeDef(rhs: Tree): Tree = {
3405-
val rhs1 = lambdaAbstract(tparams, rhs)
3415+
val rhs1 = lambdaAbstractAll(tparams :: vparamss, rhs)
34063416
val tdef = TypeDef(nameIdent.name.toTypeName, rhs1)
34073417
if (nameIdent.isBackquoted)
34083418
tdef.pushAttachment(Backquoted, ())

docs/docs/internals/syntax.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,16 @@ ClassQualifier ::= ‘[’ id ‘]’
138138
### Types
139139
```ebnf
140140
Type ::= FunType
141-
| HkTypeParamClause ‘=>>’ Type TypeLambda(ps, t)
142-
| ‘(’ TypedFunParams ‘)’ ‘=>>’ Type TypeLambda(ps, t)
141+
| HkTypeParamClause ‘=>>’ Type LambdaTypeTree(ps, t)
142+
| FunParamClause ‘=>>’ Type TermLambdaTypeTree(ps, t)
143143
| MatchType
144144
| InfixType
145145
FunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type Function(ts, t)
146146
| HKTypeParamClause '=>' Type PolyFunction(ps, t)
147147
FunArgTypes ::= InfixType
148148
| ‘(’ [ FunArgType {‘,’ FunArgType } ] ‘)’
149-
| ‘(’ TypedFunParams ‘)’
150-
TypedFunParams ::= TypedFunParam {‘,’ TypedFunParam }
149+
| FunParamClause
150+
FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’
151151
TypedFunParam ::= id ‘:’ Type
152152
MatchType ::= InfixType `match` ‘{’ TypeCaseClauses ‘}’
153153
InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
@@ -372,7 +372,8 @@ VarDcl ::= ids ‘:’ Type
372372
DefDcl ::= DefSig ‘:’ Type DefDef(_, name, tparams, vparamss, tpe, EmptyTree)
373373
DefSig ::= id [DefTypeParamClause] DefParamClauses
374374
| ExtParamClause {nl} [‘.’] id DefParamClauses
375-
TypeDcl ::= id [TypeParamClause] SubtypeBounds [‘=’ Type] TypeDefTree(_, name, tparams, bound
375+
TypeDcl ::= id [TypeParamClause] {FunParamClause} SubtypeBounds TypeDefTree(_, name, tparams, bound
376+
[‘=’ Type]
376377
377378
Def ::= ‘val’ PatDef
378379
| ‘var’ VarDef

tests/neg/deptypes.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11

22
type Vec[T] = (n: Int) =>> Array[T] // error: needs to be enabled
3+
4+
type Matrix[T](m: Int, n: Int) = Vec[Vec[T](n)](m) // error: needs to be enabled
5+
6+
type Tensor2[T](m: Int)(n: Int) = Matrix[T](m, n) // error: needs to be enabled
7+
38
val x: Vec[Int](10) = ??? // error: needs to be enabled
49
val n = 10
510
type T = Vec[String](n) // error: needs to be enabled

0 commit comments

Comments
 (0)