diff --git a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala index 0fc7e5639c..512643e3c5 100644 --- a/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala +++ b/compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala @@ -525,8 +525,22 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent { } else { // Sort them so that, e.g., isInstanceOf[String] // comes before isInstanceOf[Object] - val sortedAltsByTypeTest = topoSortDistinctsBy( - altsByTypeTest)(_._1)(RTTypeTest.Ordering) + val sortedAltsByTypeTest = topoSortDistinctsWith(altsByTypeTest) { (lhs, rhs) => + (lhs._1, rhs._1) match { + // NoTypeTest is always last + case (_, NoTypeTest) => true + case (NoTypeTest, _) => false + + case (PrimitiveTypeTest(_, rank1), PrimitiveTypeTest(_, rank2)) => + rank1 <= rank2 + + case (InstanceOfTypeTest(t1), InstanceOfTypeTest(t2)) => + t1 <:< t2 + + case (_: PrimitiveTypeTest, _: InstanceOfTypeTest) => true + case (_: InstanceOfTypeTest, _: PrimitiveTypeTest) => false + } + } val defaultCase = genThrowTypeError() @@ -946,47 +960,16 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent { private case object NoTypeTest extends RTTypeTest - private object RTTypeTest { - implicit object Ordering extends PartialOrdering[RTTypeTest] { - override def tryCompare(lhs: RTTypeTest, rhs: RTTypeTest): Option[Int] = { - if (lteq(lhs, rhs)) if (lteq(rhs, lhs)) Some(0) else Some(-1) - else if (lteq(rhs, lhs)) Some(1) else None - } - - override def lteq(lhs: RTTypeTest, rhs: RTTypeTest): Boolean = { - (lhs, rhs) match { - // NoTypeTest is always last - case (_, NoTypeTest) => true - case (NoTypeTest, _) => false - - case (PrimitiveTypeTest(_, rank1), PrimitiveTypeTest(_, rank2)) => - rank1 <= rank2 - - case (InstanceOfTypeTest(t1), InstanceOfTypeTest(t2)) => - t1 <:< t2 - - case (_: PrimitiveTypeTest, _: InstanceOfTypeTest) => true - case (_: InstanceOfTypeTest, _: PrimitiveTypeTest) => false - } - } - - override def equiv(lhs: RTTypeTest, rhs: RTTypeTest): Boolean = { - lhs == rhs - } - } - } - // Very simple O(n²) topological sort for elements assumed to be distinct - private def topoSortDistinctsBy[A <: AnyRef, B](coll: List[A])(f: A => B)( - implicit ord: PartialOrdering[B]): List[A] = { - + private def topoSortDistinctsWith[A <: AnyRef](coll: List[A])( + lteq: (A, A) => Boolean): List[A] = { @scala.annotation.tailrec def loop(coll: List[A], acc: List[A]): List[A] = { if (coll.isEmpty) acc else if (coll.tail.isEmpty) coll.head :: acc else { val (lhs, rhs) = coll.span(x => !coll.forall( - y => (x eq y) || !ord.lteq(f(x), f(y)))) + y => (x eq y) || !lteq(x, y))) assert(!rhs.isEmpty, s"cycle while ordering $coll") loop(lhs ::: rhs.tail, rhs.head :: acc) }