From 9f17b7e0d6dcc8829f5a139b1c97a63add4cb628 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Sun, 24 Dec 2017 14:52:16 +0100 Subject: [PATCH] Fix Lazy for tagged types Fixes #584 --- core/src/main/scala/shapeless/lazy.scala | 2 +- .../scala/shapeless/labelledgeneric.scala | 27 ++++++++++--------- core/src/test/scala/shapeless/lazy.scala | 17 ++++++++++++ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/core/src/main/scala/shapeless/lazy.scala b/core/src/main/scala/shapeless/lazy.scala index 607e5e560..70b764d53 100644 --- a/core/src/main/scala/shapeless/lazy.scala +++ b/core/src/main/scala/shapeless/lazy.scala @@ -180,7 +180,7 @@ trait OpenImplicitMacros { def openImplicitTpeParam: Option[Type] = openImplicitTpe.map { case TypeRef(_, _, List(tpe)) => - tpe.map(_.dealias) + tpe.dealias case other => c.abort(c.enclosingPosition, s"Bad materialization: $other") } diff --git a/core/src/test/scala/shapeless/labelledgeneric.scala b/core/src/test/scala/shapeless/labelledgeneric.scala index 242a3be20..967d052c0 100644 --- a/core/src/test/scala/shapeless/labelledgeneric.scala +++ b/core/src/test/scala/shapeless/labelledgeneric.scala @@ -93,7 +93,7 @@ object ScalazTaggedAux { def apply(): String } - object TC { + object TC extends TCLowPriority { implicit val intTC: TC[Int] = new TC[Int] { def apply() = "Int" @@ -114,22 +114,13 @@ object ScalazTaggedAux { def apply() = "HNil" } - implicit def hconsTCTagged[K <: Symbol, H, HT, T <: HList](implicit - key: Witness.Aux[K], - headTC: Lazy[TC[H @@ HT]], - tailTC: Lazy[TC[T]] - ): TC[FieldType[K, H @@ HT] :: T] = - new TC[FieldType[K, H @@ HT] :: T] { - def apply() = s"${key.value.name}: ${headTC.value()} :: ${tailTC.value()}" - } - implicit def hconsTC[K <: Symbol, H, T <: HList](implicit key: Witness.Aux[K], headTC: Lazy[TC[H]], - tailTC: Lazy[TC[T]] + tailTC: TC[T] ): TC[FieldType[K, H] :: T] = new TC[FieldType[K, H] :: T] { - def apply() = s"${key.value.name}: ${headTC.value()} :: ${tailTC.value()}" + def apply() = s"${key.value.name}: ${headTC.value()} :: ${tailTC()}" } implicit def projectTC[F, G](implicit @@ -140,6 +131,18 @@ object ScalazTaggedAux { def apply() = s"Proj(${tc.value()})" } } + + abstract class TCLowPriority { + // FIXME: Workaround #309 + implicit def hconsTCTagged[K <: Symbol, H, HT, T <: HList](implicit + key: Witness.Aux[K], + headTC: Lazy[TC[H @@ HT]], + tailTC: TC[T] + ): TC[FieldType[K, H @@ HT] :: T] = + new TC[FieldType[K, H @@ HT] :: T] { + def apply() = s"${key.value.name}: ${headTC.value()} :: ${tailTC()}" + } + } } class LabelledGenericTests { diff --git a/core/src/test/scala/shapeless/lazy.scala b/core/src/test/scala/shapeless/lazy.scala index 529b47594..9d4ad9f47 100644 --- a/core/src/test/scala/shapeless/lazy.scala +++ b/core/src/test/scala/shapeless/lazy.scala @@ -315,4 +315,21 @@ class LazyStrictTests { "lazily[W[String, Int]]", "No W\\[String, Int]" ) } + + @Test + def testInteractionWithTaggedTypes { + import tag._ + + class Readable[A] + trait IdTag + type Id = String @@ IdTag + + implicit def taggedStringReadable[T, M[_, _]]( + implicit ev: String @@ T =:= M[String, T] + ): Readable[M[String, T]] = new Readable + + implicitly[Readable[Id]] + implicitly[Lazy[Readable[Id]]] + implicitly[Strict[Readable[Id]]] + } }