summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/reflect
diff options
context:
space:
mode:
authorDenys Shabalin <denys.shabalin@typesafe.com>2014-04-01 22:26:55 +0200
committerDenys Shabalin <denys.shabalin@typesafe.com>2014-04-02 13:05:37 +0200
commit9fbac09b6ec7fcb1b2df75fcbc04bc795eccd669 (patch)
treec06549a36370a9a5a9f2d4c6fc7490647b481162 /src/compiler/scala/tools/reflect
parent8489be16b57a08f51bf3655c99cede52477b3022 (diff)
downloadscala-9fbac09b6ec7fcb1b2df75fcbc04bc795eccd669.tar.gz
scala-9fbac09b6ec7fcb1b2df75fcbc04bc795eccd669.tar.bz2
scala-9fbac09b6ec7fcb1b2df75fcbc04bc795eccd669.zip
SI-8466 fix quasiquote crash on recursively iterable unlifting
In order to handle unquoting quasiquotes needs to know if type is iterable and whats the depth of the iterable nesting which is called rank. (e.g. List[List[Tree]] is rank 2 iterable of Tree) The logic that checks depth of iterable nesting didn't take a situation where T is in fact Iterable[T] which caused infinite recursion in stripIterable function. In order to fix it stripIterable now always recurs no more than non-optional limit times.
Diffstat (limited to 'src/compiler/scala/tools/reflect')
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Holes.scala10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
index 55a28f9f20..68cc728eb3 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
@@ -43,13 +43,13 @@ trait Holes { self: Quasiquotes =>
tpe <:< NothingClass.tpe || tpe <:< NullClass.tpe
private def extractIterableTParam(tpe: Type) =
IterableTParam.asSeenFrom(tpe, IterableClass)
- private def stripIterable(tpe: Type, limit: Option[Rank] = None): (Rank, Type) =
- if (limit.map { _ == NoDot }.getOrElse { false }) (NoDot, tpe)
+ private def stripIterable(tpe: Type, limit: Rank = DotDotDot): (Rank, Type) =
+ if (limit == NoDot) (NoDot, tpe)
else if (tpe != null && !isIterableType(tpe)) (NoDot, tpe)
else if (isBottomType(tpe)) (NoDot, tpe)
else {
val targ = extractIterableTParam(tpe)
- val (rank, innerTpe) = stripIterable(targ, limit.map { _.pred })
+ val (rank, innerTpe) = stripIterable(targ, limit.pred)
(rank.succ, innerTpe)
}
private def iterableTypeFromRank(n: Rank, tpe: Type): Type = {
@@ -76,7 +76,7 @@ trait Holes { self: Quasiquotes =>
class ApplyHole(annotatedRank: Rank, unquotee: Tree) extends Hole {
val (strippedTpe, tpe): (Type, Type) = {
- val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = Some(annotatedRank))
+ val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = annotatedRank)
if (isBottomType(strippedTpe)) cantSplice()
else if (isNativeType(strippedTpe)) {
if (strippedRank != NoDot && !(strippedTpe <:< treeType) && !isLiftableType(strippedTpe)) cantSplice()
@@ -193,7 +193,7 @@ trait Holes { self: Quasiquotes =>
val (iterableRank, _) = stripIterable(tpe)
if (iterableRank.value < rank.value)
c.abort(pat.pos, s"Can't extract $tpe with $rank, consider using $iterableRank")
- val (_, strippedTpe) = stripIterable(tpe, limit = Some(rank))
+ val (_, strippedTpe) = stripIterable(tpe, limit = rank)
if (strippedTpe <:< treeType) treeNoUnlift
else
unlifters.spawn(strippedTpe, rank).map {