Generic in shapeless 2.3.5+ not working for classes with context bounds if some implicit value is present
lsrcz opened this issue · comments
Hi, I am using shapeless in my project and met some strange behavior. I am not sure if it is a bug.
The following code is a minimal example. It compiles with shapeless 2.3.5+ only if the instance is commented out. It works well with shapeless 2.3.3/2.3.4.
import shapeless._
trait ATypeClass[T]
case class AnUnrelatedCaseClass[T](v: T)
case class ACaseClassWithContextBound[T: ATypeClass]()
object Main extends App {
implicit def instance[T: ATypeClass]: ATypeClass[AnUnrelatedCaseClass[T]] = new ATypeClass[AnUnrelatedCaseClass[T]] {}
/*
* With shapeless 2.3.5+, the following function compiles only if instance is commented out
* With shapeless 2.3.3/2.3.4, the following function always compiles
*/
def compilesOnlyIfInstanceIsCommented[T: ATypeClass]
: Generic.Aux[ACaseClassWithContextBound[T], HNil] = Generic[ACaseClassWithContextBound[T]]
}
That sounds like a bug. But in general the interaction between shapeless and implicits might be confusing - because the implicit instance would be captured at Generic
definition time, not when it is used.
I read something about debugging implicits and hope that I can provide you more information.
I turned on -Xlog-implicits
, and the compiler reported that
instance is not a valid implicit value for ATypeClass[T] because:
hasMatchingSymbol reported error: diverging implicit expansion for type ATypeClass[T]
starting with value evidence$3
: Generic.Aux[ACaseClassWithContextBound[T], HNil] = Generic[ACaseClassWithContextBound[T]]
shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic[ACaseClassWithContextBound[T]] because:
hasMatchingSymbol reported error: ambiguous implicit values:
both method instance in object Main of type [T](implicit evidence$2: ATypeClass[T])ATypeClass[AnUnrelatedCaseClass[T]]
and value evidence$3 of type ATypeClass[T]
match expected type ATypeClass[T]
: Generic.Aux[ACaseClassWithContextBound[T], HNil] = Generic[ACaseClassWithContextBound[T]]
I am not so familiar with scala macros so I cannot fully understand the shapeless source. But if I understand it correctly, it failed to resolve the type class instance required by the constructor of ACaseClassWithContextBound
.