Skip to content

Commit e64d3d1

Browse files
authored
Merge pull request #11748 from lampepfl/revert-11623-master
Revert "Fix desugaring of context bounds in extensions"
2 parents ff218b3 + 6158a2a commit e64d3d1

10 files changed

+88
-95
lines changed

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

Lines changed: 55 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -218,32 +218,15 @@ object desugar {
218218
* def f$default$2[T](x: Int) = x + "m"
219219
*/
220220
private def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false)(using Context): Tree =
221-
addDefaultGetters(elimContextBounds(Nil, meth, isPrimaryConstructor))
221+
addDefaultGetters(elimContextBounds(meth, isPrimaryConstructor))
222222

223-
private def defDef(extParamss: List[ParamClause], meth: DefDef)(using Context): Tree =
224-
addDefaultGetters(elimContextBounds(extParamss, meth, false))
225-
226-
private def elimContextBounds(extParamss: List[ParamClause], meth: DefDef, isPrimaryConstructor: Boolean)(using Context): DefDef =
223+
private def elimContextBounds(meth: DefDef, isPrimaryConstructor: Boolean)(using Context): DefDef =
227224
val DefDef(_, paramss, tpt, rhs) = meth
228-
229-
rhs match
230-
case MacroTree(call) =>
231-
cpy.DefDef(meth)(rhs = call).withMods(meth.mods | Macro | Erased)
232-
case _ =>
233-
cpy.DefDef(meth)(
234-
name = normalizeName(meth, tpt).asTermName,
235-
paramss =
236-
elimContextBounds(extParamss, isPrimaryConstructor, true) ++
237-
elimContextBounds(paramss, isPrimaryConstructor, false)
238-
)
239-
end elimContextBounds
240-
241-
private def elimContextBounds(paramss: List[ParamClause], isPrimaryConstructor: Boolean, ext: Boolean)(using Context): List[ParamClause] =
242225
val evidenceParamBuf = ListBuffer[ValDef]()
243226

244227
def desugarContextBounds(rhs: Tree): Tree = rhs match
245228
case ContextBounds(tbounds, cxbounds) =>
246-
val iflag = if ext || sourceVersion.isAtLeast(`future`) then Given else Implicit
229+
val iflag = if sourceVersion.isAtLeast(`future`) then Given else Implicit
247230
evidenceParamBuf ++= makeImplicitParameters(
248231
cxbounds, iflag, forPrimaryConstructor = isPrimaryConstructor)
249232
tbounds
@@ -257,7 +240,15 @@ object desugar {
257240
tparam => cpy.TypeDef(tparam)(rhs = desugarContextBounds(tparam.rhs))
258241
}(identity)
259242

260-
addEvidenceParams(paramssNoContextBounds, evidenceParamBuf.toList)
243+
rhs match
244+
case MacroTree(call) =>
245+
cpy.DefDef(meth)(rhs = call).withMods(meth.mods | Macro | Erased)
246+
case _ =>
247+
addEvidenceParams(
248+
cpy.DefDef(meth)(
249+
name = normalizeName(meth, tpt).asTermName,
250+
paramss = paramssNoContextBounds),
251+
evidenceParamBuf.toList)
261252
end elimContextBounds
262253

263254
def addDefaultGetters(meth: DefDef)(using Context): Tree =
@@ -357,22 +348,22 @@ object desugar {
357348
adaptToExpectedTpt(tree)
358349
}
359350

