Skip to content

Commit eb1f5f3

Browse files
committed
Drop generation of Eq instances for enums
Treat Eq like any other derivable typeclass. This caused a bit of changes in fuzzing tests.
1 parent bfcb4c6 commit eb1f5f3

File tree

9 files changed

+17
-57
lines changed

9 files changed

+17
-57
lines changed

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

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -538,45 +538,6 @@ object desugar {
538538
if (isEnum)
539539
parents1 = parents1 :+ ref(defn.EnumType)
540540

541-
// The Eq instance for an Enum class. For an enum class
542-
//
543-
// enum class C[T1, ..., Tn]
544-
//
545-
// we generate:
546-
//
547-
// implicit def eqInstance[T1$1, ..., Tn$1, T1$2, ..., Tn$2](implicit
548-
// ev1: Eq[T1$1, T1$2], ..., evn: Eq[Tn$1, Tn$2]])
549-
// : Eq[C[T1$, ..., Tn$1], C[T1$2, ..., Tn$2]] = Eq
550-
//
551-
// Higher-kinded type arguments `Ti` are omitted as evidence parameters.
552-
//
553-
// FIXME: This is too simplistic. Instead of just generating evidence arguments
554-
// for every first-kinded type parameter, we should look instead at the
555-
// actual types occurring in cases and derive parameters from these. E.g. in
556-
//
557-
// enum HK[F[_]] {
558-
// case C1(x: F[Int]) extends HK[F[Int]]
559-
// case C2(y: F[String]) extends HL[F[Int]]
560-
//
561-
// we would need evidence parameters for `F[Int]` and `F[String]`
562-
// We should generate Eq instances with the techniques
563-
// of typeclass derivation once that is available.
564-
def eqInstance = {
565-
val leftParams = constrTparams.map(derivedTypeParam(_, "$1"))
566-
val rightParams = constrTparams.map(derivedTypeParam(_, "$2"))
567-
val subInstances =
568-
for ((param1, param2) <- leftParams `zip` rightParams if !isHK(param1))
569-
yield appliedRef(ref(defn.EqType), List(param1, param2), widenHK = true)
570-
DefDef(
571-
name = nme.eqInstance,
572-
tparams = leftParams ++ rightParams,
573-
vparamss = if (subInstances.isEmpty) Nil else List(makeImplicitParameters(subInstances)),
574-
tpt = appliedTypeTree(ref(defn.EqType),
575-
appliedRef(classTycon, leftParams) :: appliedRef(classTycon, rightParams) :: Nil),
576-
rhs = ref(defn.EqModule.termRef)).withFlags(Synthetic | Implicit)
577-
}
578-
def eqInstances = if (isEnum) eqInstance :: Nil else Nil
579-
580541
// derived type classes of non-module classes go to their companions
581542
val (clsDerived, companionDerived) =
582543
if (mods.is(Module)) (impl.derived, Nil) else (Nil, impl.derived)
@@ -595,7 +556,7 @@ object desugar {
595556
mdefs
596557
}
597558

598-
val companionMembers = defaultGetters ::: eqInstances ::: enumCases
559+
val companionMembers = defaultGetters ::: enumCases
599560

600561
// The companion object definitions, if a companion is needed, Nil otherwise.
601562
// companion definitions include:
@@ -645,7 +606,7 @@ object desugar {
645606
}
646607
companionDefs(companionParent, applyMeths ::: unapplyMeth :: companionMembers)
647608
}
648-
else if (companionMembers.nonEmpty || companionDerived.nonEmpty)
609+
else if (companionMembers.nonEmpty || companionDerived.nonEmpty || isEnum)
649610
companionDefs(anyRef, companionMembers)
650611
else if (isValueClass) {
651612
impl.constr.vparamss match {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,7 @@ class Namer { typer: Typer =>
10291029

10301030
if (impl.derived.nonEmpty) {
10311031
val (derivingClass, derivePos) = original.removeAttachment(desugar.DerivingCompanion) match {
1032-
case Some(pos) => (cls.companionClass.asClass, pos)
1032+
case Some(pos) => (cls.companionClass.orElse(cls).asClass, pos)
10331033
case None => (cls, impl.sourcePos.startPos)
10341034
}
10351035
val deriver = new Deriver(derivingClass, derivePos)(localCtx)

tests/neg/derive-eq.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ case class Triple[S, T, U] derives Eq
1313

1414

1515
object Test extends App {
16-
Test1
1716
implicitly[Eq[Lst[Lst[One]], Lst[Lst[Two]]]]
1817
implicitly[Eq[Triple[One, One, One],
1918
Triple[Two, Two, Two]]]

tests/neg/enums.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ enum E4 {
2424
case class C4() extends E4 // error: cannot extend enum
2525
case object O4 extends E4 // error: cannot extend enum
2626

27-
enum Option[+T] {
27+
enum Option[+T] derives Eq {
2828
case Some(x: T)
2929
case None
3030
}

tests/neg/i3976.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
object Test {
2-
enum Hoge[F[_]] {
2+
enum Hoge[F[_]] derives Eq {
33
case A extends Hoge[List]
44
case B extends Hoge[[X] => String]
55
}
@@ -18,7 +18,7 @@ object Test {
1818
}
1919

2020
object Test2 {
21-
enum Hoge[F[G[_]]] {
21+
enum Hoge[F[G[_]]] derives Eq {
2222
case A extends Hoge[[F[_]] => F[Int]]
2323
case B extends Hoge[[F[_]] => F[String]]
2424
}
@@ -37,7 +37,7 @@ object Test2 {
3737
}
3838

3939
object Test3 {
40-
enum Hoge[F[G[_]]] {
40+
enum Hoge[F[G[_]]] derives Eq {
4141
case A extends Hoge[[X] => List] // error: wrong kind
4242
case B extends Hoge[[X] => [Y] => String] // error: wrong kind
4343
}

tests/neg/i4470a.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object RepeatedEnum {
22

3-
enum Maybe { // error // error
4-
case Foo
3+
enum Maybe { // error
4+
case Foo // error
55
}
66

77
enum Maybe { // error

tests/neg/i4470b.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
object RepeatedExtendEnum {
22

3-
enum Maybe[T] { // error // error
3+
enum Maybe[T] derives Eq { // error // error
44
case Foo extends Maybe[Int]
55
}
66

7-
enum Maybe[T] { // error
7+
enum Maybe[T] derives Eq { // error
88
case Foo extends Maybe[Int]
99
}
1010
}

tests/neg/i4470c.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object DuplicatedEnum {
2-
enum Maybe[+T] { // error // error
3-
case Some(x: T)
2+
enum Maybe[+T] { // error
3+
case Some(x: T) // error
44
}
55

66
enum Maybe[+T] { // error

tests/run/derive-eq.scala renamed to tests/pos/derive-eq.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ enum Lst[T] derives Eq {
1212
class Triple[S, T, U] derives Eq
1313

1414

15-
object Test extends App {
15+
object Test {
1616
implicitly[Eq[Lst[Lst[One]], Lst[Lst[Two]]]]
1717
implicitly[Eq[Triple[One, One, One],
1818
Triple[Two, Two, Two]]]
1919

20-
val x: Triple[List[One], One, Two] = ???
21-
val y: Triple[List[Two], One, Two] = ???
22-
assert(x == y)
20+
val x: Triple[Lst[One], One, Two] = ???
21+
val y: Triple[Lst[Two], One, Two] = ???
22+
x == y
2323
}

0 commit comments

Comments
 (0)