Created
December 12, 2015 13:36
-
-
Save xeno-by/90daa4b8227034acce36 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.language.experimental.macros | |
trait Foo[T] | |
object Foo { | |
implicit def materialize[T]: Foo[T] = macro Macros.impl[T] | |
} | |
@scala.annotation.implicitNotFound("boom") | |
trait Typeclass[T] | |
object Main extends App { | |
def foo[T: Foo](x: T) = ??? | |
foo(42) | |
} | |
// We'd like to have Macros.impl look up an implicit instance of Typeclass | |
// And then propagate the implicitNotFound error message if that instance is not found | |
// c.abort only works if your macro is blackbox | |
// If you're whitebox, read on | |
import scala.reflect.macros.whitebox._ // if this was blackbox, everything would've worked without any hacks | |
import scala.language.experimental.macros | |
object Macros { | |
def impl[T: c.WeakTypeTag](c: Context): c.Tree = { | |
import c.universe._ | |
import c.internal._ | |
import decorators._ | |
val Foo = c.mirror.staticClass("Foo") | |
val Typeclass = c.mirror.staticClass("Typeclass") | |
Typeclass.initialize // necessary to get @implicitNotFound loaded | |
val TypeclassOfT = appliedType(Typeclass.toType, c.weakTypeOf[T]) | |
val result = c.inferImplicitValue(TypeclassOfT, silent = true) | |
if (result.isEmpty) { | |
val infAnn = TypeclassOfT.typeSymbol.annotations.find(_.tpe =:= typeOf[_root_.scala.annotation.implicitNotFound]).get | |
Foo.setAnnotations(infAnn) // propagate the @implicitNotFound message | |
c.abort(c.enclosingPosition, "") // the "" can be anything - it doesn't matter to the compiler anyway | |
} else { | |
q"null" | |
} | |
} | |
} | |
13:32 ~/Projects/BetterErrors/sandbox (topic/better)$ ks | |
Test.scala:13: error: boom | |
foo(42) | |
^ | |
one error found |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment