summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/macros/contexts/Typers.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-02-12 12:11:40 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-02-12 15:21:15 +0100
commit609047ba372ceaf06916d3361954bc949a6906ee (patch)
tree93eceb1b342ea114b4923ef258a9409a054197a9 /src/compiler/scala/reflect/macros/contexts/Typers.scala
parent98320a6d5947f26e7252b025cf56a0763b39cd07 (diff)
downloadscala-609047ba372ceaf06916d3361954bc949a6906ee.tar.gz
scala-609047ba372ceaf06916d3361954bc949a6906ee.tar.bz2
scala-609047ba372ceaf06916d3361954bc949a6906ee.zip
typecheck(q"class C") no longer crashes
MemberDefs alone can't be typechecked as is, because namer only names contents of PackageDefs, Templates and Blocks. And, if not named, a tree can't be typed. This commit solves this problem by wrapping typecheckees in a trivial block and then unwrapping the result when it returns back from the typechecker.
Diffstat (limited to 'src/compiler/scala/reflect/macros/contexts/Typers.scala')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Typers.scala16
1 files changed, 6 insertions, 10 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala
index c1ab17027f..f80b43b636 100644
--- a/src/compiler/scala/reflect/macros/contexts/Typers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala
@@ -16,15 +16,11 @@ trait Typers {
def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled))
val context = callsiteTyper.context
- val wrapper1 = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _)
- val wrapper2 = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _)
- def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
- // if you get a "silent mode is not available past typer" here
- // don't rush to change the typecheck not to use the silent method when the silent parameter is false
- // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time
- // I'd advise fixing the root cause: finding why the context is not set to report errors
- // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you)
- wrapper(callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), pt), reportAmbiguousErrors = false) match {
+ val withImplicitFlag = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _)
+ val withMacroFlag = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _)
+ def withContext(tree: => Tree) = withImplicitFlag(withMacroFlag(tree))
+ def typecheckInternal(tree: Tree) = callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), pt), reportAmbiguousErrors = false)
+ universe.wrappingIntoTerm(tree)(wrappedTree => withContext(typecheckInternal(wrappedTree) match {
case universe.analyzer.SilentResultValue(result) =>
macroLogVerbose(result)
result
@@ -32,7 +28,7 @@ trait Typers {
macroLogVerbose(error.err.errMsg)
if (!silent) throw new TypecheckException(error.err.errPos, error.err.errMsg)
universe.EmptyTree
- })
+ }))
}
def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = {