Given Loop Prevention
Implicit resolution now avoids generating recursive givens that can lead to an infinite loop at runtime. Here is an example:
object Prices {
opaque type Price = BigDecimal
object Price{
given Ordering[Price] = summon[Ordering[BigDecimal]] // was error, now avoided
}
}
Previously, implicit resolution would resolve the summon
to the given in Price
, leading to an infinite loop (a warning was issued in that case). We now use the underlying given in BigDecimal
instead. We achieve that by adding the following rule for implicit search:
- When doing an implicit search while checking the implementation of a
given
definitionG
of the formgiven ... = ....
discard all search results that lead back to
G
or to a given with the same owner asG
that comes later in the source thanG
.
The new behavior is enabled with the experimental.givenLoopPrevention
language import. If no such import or setting is given, a warning is issued where the behavior would change under that import (for source version 3.4 and later).
Old-style implicit definitions are unaffected by this change.