From 4e64a2731d6e4c27e2fd4c75559e118708e79ad5 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 4 May 2013 16:18:23 +0200 Subject: [nomaster] removes duplication in inferImplicitValue Shame-driven development at its best. --- .../scala/reflect/macros/runtime/Typers.scala | 31 ++-------------------- .../scala/tools/nsc/typechecker/Implicits.scala | 25 +++++++++++++++++ .../scala/tools/reflect/ToolBoxFactory.scala | 22 +-------------- 3 files changed, 28 insertions(+), 50 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 2823a8300d..4d333f180b 100644 --- a/src/compiler/scala/reflect/macros/runtime/Typers.scala +++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala @@ -35,40 +35,13 @@ trait Typers { def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) - inferImplicit(universe.EmptyTree, pt, isView = false, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) + universe.analyzer.inferImplicit(universe.EmptyTree, pt, false, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg)) } def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s".format(from, to, tree, !withMacrosDisabled)) val viewTpe = universe.appliedType(universe.definitions.FunctionClass(1).toTypeConstructor, List(from, to)) - inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) - } - - 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) - 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")) - } + universe.analyzer.inferImplicit(tree, viewTpe, true, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg)) } def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(tree) diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index a8de11911c..193e589470 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -96,6 +96,31 @@ trait Implicits { result } + /** A friendly wrapper over inferImplicit to be used in macro contexts and toolboxes. + */ + def inferImplicit(tree: Tree, pt: Type, isView: Boolean, context: Context, silent: Boolean, withMacrosDisabled: Boolean, pos: Position, onError: (Position, String) => Unit): Tree = { + val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) + def wrapper(inference: => SearchResult) = wrapper1(inference) + def fail(reason: Option[String]) = { + if (!silent) { + if (context.hasErrors) onError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) + else onError(pos, reason getOrElse "implicit search has failed. to find out the reason, turn on -Xlog-implicits") + } + EmptyTree + } + try { + wrapper(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) + debugwarn("this shouldn't happen. DivergentImplicit exception has been thrown with -Xdivergence211 turned on: "+ex) + fail(Some("divergent implicit expansion")) + } + } + /** Find all views from type `tp` (in which `tpars` are free) * * Note that the trees in the search results in the returned list share the same type variables. diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index b9968eedef..4b5dcadfa2 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -180,28 +180,8 @@ 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 - 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")) - } + analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw ToolBoxError(msg)) }) def compile(expr0: Tree): () => Any = { -- cgit v1.2.3