From 3edde2727bad9b00cbaf5475f5bf234f08c26cbd Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 23 Feb 2013 14:34:29 +0100 Subject: [nomaster] SI-7166 catches DivergentImplicit in c.inferImplicitXXX Despite inferImplicit usually being nice and buffering errors, apparently it can also throw DivergentImplicit exception. This patch catches it and only reports it if silent is set to false. NOTE: we no longer have the DivergentImplicit exception in master, so this commit only makes sense in 2.10.x. --- .../scala/reflect/macros/runtime/Typers.scala | 29 ++++++++++++++-------- .../scala/tools/reflect/ToolBoxFactory.scala | 29 ++++++++++++++-------- 2 files changed, 38 insertions(+), 20 deletions(-) (limited to 'src') 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")) } }) -- cgit v1.2.3