summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Macros.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-10-02 17:21:27 +0200
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-11-12 18:40:01 -0800
commita2b523a39b4e56eb9ab5d9a5639f5b59d425e354 (patch)
tree8d91dd18059b1166d9e7d3ee6a1ab22166d0ae7b /src/compiler/scala/tools/nsc/typechecker/Macros.scala
parentce37ae45e22463a3f1a2d659d6699f2977b26c6b (diff)
downloadscala-a2b523a39b4e56eb9ab5d9a5639f5b59d425e354.tar.gz
scala-a2b523a39b4e56eb9ab5d9a5639f5b59d425e354.tar.bz2
scala-a2b523a39b4e56eb9ab5d9a5639f5b59d425e354.zip
blackbox restriction #1: can't refine the official return type
When an application of a blackbox macro expands into a tree `x`, the expansion is wrapped into a type ascription `(x: T)`, where `T` is the declared return type of the blackbox macro with type arguments and path dependencies applied in consistency with the particular macro application being expanded. This invalidates blackbox macros as an implementation vehicle of type providers.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Macros.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index f1b9bd4833..57358f72f5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -604,21 +604,27 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
*/
def macroExpandApply(typer: Typer, expandee: Tree, mode: Mode, pt: Type): Tree = {
object expander extends TermMacroExpander(APPLY_ROLE, typer, expandee, mode, pt) {
- override def onSuccess(expanded: Tree) = {
+ override def onSuccess(expanded0: Tree) = {
+ def approximate(tp: Type) = {
+ // approximation is necessary for whitebox macros to guide type inference
+ // read more in the comments for onDelayed below
+ if (isBlackbox(expandee)) tp
+ else {
+ val undetparams = tp collect { case tp if tp.typeSymbol.isTypeParameter => tp.typeSymbol }
+ deriveTypeWithWildcards(undetparams)(tp)
+ }
+ }
+ val macroPt = approximate(if (isNullaryInvocation(expandee)) expandee.tpe.finalResultType else expandee.tpe)
+ val expanded = if (isBlackbox(expandee)) atPos(enclosingMacroPosition.focus)(Typed(expanded0, TypeTree(macroPt))) else expanded0
+
// prematurely annotate the tree with a macro expansion attachment
// so that adapt called indirectly by typer.typed knows that it needs to apply the existential fixup
linkExpandeeAndExpanded(expandee, expanded)
- // approximation is necessary for whitebox macros to guide type inference
- // read more in the comments for onDelayed below
- def approximate(tp: Type) = {
- val undetparams = tp collect { case tp if tp.typeSymbol.isTypeParameter => tp.typeSymbol }
- deriveTypeWithWildcards(undetparams)(tp)
- }
- val macroPtApprox = approximate(if (isNullaryInvocation(expandee)) expandee.tpe.finalResultType else expandee.tpe)
+
// `macroExpandApply` is called from `adapt`, where implicit conversions are disabled
// therefore we need to re-enable the conversions back temporarily
- if (macroDebugVerbose) println(s"typecheck #1 (against macroPtApprox = $macroPtApprox): $expanded")
- val expanded1 = typer.context.withImplicitsEnabled(typer.typed(expanded, mode, macroPtApprox))
+ if (macroDebugVerbose) println(s"typecheck #1 (against macroPt = $macroPt): $expanded")
+ val expanded1 = typer.context.withImplicitsEnabled(typer.typed(expanded, mode, macroPt))
if (expanded1.isErrorTyped) {
if (macroDebugVerbose) println(s"typecheck #1 has failed: ${typer.context.reportBuffer.errors}")
expanded1