diff options
-rw-r--r-- | src/compiler/scala/reflect/macros/runtime/Typers.scala | 29 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/ToolBoxFactory.scala | 29 | ||||
-rw-r--r-- | test/files/neg/t7166.check | 4 | ||||
-rw-r--r-- | test/files/neg/t7166/Impls_Macros_1.scala | 26 | ||||
-rw-r--r-- | test/files/neg/t7166/Test_2.scala | 3 |
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 |