Skip to content

Commit 96b0eff

Browse files
aztekxeno-by
authored andcommitted
SI-5824 Fix crashes in reify with _*
Reification crashes if "foo: _*" construct is used. This happens besause type tree is represented either with TypeTree, or with Ident (present case), and `toPreTyperTypedOrAnnotated' only matches of the former. The fix is to cover the latter too. A test is included.
1 parent 3d318be commit 96b0eff

File tree

5 files changed

+25
-5
lines changed

5 files changed

+25
-5
lines changed

src/compiler/scala/reflect/reify/codegen/GenTrees.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ trait GenTrees {
177177
// then we can reify the scrutinee as a symless AST and that will definitely be hygienic
178178
// why? because then typechecking of a scrutinee doesn't depend on the environment external to the quasiquote
179179
// otherwise we need to reify the corresponding type
180-
if (sym.isLocalToReifee || tpe.isLocalToReifee)
180+
if (sym.isLocalToReifee || tpe.isLocalToReifee || treeInfo.isWildcardStarType(tree))
181181
reifyProduct(tree)
182182
else {
183183
if (reifyDebug) println("reifying bound type %s (underlying type is %s)".format(sym, tpe))

src/compiler/scala/reflect/reify/phases/Reshape.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,24 +188,28 @@ trait Reshape {
188188
}
189189

190190
private def toPreTyperTypedOrAnnotated(tree: Tree): Tree = tree match {
191-
case ty @ Typed(expr1, tt @ TypeTree()) =>
191+
case ty @ Typed(expr1, tpt) =>
192192
if (reifyDebug) println("reify typed: " + tree)
193+
val original = tpt match {
194+
case tt @ TypeTree() => tt.original
195+
case tpt => tpt
196+
}
193197
val annotatedArg = {
194198
def loop(tree: Tree): Tree = tree match {
195199
case annotated1 @ Annotated(ann, annotated2 @ Annotated(_, _)) => loop(annotated2)
196200
case annotated1 @ Annotated(ann, arg) => arg
197201
case _ => EmptyTree
198202
}
199203

200-
loop(tt.original)
204+
loop(original)
201205
}
202206
if (annotatedArg != EmptyTree) {
203207
if (annotatedArg.isType) {
204208
if (reifyDebug) println("verdict: was an annotated type, reify as usual")
205209
ty
206210
} else {
207-
if (reifyDebug) println("verdict: was an annotated value, equivalent is " + tt.original)
208-
toPreTyperTypedOrAnnotated(tt.original)
211+
if (reifyDebug) println("verdict: was an annotated value, equivalent is " + original)
212+
toPreTyperTypedOrAnnotated(original)
209213
}
210214
} else {
211215
if (reifyDebug) println("verdict: wasn't annotated, reify as usual")

src/reflect/scala/reflect/internal/TreeInfo.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,13 @@ abstract class TreeInfo {
431431
case _ => false
432432
}
433433

434+
/** Is the argument a wildcard star type of the form `_*`?
435+
*/
436+
def isWildcardStarType(tree: Tree): Boolean = tree match {
437+
case Ident(tpnme.WILDCARD_STAR) => true
438+
case _ => false
439+
}
440+
434441
/** Is this pattern node a catch-all (wildcard or variable) pattern? */
435442
def isDefaultCase(cdef: CaseDef) = cdef match {
436443
case CaseDef(pat, EmptyTree, _) => isWildcardArg(pat)

test/files/run/t5824.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a b c

test/files/run/t5824.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.reflect.runtime.universe._
2+
import scala.tools.reflect.Eval
3+
4+
object Test extends App {
5+
reify {
6+
println("%s %s %s".format(List("a", "b", "c"): _*))
7+
}.eval
8+
}

0 commit comments

Comments
 (0)