Skip to content

Commit 6113a0f

Browse files
committed
Keep correct track of parameter counts in extension clauses
Fixes #11020
1 parent 5672999 commit 6113a0f

File tree

3 files changed

+22
-15
lines changed

3 files changed

+22
-15
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ object desugar {
253253

254254
def addDefaultGetters(meth: DefDef)(using Context): Tree =
255255

256-
/** The longest prefix of parameter lists in =paramss whose total number of
256+
/** The longest prefix of parameter lists in paramss whose total number of
257257
* ValDefs does not exceed `n`
258258
*/
259259
def takeUpTo(paramss: List[ParamClause], n: Int): List[ParamClause] = paramss match

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3020,7 +3020,8 @@ object Parsers {
30203020
*/
30213021
def paramClauses(ofClass: Boolean = false,
30223022
ofCaseClass: Boolean = false,
3023-
givenOnly: Boolean = false): List[List[ValDef]] =
3023+
givenOnly: Boolean = false,
3024+
numLeadParams: Int = 0): List[List[ValDef]] =
30243025

30253026
def recur(firstClause: Boolean, nparams: Int): List[List[ValDef]] =
30263027
newLineOptWhenFollowedBy(LPAREN)
@@ -3039,7 +3040,7 @@ object Parsers {
30393040
else Nil
30403041
end recur
30413042

3042-
recur(firstClause = true, 0)
3043+
recur(firstClause = true, numLeadParams)
30433044
end paramClauses
30443045

30453046
/* -------- DEFS ------------------------------------------- */
@@ -3244,7 +3245,7 @@ object Parsers {
32443245
* DefSig ::= id [DefTypeParamClause] DefParamClauses
32453246
* | ExtParamClause [nl] [‘.’] id DefParamClauses
32463247
*/
3247-
def defDefOrDcl(start: Offset, mods: Modifiers): DefDef = atSpan(start, nameStart) {
3248+
def defDefOrDcl(start: Offset, mods: Modifiers, numLeadParams: Int = 0): DefDef = atSpan(start, nameStart) {
32483249

32493250
def scala2ProcedureSyntax(resultTypeStr: String) =
32503251
def toInsert =
@@ -3261,7 +3262,7 @@ object Parsers {
32613262

32623263
if (in.token == THIS) {
32633264
in.nextToken()
3264-
val vparamss = paramClauses()
3265+
val vparamss = paramClauses(numLeadParams = numLeadParams)
32653266
if (vparamss.isEmpty || vparamss.head.take(1).exists(_.mods.isOneOf(GivenOrImplicit)))
32663267
in.token match {
32673268
case LBRACKET => syntaxError("no type parameters allowed here")
@@ -3280,7 +3281,7 @@ object Parsers {
32803281
val ident = termIdent()
32813282
var name = ident.name.asTermName
32823283
val tparams = typeParamClauseOpt(ParamOwner.Def)
3283-
val vparamss = paramClauses()
3284+
val vparamss = paramClauses(numLeadParams = numLeadParams)
32843285
var tpt = fromWithinReturnType {
32853286
if in.token == COLONEOL then in.token = COLON
32863287
// a hack to allow
@@ -3566,24 +3567,23 @@ object Parsers {
35663567
val start = in.skipToken()
35673568
val tparams = typeParamClauseOpt(ParamOwner.Def)
35683569
val leadParamss = ListBuffer[List[ValDef]]()
3569-
var nparams = 0
3570+
def nparams = leadParamss.map(_.length).sum
35703571
while
35713572
val extParams = paramClause(nparams, prefix = true)
35723573
leadParamss += extParams
3573-
nparams += extParams.length
35743574
isUsingClause(extParams)
35753575
do ()
3576-
leadParamss ++= paramClauses(givenOnly = true)
3576+
leadParamss ++= paramClauses(givenOnly = true, numLeadParams = nparams)
35773577
if in.token == COLON then
35783578
syntaxError("no `:` expected here")
35793579
in.nextToken()
35803580
val methods =
35813581
if isDefIntro(modifierTokens) then
3582-
extMethod() :: Nil
3582+
extMethod(nparams) :: Nil
35833583
else
35843584
in.observeIndented()
35853585
newLineOptWhenFollowedBy(LBRACE)
3586-
if in.isNestedStart then inDefScopeBraces(extMethods())
3586+
if in.isNestedStart then inDefScopeBraces(extMethods(nparams))
35873587
else { syntaxError("Extension without extension methods"); Nil }
35883588
val result = atSpan(start)(ExtMethods(joinParams(tparams, leadParamss.toList), methods))
35893589
val comment = in.getDocComment(start)
@@ -3595,20 +3595,20 @@ object Parsers {
35953595

35963596
/** ExtMethod ::= {Annotation [nl]} {Modifier} ‘def’ DefDef
35973597
*/
3598-
def extMethod(): DefDef =
3598+
def extMethod(numLeadParams: Int): DefDef =
35993599
val start = in.offset
36003600
val mods = defAnnotsMods(modifierTokens)
36013601
accept(DEF)
3602-
defDefOrDcl(start, mods)
3602+
defDefOrDcl(start, mods, numLeadParams)
36033603

36043604
/** ExtMethods ::= ExtMethod | [nl] ‘{’ ExtMethod {semi ExtMethod ‘}’
36053605
*/
3606-
def extMethods(): List[DefDef] = checkNoEscapingPlaceholders {
3606+
def extMethods(numLeadParams: Int): List[DefDef] = checkNoEscapingPlaceholders {
36073607
val meths = new ListBuffer[DefDef]
36083608
val exitOnError = false
36093609
while !isStatSeqEnd && !exitOnError do
36103610
setLastStatOffset()
3611-
meths += extMethod()
3611+
meths += extMethod(numLeadParams)
36123612
acceptStatSepUnlessAtEnd(meths)
36133613
if meths.isEmpty then syntaxError("`def` expected")
36143614
meths.toList

tests/pos/i11020.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait Bar
2+
trait Baz
3+
trait B[X]
4+
extension (using Bar)(s: String)(using Baz) def foo = ???
5+
extension (using Bar)(s: String) def bar(using Baz) = ???
6+
extension [T: B](s: T) def baz [U: B](x: Int) = ???
7+

0 commit comments

Comments
 (0)