summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Typers.scala29
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala29
-rw-r--r--test/files/neg/t7166.check4
-rw-r--r--test/files/neg/t7166/Impls_Macros_1.scala26
-rw-r--r--test/files/neg/t7166/Test_2.scala3
5 files changed, 71 insertions, 20 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala
index 7cfee2041c..2823a8300d 100644
--- a/src/compiler/scala/reflect/macros/runtime/Typers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala
@@ -46,19 +46,28 @@ trait Typers {
private def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree = {
import universe.analyzer.SearchResult
+ import scala.tools.nsc.typechecker.DivergentImplicit
val context = callsiteTyper.context
val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
def wrapper (inference: => SearchResult) = wrapper1(inference)
- wrapper(universe.analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos)) match {
- case failure if failure.tree.isEmpty =>
- macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
- if (!silent) {
- if (context.hasErrors) throw new TypecheckException(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
- else throw new TypecheckException(pos, "implicit search has failed. to find out the reason, turn on -Xlog-implicits")
- }
- universe.EmptyTree
- case success =>
- success.tree
+ def fail(reason: Option[String]) = {
+ macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
+ if (!silent) {
+ if (context.hasErrors) throw new TypecheckException(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
+ else throw new TypecheckException(pos, reason getOrElse "implicit search has failed. to find out the reason, turn on -Xlog-implicits")
+ }
+ universe.EmptyTree
+ }
+ try {
+ wrapper(universe.analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos)) match {
+ case failure if failure.tree.isEmpty => fail(None)
+ case success => success.tree
+ }
+ } catch {
+ case ex: DivergentImplicit =>
+ if (universe.settings.Xdivergence211.value)
+ universe.debuglog("this shouldn't happen. DivergentImplicit exception has been thrown with -Xdivergence211 turned on: "+ex)
+ fail(Some("divergent implicit expansion"))
}
}
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index acfc86c1ac..b9968eedef 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -180,18 +180,27 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree =
transformDuringTyper(tree, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, tree) => {
+ import scala.tools.nsc.typechecker.DivergentImplicit
trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, true, true, settings.Yshowsymkinds.value))
val context = currentTyper.context
- analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos) match {
- case failure if failure.tree.isEmpty =>
- trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits: ")(failure.tree)
- if (!silent) {
- if (context.hasErrors) throw ToolBoxError("reflective implicit search has failed: %s".format(context.errBuffer.head.errMsg))
- else throw new ToolBoxError("reflective implicit search has failed. to find out the reason, turn on -Xlog-implicits")
- }
- EmptyTree
- case success =>
- success.tree
+ def fail(reason: Option[String]) = {
+ debuglog("reflective implicit search has failed. to find out the reason, turn on -Xlog-implicits")
+ if (!silent) {
+ if (context.hasErrors) throw ToolBoxError("reflective implicit search has failed: %s".format(context.errBuffer.head.errMsg))
+ else throw ToolBoxError(reason getOrElse "reflective implicit search has failed. to find out the reason, turn on -Xlog-implicits")
+ }
+ EmptyTree
+ }
+ try {
+ analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos) match {
+ case failure if failure.tree.isEmpty => fail(None)
+ case success => success.tree
+ }
+ } catch {
+ case ex: DivergentImplicit =>
+ if (settings.Xdivergence211.value)
+ debuglog("this shouldn't happen. DivergentImplicit exception has been thrown with -Xdivergence211 turned on: "+ex)
+ fail(Some("divergent implicit expansion"))
}
})
diff --git a/test/files/neg/t7166.check b/test/files/neg/t7166.check
new file mode 100644
index 0000000000..c87198cb27
--- /dev/null
+++ b/test/files/neg/t7166.check
@@ -0,0 +1,4 @@
+Test_2.scala:2: error: silent = true does work!
+ println(implicitly[Complex[Foo]])
+ ^
+one error found
diff --git a/test/files/neg/t7166/Impls_Macros_1.scala b/test/files/neg/t7166/Impls_Macros_1.scala
new file mode 100644
index 0000000000..62a15657c3
--- /dev/null
+++ b/test/files/neg/t7166/Impls_Macros_1.scala
@@ -0,0 +1,26 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+trait Complex[T]
+
+class Foo
+
+object Complex {
+ def impl[T: c.WeakTypeTag](c: Context): c.Expr[Complex[T]] = {
+ import c.universe._
+ def shout(msg: String) = {
+ val cannotShutMeUp = c.asInstanceOf[scala.reflect.macros.runtime.Context].universe.currentRun.currentUnit.error _
+ cannotShutMeUp(c.enclosingPosition.asInstanceOf[scala.reflect.internal.util.Position], msg)
+ }
+ try {
+ val complexOfT = appliedType(typeOf[Complex[_]], List(weakTypeOf[T]))
+ val infiniteRecursion = c.inferImplicitValue(complexOfT, silent = true)
+ shout("silent = true does work!")
+ } catch {
+ case ex: Exception => shout(ex.toString)
+ }
+ c.literalNull
+ }
+
+ implicit def genComplex[T]: Complex[T] = macro impl[T]
+}
diff --git a/test/files/neg/t7166/Test_2.scala b/test/files/neg/t7166/Test_2.scala
new file mode 100644
index 0000000000..dcc4593335
--- /dev/null
+++ b/test/files/neg/t7166/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println(implicitly[Complex[Foo]])
+} \ No newline at end of file