Skip to content

Commit a28a078

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 c64ee4b commit a28a078

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
@@ -537,45 +537,6 @@ object desugar {
537537
if (isEnum)
538538
parents1 = parents1 :+ ref(defn.EnumType)
539539

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

597-
val companionMembers = defaultGetters ::: eqInstances ::: enumCases
558+
val companionMembers = defaultGetters ::: enumCases
598559

599560
// The companion object definitions, if a companion is needed, Nil otherwise.
600561
// companion definitions include:
@@ -644,7 +605,7 @@ object desugar {
644605
}
645606
companionDefs(companionParent, applyMeths ::: unapplyMeth :: companionMembers)
646607
}
647-
else if (companionMembers.nonEmpty || companionDerived.nonEmpty)
608+
else if (companionMembers.nonEmpty || companionDerived.nonEmpty || isEnum)
648609
companionDefs(anyRef, companionMembers)
649610
else if (isValueClass) {
650611
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)