Skip to content

Commit cd27721

Browse files
committed
Remove type currying
This adds back the TypeApply case that was present in Applications.scala. With it is an improved error message that shows a potential fix.
1 parent b7de2b2 commit cd27721

File tree

5 files changed

+24
-22
lines changed

5 files changed

+24
-22
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,7 +3101,7 @@ object Parsers {
31013101

31023102
end typeOrTermParamClause
31033103

3104-
/** DefParamClauses ::= DefParamClause { DefParamClause }
3104+
/** DefParamClauses ::= DefParamClause { DefParamClause } -- and two DefTypeParamClause cannot be adjacent
31053105
*/
31063106
def typeOrTermParamClauses(
31073107
ownerKind: ParamOwner,
@@ -3111,7 +3111,7 @@ object Parsers {
31113111
numLeadParams: Int = 0
31123112
): List[List[TypeDef] | List[ValDef]] =
31133113

3114-
def recur(firstClause: Boolean, numLeadParams: Int): List[List[TypeDef] | List[ValDef]] =
3114+
def recur(firstClause: Boolean, numLeadParams: Int, prevIsTypeClause: Boolean): List[List[TypeDef] | List[ValDef]] =
31153115
newLineOptWhenFollowedBy(LPAREN)
31163116
newLineOptWhenFollowedBy(LBRACKET)
31173117
if in.token == LPAREN then
@@ -3125,13 +3125,18 @@ object Parsers {
31253125
val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit)
31263126
params :: (
31273127
if lastClause then Nil
3128-
else recur(firstClause = false, numLeadParams + params.length))
3128+
else recur(firstClause = false, numLeadParams + params.length, prevIsTypeClause = false))
31293129
else if in.token == LBRACKET then
3130-
typeParamClause(ownerKind) :: recur(firstClause, numLeadParams)
3130+
if prevIsTypeClause then
3131+
syntaxError(
3132+
em"Type parameter lists must be separated by a term or using parameter list",
3133+
in.offset
3134+
)
3135+
typeParamClause(ownerKind) :: recur(firstClause, numLeadParams, prevIsTypeClause = true)
31313136
else Nil
31323137
end recur
31333138

3134-
recur(firstClause = true, numLeadParams = numLeadParams)
3139+
recur(firstClause = true, numLeadParams = numLeadParams, prevIsTypeClause = false)
31353140
end typeOrTermParamClauses
31363141

31373142

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,12 @@ trait Applications extends Compatibility {
11511151
val typedArgs = if (isNamed) typedNamedArgs(tree.args) else tree.args.mapconserve(typedType(_))
11521152
record("typedTypeApply")
11531153
typedExpr(tree.fun, PolyProto(typedArgs, pt)) match {
1154+
case fun: TypeApply if !ctx.isAfterTyper =>
1155+
val function = fun.fun
1156+
val args = (fun.args ++ tree.args).map(_.show).mkString(", ")
1157+
errorTree(tree, em"""illegal repeated type application
1158+
|You might have meant something like:
1159+
|${function}[${args}]""")
11541160
case typedFn =>
11551161
typedFn.tpe.widen match {
11561162
case pt: PolyType =>

docs/_docs/internals/syntax.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ ClsParams ::= ClsParam {‘,’ ClsParam}
361361
ClsParam ::= {Annotation} ValDef(mods, id, tpe, expr) -- point of mods on val/var
362362
[{Modifier} (‘val’ | ‘var’) | ‘inline’] Param
363363
364-
DefParamClauses ::= DefParamClause { DefParamClause }
364+
DefParamClauses ::= DefParamClause { DefParamClause } -- and two DefTypeParamClause cannot be adjacent
365365
DefParamClause ::= DefTypeParamClause
366366
| DefTermParamClause
367367
| UsingParamClause
@@ -427,7 +427,7 @@ Dcl ::= RefineDcl
427427
| ‘var’ VarDcl
428428
ValDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree)
429429
VarDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree)
430-
DefDcl ::= DefSig ‘:’ Type DefDef(_, name, tparams, vparamss, tpe, EmptyTree)
430+
DefDcl ::= DefSig ‘:’ Type DefDef(_, name, paramss, tpe, EmptyTree)
431431
DefSig ::= id [DefParamClauses] [DefImplicitClause]
432432
TypeDcl ::= id [TypeParamClause] {FunParamClause} TypeBounds TypeDefTree(_, name, tparams, bound
433433
[‘=’ Type]

docs/_docs/reference/other-new-features/generalized-method-syntax.md

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ def foo[T, U](x: T)(y: U)(z: Int, s: String)(a: Array[T])(implicit ordInt: Ord[I
1818

1919
### In Scala 3
2020

21-
The new syntax allows any number of type, term and using clause, in any order, optionnaly followed by an implicit clause:
21+
The new syntax allows any number of type clauses, as long as they are not adjacent:
2222
(do note however that [implicit clause are discouraged, in favor of using clauses](https://docs.scala-lang.org/scala3/reference/contextual/relationship-implicits.html))
2323

2424
```scala
25-
def foo[T, U](x: T)(y: U)[V](z: V, s: String)[A](a: Array[A])(implicit List[U])
25+
def foo[T, U](x: T)(y: U)[V](z: V, s: String)(using Ord[Int])[A](a: Array[A])(implicit List[U])
2626
```
2727

2828
### Unchanged
@@ -48,15 +48,6 @@ trait DB {
4848
Note that simply replacing `V` by `k.Value` would not be equivalent. For example, if `k.Value` is `Some[Int]`, only the above allows:
4949
`getOrElse(k)[Option[Int]](None)`, which returns a `Number`.
5050

51-
### Partial Inference
52-
53-
It is now possible to only infer some of the type parameters, this reduces boilerplate at the use site:
54-
```scala
55-
trait StaticSizeList[S <: Int & Singleton, T]
56-
def filled[S <: Int & Singleton][T](x: T): StaticSizeList[S,T] = ???
57-
val helloes = filled[4]("Hello!") // S=4, and T is inferred
58-
```
59-
6051
## Details
6152

6253
### Application
@@ -90,9 +81,9 @@ On the other hand, the `getOrElse` method is recommended as-is, as it cannot be
9081
DefDcl ::= DefSig ‘:’ Type
9182
DefDef ::= DefSig [‘:’ Type] ‘=’ Expr
9283
DefSig ::= id [DefParamClauses] [DefImplicitClause]
93-
DefParamClauses ::= DefParamClause { DefParamClause }
94-
DefParamClause ::= DefTypeParamClause
95-
| DefTermParamClause
84+
DefParamClauses ::= DefParamClause { DefParamClause } -- and two DefTypeParamClause cannot be adjacent
85+
DefParamClause ::= DefTypeParamClause
86+
| DefTermParamClause
9687
| UsingParamClause
9788
DefTypeParamClause::= [nl] ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’
9889
DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds

docs/_docs/reference/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’
350350
ClsParams ::= ClsParam {‘,’ ClsParam}
351351
ClsParam ::= {Annotation} [{Modifier} (‘val’ | ‘var’) | ‘inline’] Param
352352
353-
DefParamClauses ::= DefParamClause { DefParamClause }
353+
DefParamClauses ::= DefParamClause { DefParamClause } -- and two DefTypeParamClause cannot be adjacent
354354
DefParamClause ::= DefTypeParamClause
355355
| DefTermParamClause
356356
| UsingParamClause

0 commit comments

Comments
 (0)