-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Labels
Description
Compiler version
3.6.3
Minimized code
import scala.compiletime.deferred
trait MyCodec[E]
object auto {
trait CompanionEssentials[E] {
given MyCodec[E] = deferred
}
}
import auto.CompanionEssentials
case class Person(name: String, age: Int)
object Person extends CompanionEssentials[Person]
// deferred given implemented as:
// override final lazy given val given_MyCodec_E: MyCodec[Person] =
// Person.given_MyCodec_EOutput
Due to module class Person being in the implicit scope of Person, the compiler resolves the deferred given to its unimplemented self resulting in infinite recursion. This happens regardless of presence of a valid given in scope or not.
Expectation
The compiler should detect the cycle and exclude Person.given_MyCodec_E as a viable candidate, and produce an error if the deferred given couldn't be synthesized from other candidates in scope.
Workaround
The infinite recursion problem can be avoided by explicitly importing the relevant givens (which is probably what you should be doing in the first place):
object auto {
trait CompanionEssentials[E] {
given MyCodec[E] = deferred
}
given [E] => MyCodec[E] = new MyCodec[E]{}
}
import auto.{CompanionEssentials, given}
case class Person(name: String, age: Int)
object Person extends CompanionEssentials[Person]
// deferred given implemented as:
// override final lazy given val given_MyCodec_E: MyCodec[Person] =
// auto.given_MyCodec_E[Person]