diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2014-02-12 12:11:40 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-02-12 15:21:15 +0100 |
commit | 609047ba372ceaf06916d3361954bc949a6906ee (patch) | |
tree | 93eceb1b342ea114b4923ef258a9409a054197a9 /src/compiler/scala/reflect/macros | |
parent | 98320a6d5947f26e7252b025cf56a0763b39cd07 (diff) | |
download | scala-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')
-rw-r--r-- | src/compiler/scala/reflect/macros/contexts/Typers.scala | 16 |
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 = { |