diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-11-14 12:17:07 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-11-14 12:17:07 +0100 |
commit | ee6fbae3d069d8fe55b7a20756c04abcc9119bba (patch) | |
tree | f99910e432b9d3d4ba2b426ac4343b4ba7f45873 | |
parent | 96df73d994097e3318d003ddef00194b711289a3 (diff) | |
download | scala-ee6fbae3d069d8fe55b7a20756c04abcc9119bba.tar.gz scala-ee6fbae3d069d8fe55b7a20756c04abcc9119bba.tar.bz2 scala-ee6fbae3d069d8fe55b7a20756c04abcc9119bba.zip |
correctly fails implicit search for invalid implicit macros
There was a rare corner case when implicit search wouldn’t discard
an invalid implicit macro (e.g. the one with mismatching macro impl or
the one with macro impl defined in the same compilation run) during
typechecking the corresponding candidate in typedImplicit1. This is now fixed.
3 files changed, 30 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 01acbb8cc2..d31a8e81d4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -664,6 +664,8 @@ trait Implicits { if (context.hasErrors) fail("hasMatchingSymbol reported error: " + context.firstError.get.errMsg) + else if (itree3.isErroneous) + fail("error typechecking implicit candidate") else if (isLocal && !hasMatchingSymbol(itree2)) fail("candidate implicit %s is shadowed by %s".format( info.sym.fullLocationString, itree2.symbol.fullLocationString)) diff --git a/test/files/pos/macro-implicit-invalidate-on-error.check b/test/files/pos/macro-implicit-invalidate-on-error.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/pos/macro-implicit-invalidate-on-error.check diff --git a/test/files/pos/macro-implicit-invalidate-on-error.scala b/test/files/pos/macro-implicit-invalidate-on-error.scala new file mode 100644 index 0000000000..22cd2d34b4 --- /dev/null +++ b/test/files/pos/macro-implicit-invalidate-on-error.scala @@ -0,0 +1,28 @@ +package scala.reflect +package api + +import scala.language.experimental.macros +import scala.reflect.macros.Context + +trait Liftable[T] { + def apply(universe: api.Universe, value: T): universe.Tree +} + +object Liftable { + implicit def liftCaseClass[T <: Product]: Liftable[T] = macro liftCaseClassImpl[T] + + def liftCaseClassImpl[T: c.WeakTypeTag](c: Context): c.Expr[Liftable[T]] = { + import c.universe._ + val tpe = weakTypeOf[T] + if (!tpe.typeSymbol.asClass.isCaseClass) c.abort(c.enclosingPosition, "denied") + val p = List(q"Literal(Constant(1))") + c.Expr[Liftable[T]] { q""" + new scala.reflect.api.Liftable[$tpe] { + def apply(universe: scala.reflect.api.Universe, value: $tpe): universe.Tree = { + import universe._ + Apply(Select(Ident(TermName("C")), TermName("apply")), List(..$p)) + } + } + """ } + } +} |