Skip to content

Commit e538e89

Browse files
committed
Don't allow two type parameter sections for extension methods
Don't allow extension methods to have type parameters if collective type parameters were already given. The reason to disallow is that we don't support multiple consecutive type argument sections yet. And merging two type parameter sections into one would break a future extension where we do allow multiple consecutive type argument sections.
1 parent 7a2cff6 commit e538e89

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3372,11 +3372,14 @@ object Parsers {
33723372
case _ =>
33733373
syntaxError(em"extension clause must start with a single regular parameter", start)
33743374

3375-
def checkExtensionMethod(stat: Tree): Unit = stat match {
3375+
def checkExtensionMethod(tparams: List[Tree], stat: Tree): Unit = stat match {
33763376
case stat: DefDef =>
33773377
if stat.mods.is(Extension) then
33783378
syntaxError(i"no extension method allowed here since leading parameter was already given", stat.span)
3379-
case _ =>
3379+
else if tparams.nonEmpty && stat.tparams.nonEmpty then
3380+
syntaxError(i"extension method cannot have type parameters since some were already given previously",
3381+
stat.tparams.head.span)
3382+
case stat =>
33803383
syntaxError(i"extension clause can only define methods", stat.span)
33813384
}
33823385

@@ -3406,7 +3409,7 @@ object Parsers {
34063409
possibleTemplateStart()
34073410
val templ = templateBodyOpt(
34083411
makeConstructor(tparams, extParams :: givenParamss), Nil, Nil)
3409-
templ.body.foreach(checkExtensionMethod)
3412+
templ.body.foreach(checkExtensionMethod(tparams, _))
34103413
ModuleDef(name, templ)
34113414
else
34123415
var tparams: List[TypeDef] = Nil
@@ -3467,7 +3470,7 @@ object Parsers {
34673470
vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal)))
34683471
val templ = templateBodyOpt(makeConstructor(tparams, vparamss), parents, Nil)
34693472
if hasExtensionParams then
3470-
templ.body.foreach(checkExtensionMethod)
3473+
templ.body.foreach(checkExtensionMethod(tparams, _))
34713474
ModuleDef(name, templ)
34723475
else if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ)
34733476
else TypeDef(name.toTypeName, templ)

tests/neg/i6900.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object Test2 {
2+
3+
// Works with extension method
4+
given extension [A](a: A) with
5+
def foo[C]: C => A = _ => a // error: extension method cannot have type parameters
6+
7+
1.foo.foo
8+
9+
// ... but have to pass 2 parameters
10+
1.foo.foo[Any => Int, String]
11+
1.foo[Int, String].foo
12+
1.foo[Int, String].foo[String => Int, String]
13+
14+
}
15+

0 commit comments

Comments
 (0)