360-
/** Add all evidence parameters in `params` as implicit parameters to `paramss`.
361-
* If the parameters of `paramss` end in an implicit parameter list or using clause,
351+
/** Add all evidence parameters in `params` as implicit parameters to `meth`.
352+
* If the parameters of `meth` end in an implicit parameter list or using clause,
362353
* evidence parameters are added in front of that list. Otherwise they are added
363354
* as a separate parameter clause.
364355
*/
365-
366-
private def addEvidenceParams(paramss: List[ParamClause], params: List[ValDef])(using Context): List[ParamClause] =
367-
paramss.reverse match
368-
case ValDefs(vparams @ (vparam :: _)) :: rparamss if vparam.mods.isOneOf(GivenOrImplicit) =>
369-
((params ++ vparams) :: rparamss).reverse
370-
case _ =>
371-
params match
372-
case Nil =>
373-
paramss
374-
case evidenceParams =>
375-
paramss :+ evidenceParams
356+
private def addEvidenceParams(meth: DefDef, params: List[ValDef])(using Context): DefDef =
357+
params match
358+
case Nil =>
359+
meth
360+
case evidenceParams =>
361+
val paramss1 = meth.paramss.reverse match
362+
case ValDefs(vparams @ (vparam :: _)) :: rparamss if vparam.mods.isOneOf(GivenOrImplicit) =>
363+
((evidenceParams ++ vparams) :: rparamss).reverse
364+
case _ =>
365+
meth.paramss :+ evidenceParams
366+
cpy.DefDef(meth)(paramss = paramss1)
376367

