diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-03-30 10:41:04 +0700 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-05-11 18:37:10 +0200 |
commit | bb73b9669a96410bc9c513d061d090f5bd3c075e (patch) | |
tree | 23b5a3f29b04f52dd403e17d349694f18a09486b | |
parent | 90ac5c4e1350493f6f47c674572c2dcb97b2b9eb (diff) | |
download | scala-bb73b9669a96410bc9c513d061d090f5bd3c075e.tar.gz scala-bb73b9669a96410bc9c513d061d090f5bd3c075e.tar.bz2 scala-bb73b9669a96410bc9c513d061d090f5bd3c075e.zip |
[nomaster] macroExpandAll is now triggered in all invocations of typed
macroExpandAll is the key player in the mechanism of expanding macros after
their type arguments have been inferred. (Macro applications that contain
yet uninferred type arguments don't get expanded and are delayed until
the targs are inferred. Therefore later on we need to trigger those delayed
expansions manually, which is done by macroExpandAll).
Previously macroExpandAll was only called from a few selected places in
the typechecker, but that's quite risky, since typer evolves, and who knows
when this scheme breaks.
To make things more robust, I'm now calling macroExpandAll in the epilogue
of every single call to `typed`. Don't worry - this shouldn't impose
noticeable performance penalties, since the call is guarded by a branch
upon a plain boolean field.
NOTE: This patch is a second take on fixing implicit macros, with the first
one being a backport from macro paradise merged into master in January 2013:
https://github.com/scala/scala/commit/fe60284769.
The original fix had an unfortunate error, as described on scala-internals:
https://groups.google.com/forum/#!msg/scala-internals/7pA9CiiD3u8, so I had
to refine the approach here.
This means that it's not possible to directly merge this commit into master,
so I'm marking it as [nomaster] and will submit a separate pull request
targetting master later on.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 10 | ||||
-rw-r--r-- | test/files/pos/t5692c.check | 0 | ||||
-rw-r--r-- | test/files/pos/t5692c.scala | 4 |
4 files changed, 17 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 58cd0d1fe6..25091562b3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -796,8 +796,12 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val nowDelayed = !typer.context.macrosEnabled || undetparams.nonEmpty (wasDelayed, nowDelayed) match { - case (true, true) => Delay(expandee) - case (true, false) => Skip(macroExpandAll(typer, expandee)) + case (true, true) => + Delay(expandee) + case (true, false) => + val expanded = macroExpandAll(typer, expandee) + if (expanded exists (_.isErroneous)) Failure(expandee) + else Skip(expanded) case (false, true) => macroLogLite("macro expansion is delayed: %s".format(expandee)) delayed += expandee -> undetparams diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ac6caf8b7e..16481774d0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3059,8 +3059,7 @@ trait Typers extends Modes with Adaptations with Tags { else if (isByNameParamType(formals.head)) 0 else BYVALmode ) - var tree = typedArg(args.head, mode, typedMode, adapted.head) - if (hasPendingMacroExpansions) tree = macroExpandAll(this, tree) + val tree = typedArg(args.head, mode, typedMode, adapted.head) // formals may be empty, so don't call tail tree :: loop(args.tail, formals drop 1, adapted.tail) } @@ -5612,7 +5611,12 @@ trait Typers extends Modes with Adaptations with Tags { } tree1.tpe = pluginsTyped(tree1.tpe, this, tree1, mode, ptPlugins) - val result = if (tree1.isEmpty) tree1 else adapt(tree1, mode, ptPlugins, tree) + val result = + if (tree1.isEmpty) tree1 + else { + val result = adapt(tree1, mode, ptPlugins, tree) + if (hasPendingMacroExpansions) macroExpandAll(this, result) else result + } if (!alreadyTyped) { printTyping("adapted %s: %s to %s, %s".format( diff --git a/test/files/pos/t5692c.check b/test/files/pos/t5692c.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/pos/t5692c.check diff --git a/test/files/pos/t5692c.scala b/test/files/pos/t5692c.scala new file mode 100644 index 0000000000..fa5f0b2dcd --- /dev/null +++ b/test/files/pos/t5692c.scala @@ -0,0 +1,4 @@ +class C { + def foo[T: scala.reflect.ClassTag](xs: T*): Array[T] = ??? + foo() +}
\ No newline at end of file |