-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
infinite loop when evaluating a recursive given definition #10947
Comments
|
Seems like the issue occurs on Scastie but not locally (works for me too) |
@som-snytt @griggt please remove the indentation on the import and mainz block, i.e It appears it should not be on the same block as where the opaque type is defined for the issue to occur. It should occur then. I'll update the example to use curlies for clarity.
|
EDIT: nvm, it hangs at runtime, not compile time |
What happens here is that you have a recursive given definition. What you need to do is to summon the It seems that the following works fine: object Prices {
opaque type Price = BigDecimal
private val orderingBigDecimal = summon[Ordering[BigDecimal]]
object Price{
given Ordering[Price] = orderingBigDecimal
}
}
extension[K,V] (m1: Map[K,V]) def computeDiff(m2: Map[K,V])(using Ordering[K])(using orderAsc: Boolean = true): Unit = println("Ok....")
import Prices._
@main def mainz =
println("begin")
val result = Map.empty[Price,Int].computeDiff(Map.empty[Price,Int])
println(s"end $result") |
I am not sure what we should do about this problem. I think the current behavior is expected. I don’t think we can reliably implement a detection mechanism for such loops at compilation time so I’m closing the issue. Feel free to re-open it if I miss something. |
It seems like an easy pitfall to fall into, but then again I am not sure how to best prevent these kind of issue myself. I wonder there is any chance to eagarly evaluate givens for opaque type at compile time? I don't know if thats possible. |
This is not specific to opaque types, the same issue can happen with regular type aliases, abstract type members, etc. It is easy to construct a recursive instance, but it is known to be a hard problem to detect such constructions at compile-time. Also, not all the recursive given definitions are wrong. Some of them are correct (this is how we define instances for recursive data types). |
😦 That is a bit worrying, hope we can think of something in the future. |
We could enhance the initialization check to check for possible non-termination of lazy fields. A related issue #9668. |
What's interesting about this one is that one common use case is derivation (a la Haskell's generalize newtype deriving). Would it be possible to hook something into the derivation mechanism? |
It is a lint in Scala 2 ➜ ~ scala -Xlint
Welcome to Scala 2.13.4 (OpenJDK 64-Bit Server VM, Java 15).
Type in expressions for evaluation. Or try :help.
scala> type Price = BigDecimal
type Price
scala> implicit val `order price`: Ordering[Price] = implicitly[Ordering[BigDecimal]]
^
warning: Implicit resolves to enclosing value order price
val order price: Ordering[Price] = null
scala> |
@tel I really wish this was possible. I don't see people switching from |
1. Also check apply methods of companions of implicit or given classes. Specifically apply methods of implicit Conversions. 2. Look inside Inlined nodes to detect loops. Fixes scala#15474 Fixes scala#10947
When running a program which consumes opaque types as follows, it appears to be stuck on an infinite loop. Not sure what is going on here.
Minimized code
Scastie link: https://scastie.scala-lang.org/ajEagvzvTbitmzbqFt0Oxw
Output
Expectation
Should successfully print the following:
This works if the
Price
was swapped withBigDecimal
in the lineThis is happening on 3.0.0-M3
The text was updated successfully, but these errors were encountered: