New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
compile error "diverging implicit expansion for type scala.math.Ordering ..." #8541
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8541?orig=1 |
@retronym said:
|
@retronym said (edited on Apr 27, 2014 8:33:47 AM UTC): Here's a aimilar example, teased apart from the standard library:
object Test2 {
import Test._, Implicits1._, Implicits2._
abstract class TimeStamp(val toLong: Long) extends Ordered[TimeStamp]
implicitly[Ordering[TimeStamp]]
implicitly[Ordering[(Int,TimeStamp)]]
}
object Test {
class Ordering[T]
abstract class Ordered[T] extends java.lang.Comparable[T]
trait Low {
implicit def ordered[A <% java.lang.Comparable[A]]: Ordering[A] = ???
implicit def comparatorToOrdering[A](implicit cmp: java.util.Comparator[A]): Ordering[A] = ???
}
object Implicits1 extends Low {
implicit def OrderingInt: Ordering[Int] = ???
implicit def OrderingTuple2[A: Ordering, B: Ordering]: Ordering[(A, B)] = ???
}
object Implicits2 {
implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = ???
}
} The troublesome implicit is: implicit def ordered[A <% java.lang.Comparable[A]]: Ordering[A] = ??? This should have instead been declared as: implicit def ordered[A <: java.lang.Comparable[A]]: Ordering[A] = ??? But it is pretty hard to fix this sort of design error with our backwards compat. constraints. My example above actually works again in 2.11.0, after a last minute tweak we made to divergence checking to try to make it more lenient and more compatible with 2.11.0. But your example is not rescued. I haven't dug in to the exact reason for that. My recommendation to work around this issue is to explicitly publish an object Test2 {
class TimeStamp(val toLong: Long) extends AnyVal
object TimeStamp {
implicit def TimeStampOrdering: Ordering[TimeStamp] = Ordering.by(_.toLong)
}
// while looking irrelevant, these two code lines are needed to reproduce the bug
case class L(time: TimeStamp)
List.empty[L].sortBy(_.time)
// this line triggers compiler error "diverging implicit expansion for type scala.math.Ordering[(Int, Test2.TimeStamp)] starting with method $conforms in object Predef"
List.empty[(Int,TimeStamp)].sorted
} |
Denis Petrov (denis) said: What is weird is the error appears in so simple code, without any esoteric features of scala, in the code that any beginner could write. |
@adriaanm said: |
James Koch (james.koch) said: I hit this in a more complex file, with about ten calls to methods like these, and worked around it by adding |
I also hit this bug in a different setting: import org.apache.spark.rdd.RDD
class Bar(v: Int) extends Ordered[Bar] {
def compare(that: Bar): Int = ???
}
object App {
def main(args: Array[String]): Unit = {
val dataSet: RDD[Baz] = ???
// This works - Case 1
val pairs = RDD.rddToPairRDDFunctions(dataSet)
pairs.reduceByKey(merge _)
// This does not work!! - Case 2
RDD.rddToPairRDDFunctions(dataSet).reduceByKey(merge _)
// This does not work!! - Case 3
dataSet.reduceByKey(merge _)
}
type Baz = ((Bar, Option[Bar]), Int)
def merge(b1: Int, b2: Int): Int = ???
} The first two cases should be identical, not sure why Scala fails to accept the second. I can make the compiler happy if I provide an implicit ordering instance for Bar. The above code works fine with 2.10 but doesn't with 2.11 |
This performance optimization leads to compilation order dependent variations in whether an implicit search will diverge or will find a successful result. Let's try turning off this sorting and measuring the impact on compilation speed. Refererences: scala/bug#10222, scala/bug#8541, scala/bug#10080
Maybe one more reproducer of the problem using scala 2.12.3: Welcome to Scala 2.12.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144).
Type in expressions for evaluation. Or try :help.
scala> :paste
// Entering paste mode (ctrl-D to finish)
import java.time.OffsetDateTime
import scala.concurrent.duration.FiniteDuration
implicitly[Ordering[OffsetDateTime]]
implicitly[Ordering[FiniteDuration]]
// Exiting paste mode, now interpreting.
<console>:17: error: diverging implicit expansion for type Ordering[scala.concurrent.duration.FiniteDuration]
starting with method $conforms in object Predef
implicitly[Ordering[FiniteDuration]]
^ To my surprise if I rearrange the scala> :paste
// Entering paste mode (ctrl-D to finish)
import java.time.OffsetDateTime
import scala.concurrent.duration.FiniteDuration
implicitly[Ordering[FiniteDuration]]
implicitly[Ordering[OffsetDateTime]]
// Exiting paste mode, now interpreting.
import java.time.OffsetDateTime
import scala.concurrent.duration.FiniteDuration
res0: Ordering[java.time.OffsetDateTime] = scala.math.LowPriorityOrderingImplicits$$anon$6@60c73e58 |
This performance optimization leads to compilation order dependent variations in whether an implicit search will diverge or will find a successful result. Let's try turning off this sorting and measuring the impact on compilation speed. Refererences: scala/bug#10222, scala/bug#8541, scala/bug#10080
This performance optimization leads to compilation order dependent variations in whether an implicit search will diverge or will find a successful result. Let's try turning off this sorting and measuring the impact on compilation speed. Refererences: scala/bug#10222, scala/bug#8541, scala/bug#10080
The text was updated successfully, but these errors were encountered: