Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

macroExpandAll is now triggered by typed

Previously delayed macro expansions (the sole purpose of macroExpandAll)
were triggered by `typedArgs`. Probably I wanted to save CPU cycles on
not checking whether we have pending macro expansions on every iteration
of typecheck.

However this optimization is uncalled for, because the check just entails
reading a var, therefore benefits of the current approach are negliible,
whereas the robustness hit is tangible.

After delayed macro expansion mechanism became more robust, it exposed
a bug, well-hidden before. If one first delays a macro and then finds out
that the expandee is erroneous, subsequent `macroExpandAll` will crash,
because it expects a macro runtime attachment to be present. Previously
the erroneous code path never got triggered, because the macro expansion
never commenced. Luckily the fix was easy.
  • Loading branch information...
commit 143cd7a307706a8884c9352e64addf6e9be0a181 1 parent fe60284
Eugene Burmako xeno-by authored
2  src/compiler/scala/tools/nsc/typechecker/Macros.scala
View
@@ -951,7 +951,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
new Transformer {
override def transform(tree: Tree) = super.transform(tree match {
// todo. expansion should work from the inside out
- case tree if (delayed contains tree) && calculateUndetparams(tree).isEmpty =>
+ case tree if (delayed contains tree) && calculateUndetparams(tree).isEmpty && !tree.isErroneous =>
val context = tree.attachments.get[MacroRuntimeAttachment].get.typerContext
delayed -= tree
context.implicitsEnabled = typer.context.implicitsEnabled
8 src/compiler/scala/tools/nsc/typechecker/Typers.scala
View
@@ -2892,7 +2892,6 @@ trait Typers extends Modes with Adaptations with Tags {
else BYVALmode
)
var tree = typedArg(args.head, mode, typedMode, adapted.head)
- if (hasPendingMacroExpansions) tree = macroExpandAll(this, tree)
// formals may be empty, so don't call tail
tree :: loop(args.tail, formals drop 1, adapted.tail)
}
@@ -5208,7 +5207,12 @@ trait Typers extends Modes with Adaptations with Tags {
}
tree1 modifyType (addAnnotations(tree1, _))
- val result = if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, tree)
+ val result =
+ if (tree1.isEmpty) tree1
+ else {
+ val result = adapt(tree1, mode, pt, tree)
+ if (hasPendingMacroExpansions) macroExpandAll(this, result) else result
+ }
if (!alreadyTyped) {
printTyping("adapted %s: %s to %s, %s".format(
4 test/files/neg/t5353.check
View
@@ -1,4 +0,0 @@
-t5353.scala:2: error: macro has not been expanded
- def f(x: Boolean) = if (x) Array("abc") else Array()
- ^
-one error found
3  test/files/neg/t5353.scala
View
@@ -1,3 +0,0 @@
-class A {
- def f(x: Boolean) = if (x) Array("abc") else Array()
-}
2  test/files/run/t5353.check
View
@@ -0,0 +1,2 @@
+1
+[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
9 test/files/run/t5353.scala
View
@@ -0,0 +1,9 @@
+object Test extends App {
+ def f(x: Boolean) = if (x) Array("abc") else Array()
+ try {
+ println(f(true).length)
+ println(f(false).length)
+ } catch {
+ case ex: Throwable => println(ex.getMessage)
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.