From eaf30742cb945596fa57e30e8bc3578d7db7c054 Mon Sep 17 00:00:00 2001 From: Mike Curry Date: Sun, 20 Dec 2015 23:22:10 +0000 Subject: [PATCH 1/2] Use imp summon macro to summon type class instance for apply --- build.sbt | 4 ++-- core/src/main/scala/simulacrum/typeclass.scala | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index ece984e..4a69483 100644 --- a/build.sbt +++ b/build.sbt @@ -34,7 +34,8 @@ lazy val commonSettings = Seq( Resolver.sonatypeRepo("snapshots") ), libraryDependencies ++= Seq( - "org.scalatest" %%% "scalatest" % "3.0.0-M7" % "test" + "org.scalatest" %%% "scalatest" % "3.0.0-M7" % "test", + "org.spire-math" %% "imp" % "0.2.0" % "provided" ), addCompilerPlugin("org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full), licenses += ("Three-clause BSD-style", url("https://github.com/mpilquist/simulacrum/blob/master/LICENSE")), @@ -144,4 +145,3 @@ lazy val noPublishSettings = Seq( publishLocal := (), publishArtifact := false ) - diff --git a/core/src/main/scala/simulacrum/typeclass.scala b/core/src/main/scala/simulacrum/typeclass.scala index 40cecfa..fcd68bb 100644 --- a/core/src/main/scala/simulacrum/typeclass.scala +++ b/core/src/main/scala/simulacrum/typeclass.scala @@ -6,6 +6,7 @@ import scala.reflect.macros.whitebox.Context import macrocompat._ + /** * Annotation that may be applied to methods on a type that is annotated with `@typeclass`. * @@ -298,7 +299,17 @@ class TypeClassMacros(val c: Context) { def generateCompanion(typeClass: ClassDef, tparam0: TypeDef, proper: Boolean, comp: Tree) = { val tparam = eliminateVariance(tparam0) - val summoner = q"def apply[$tparam](implicit instance: ${typeClass.name}[${tparam.name}]): ${typeClass.name}[${tparam.name}] = instance" + + // The apply method uses the imp macro to summon the appropriate instance, but as imp is a + // macro itself, an import is required in the generated tree to allow the macro to be called + // in the generated tree. + val summonerImports = q""" + import scala.language.experimental.macros + """ + + val summoner = q""" + def apply[$tparam](implicit ev: ${typeClass.name}[${tparam.name}]): ${typeClass.name}[${tparam.name}] = + macro imp.summon[${typeClass.name}[${tparam.name}]]""" val liftedTypeArg = if (proper) None else Some { // We have a TypeClass[F[_ >: L <: U]], so let's create a F[X >: L <: U] for a fresh name X @@ -359,6 +370,7 @@ class TypeClassMacros(val c: Context) { val companion = q""" $mods object $name extends ..$bases { ..$body + $summonerImports $summoner ..$opsMembers } From 6e01351df517803e56c5a4316d343941d7b50c47 Mon Sep 17 00:00:00 2001 From: Mike Curry Date: Wed, 23 Dec 2015 12:12:02 +0000 Subject: [PATCH 2/2] Remove errant provided from dependency on imp --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4a69483..f51ca4f 100644 --- a/build.sbt +++ b/build.sbt @@ -35,7 +35,7 @@ lazy val commonSettings = Seq( ), libraryDependencies ++= Seq( "org.scalatest" %%% "scalatest" % "3.0.0-M7" % "test", - "org.spire-math" %% "imp" % "0.2.0" % "provided" + "org.spire-math" %% "imp" % "0.2.0" ), addCompilerPlugin("org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full), licenses += ("Three-clause BSD-style", url("https://github.com/mpilquist/simulacrum/blob/master/LICENSE")),