377368
/** The implicit evidence parameters of `meth`, as generated by `desugar.defDef` */
378369
private def evidenceParams(meth: DefDef)(using Context): List[ValDef] =
@@ -496,8 +487,9 @@ object desugar {
496487
case ddef: DefDef if ddef.name.isConstructorName =>
497488
decompose(
498489
defDef(
499-
cpy.DefDef(ddef)(paramss = addEvidenceParams(joinParams(constrTparams, ddef.paramss),
500-
evidenceParams(constr1).map(toDefParam(_, keepAnnotations = false, keepDefault = false))))))
490+
addEvidenceParams(
491+
cpy.DefDef(ddef)(paramss = joinParams(constrTparams, ddef.paramss)),
492+
evidenceParams(constr1).map(toDefParam(_, keepAnnotations = false, keepDefault = false)))))
501493
case stat =>
502494
stat
503495
}
@@ -907,29 +899,34 @@ object desugar {
907899
/** Transform extension construct to list of extension methods */
908900
def extMethods(ext: ExtMethods)(using Context): Tree = flatTree {
909901
for mdef <- ext.methods yield
910-
def ret(ess: List[ParamClause], mss: List[ParamClause]) =
911-
defDef(
912-
ess,
913-
cpy.DefDef(mdef)(
914-
name = normalizeName(mdef, ext).asTermName,
915-
paramss = mss
916-
).withMods(mdef.mods | ExtensionMethod)
917-
)
918-
mdef.paramss match
919-
case params1 :: paramss1 if mdef.name.isRightAssocOperatorName =>
920-
def badRightAssoc(problem: String) =
921-
report.error(i"right-associative extension method $problem", mdef.srcPos)
922-
ret(ext.paramss, mdef.paramss)
923-
params1 match
924-
case ValDefs(vparam :: Nil) =>
925-
if !vparam.mods.is(Given) then
926-
val (leadingUsing, otherExtParamss) = ext.paramss.span(isUsingOrTypeParamClause)
927-
ret(Nil, leadingUsing ::: params1 :: otherExtParamss ::: paramss1)
928-
else badRightAssoc("cannot start with using clause")
902+
defDef(
903+
cpy.DefDef(mdef)(
904+
name = normalizeName(mdef, ext).asTermName,
905+
paramss = mdef.paramss match
906+
case params1 :: paramss1 if mdef.name.isRightAssocOperatorName =>
907+
def badRightAssoc(problem: String) =
908+
report.error(i"right-associative extension method $problem", mdef.srcPos)
909+
ext.paramss ++ mdef.paramss
910+
def noVParam = badRightAssoc("must start with a single parameter")
911+
def checkVparam(params: ParamClause) = params match
912+
case ValDefs(vparam :: Nil) =>
913+
if !vparam.mods.is(Given) then
914+
val (leadingUsing, otherExtParamss) = ext.paramss.span(isUsingOrTypeParamClause)
915+
leadingUsing ::: params1 :: otherExtParamss ::: paramss1
916+
else badRightAssoc("cannot start with using clause")
917+
case _ =>
918+
noVParam
919+
params1 match
920+
case TypeDefs(_) => paramss1 match
921+
case params2 :: _ => checkVparam(params2)
922+
case _ => noVParam
923+
case _ =>
924+
checkVparam(params1)
925+
929926
case _ =>
930-
badRightAssoc("must start with a single parameter")
931-
case _ =>
932-
ret(ext.paramss, mdef.paramss)
927+
ext.paramss ++ mdef.paramss
928+
).withMods(mdef.mods | ExtensionMethod)
929+
)
933930
}
934931

935932
/** Transforms

tests/neg/i10901.check

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
-- [E008] Not Found Error: tests/neg/i10901.scala:45:38 ----------------------------------------------------------------
22
45 | val pos1: Point2D[Int,Double] = x º y // error
33
| ^^^
4-
|value º is not a member of object BugExp4Point2D.IntT.
5-
|An extension method was tried, but could not be fully constructed:
4+
| value º is not a member of object BugExp4Point2D.IntT.
5+
| An extension method was tried, but could not be fully constructed:
66
|
7-
| º(x) failed with
7+
| º(x) failed with
88
|
9-
| Ambiguous overload. The overloaded alternatives of method º in object dsl with types
10-
| [T1, T2]
11-
| (x: BugExp4Point2D.ColumnType[T1])
12-
| (y: BugExp4Point2D.ColumnType[T2])(using x$3: Numeric[T1], x$4: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
13-
| [T1, T2]
14-
| (x: T1)(y: BugExp4Point2D.ColumnType[T2])(using x$3: Numeric[T1], x$4: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
15-
| both match arguments ((x : BugExp4Point2D.IntT.type))
9+
| Ambiguous overload. The overloaded alternatives of method º in object dsl with types
10+
| [T1, T2]
11+
| (x: BugExp4Point2D.ColumnType[T1])
12+
| (y: BugExp4Point2D.ColumnType[T2])
13+
| (implicit evidence$7: Numeric[T1], evidence$8: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
14+
| [T1, T2]
15+
| (x: T1)
16+
| (y: BugExp4Point2D.ColumnType[T2])
17+
| (implicit evidence$5: Numeric[T1], evidence$6: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
18+
| both match arguments ((x : BugExp4Point2D.IntT.type))
1619
-- [E008] Not Found Error: tests/neg/i10901.scala:48:38 ----------------------------------------------------------------
1720
48 | val pos4: Point2D[Int,Double] = x º 201.1 // error
1821
| ^^^
@@ -23,8 +26,9 @@
2326
|
2427
| Ambiguous overload. The overloaded alternatives of method º in object dsl with types
2528
| [T1, T2]
26-
| (x: BugExp4Point2D.ColumnType[T1])(y: T2)(using x$3: Numeric[T1], x$4: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
27-
| [T1, T2](x: T1)(y: T2)(using x$3: Numeric[T1], x$4: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
29+
| (x: BugExp4Point2D.ColumnType[T1])
30+
| (y: T2)(implicit evidence$9: Numeric[T1], evidence$10: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
31+
| [T1, T2](x: T1)(y: T2)(implicit evidence$3: Numeric[T1], evidence$4: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2]
2832
| both match arguments ((x : BugExp4Point2D.IntT.type))
2933
-- [E008] Not Found Error: tests/neg/i10901.scala:62:16 ----------------------------------------------------------------
3034
62 | val y = "abc".foo // error

tests/neg/i10901.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,27 @@ object BugExp4Point2D {
99
object dsl {
1010

1111

12-
extension [T1, T2](x: T1)
12+
extension [T1:Numeric, T2:Numeric](x: T1)
1313

1414
// N - N
1515
@targetName("point2DConstant")
16-
def º(y: T2)(using Numeric[T1], Numeric[T2]): Point2D[T1,T2] = ???
16+
def º(y: T2): Point2D[T1,T2] = ???
1717

1818

1919
// N - C
2020
@targetName("point2DConstantData")
21-
def º(y: ColumnType[T2])(using Numeric[T1], Numeric[T2]): Point2D[T1,T2] = ???
21+
def º(y: ColumnType[T2]): Point2D[T1,T2] = ???
2222

2323

2424

25-
extension [T1, T2](x: ColumnType[T1])
25+
extension [T1:Numeric, T2:Numeric](x: ColumnType[T1])
2626
// C - C
2727
@targetName("point2DData")
28-
def º(y: ColumnType[T2])(using Numeric[T1], Numeric[T2]): Point2D[T1,T2] = ???
28+
def º(y: ColumnType[T2]): Point2D[T1,T2] = ???
2929

3030
// C - N
3131
@targetName("point2DDataConstant")
32-
def º(y: T2)(using Numeric[T1], Numeric[T2]): Point2D[T1,T2] = ???
32+
def º(y: T2): Point2D[T1,T2] = ???
3333

3434

3535
}

tests/neg/missing-implicit1.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
-- Error: tests/neg/missing-implicit1.scala:23:42 ----------------------------------------------------------------------
2020
23 | List(1, 2, 3).traverse(x => Option(x)) // error
2121
| ^
22-
|no implicit argument of type testObjectInstance.Zip[Option] was found for parameter x$3 of method traverse in trait Traverse
22+
|no implicit argument of type testObjectInstance.Zip[Option] was found for an implicit parameter of method traverse in trait Traverse
2323
|
2424
|The following import might fix the problem:
2525
|

tests/neg/missing-implicit1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object testObjectInstance:
22
trait Zip[F[_]]
33
trait Traverse[F[_]] {
4-
extension [A, B, G[_]](fa: F[A]) def traverse(f: A => G[B])(using Zip[G]): G[F[B]]
4+
extension [A, B, G[_] : Zip](fa: F[A]) def traverse(f: A => G[B]): G[F[B]]
55
}
66

77
object instances {

tests/neg/missing-implicit4.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
-- Error: tests/neg/missing-implicit4.scala:20:42 ----------------------------------------------------------------------
2020
20 | List(1, 2, 3).traverse(x => Option(x)) // error
2121
| ^
22-
| no implicit argument of type Zip[Option] was found for parameter x$3 of method traverse in trait Traverse
22+
|no implicit argument of type Zip[Option] was found for an implicit parameter of method traverse in trait Traverse
2323
|
24-
| The following import might fix the problem:
24+
|The following import might fix the problem:
2525
|
26-
| import instances.zipOption
26+
| import instances.zipOption
2727
|

tests/neg/missing-implicit4.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
def testLocalInstance =
22
trait Zip[F[_]]
33
trait Traverse[F[_]] {
4-
extension [A, B, G[_]](fa: F[A]) def traverse(f: A => G[B])(using Zip[G]): G[F[B]]
4+
extension [A, B, G[_] : Zip](fa: F[A]) def traverse(f: A => G[B]): G[F[B]]
55
}
66

77
object instances {

tests/pos/i11358.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ object Test:
99
def test7 = +++(IArray(1, 2))[Int](IArray(2, 3))
1010
def test8 = +++(IArray(1, 2))[Int](List(2, 3))
1111

12-
extension [A](arr: IArray[A])
13-
def +++[B >: A](suffix: IArray[B])(using reflect.ClassTag[A], reflect.ClassTag[B]): IArray[B] = ???
14-
def +++[B >: A](suffix: IterableOnce[B])(using reflect.ClassTag[A], reflect.ClassTag[B]): IArray[B] = ???
12+
extension [A: reflect.ClassTag](arr: IArray[A])
13+
def +++[B >: A: reflect.ClassTag](suffix: IArray[B]): IArray[B] = ???
14+
def +++[B >: A: reflect.ClassTag](suffix: IterableOnce[B]): IArray[B] = ???

tests/pos/i11583.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
extension (s: String)
2+
def :*:[T <: Tuple](that: T) : String *: T = ???

tests/pos/i11586.scala

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)