Skip to content

Commit

Permalink
fix scala#7034: make mapWithIndexConserve tailrec
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Jun 28, 2021
1 parent 10145ff commit 81c96d7
Show file tree
Hide file tree
Showing 4 changed files with 4,810 additions and 12 deletions.
34 changes: 23 additions & 11 deletions compiler/src/dotty/tools/dotc/core/Decorators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,29 @@ object Decorators {
* `xs` to themselves.
*/
def mapWithIndexConserve[U <: T](f: (T, Int) => U): List[U] =
def recur(xs: List[T], idx: Int): List[U] =
if xs.isEmpty then Nil
else
val x1 = f(xs.head, idx)
val xs1 = recur(xs.tail, idx + 1)
if (x1.asInstanceOf[AnyRef] eq xs.head.asInstanceOf[AnyRef])
&& (xs1 eq xs.tail)
then xs.asInstanceOf[List[U]]
else x1 :: xs1
recur(xs, 0)

@tailrec
def addAll(buf: ListBuffer[T], from: List[T], until: List[T]): ListBuffer[T] =
if from eq until then buf else addAll(buf += from.head, from.tail, until)

@tailrec
def loopWithBuffer(buf: ListBuffer[U], explore: List[T], idx: Int): List[U] = explore match
case Nil => buf.toList
case t :: rest => loopWithBuffer(buf += f(t, idx), rest, idx + 1)

@tailrec
def loop(keep: List[T], explore: List[T], idx: Int): List[U] = explore match
case Nil => keep.asInstanceOf[List[U]]
case t :: rest =>
val u = f(t, idx)
if u.asInstanceOf[AnyRef] eq t.asInstanceOf[AnyRef] then
loop(keep, rest, idx + 1)
else
val buf = addAll(new ListBuffer[T], keep, explore).asInstanceOf[ListBuffer[U]]
loopWithBuffer(buf += u, rest, idx + 1)

loop(xs, xs, 0)
end mapWithIndexConserve

final def hasSameLengthAs[U](ys: List[U]): Boolean = {
@tailrec def loop(xs: List[T], ys: List[U]): Boolean =
Expand Down Expand Up @@ -278,4 +291,3 @@ object Decorators {
def binarySearch(x: T): Int = java.util.Arrays.binarySearch(arr.asInstanceOf[Array[Object]], x)

}

3 changes: 3 additions & 0 deletions compiler/test/dotc/pos-from-tasty.blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ i10511.scala

# Violates tightened condition in Retyper#typedTyped
i11247.scala

# Tree is huge and blows stack for printing Text
i7034.scala
5 changes: 4 additions & 1 deletion compiler/test/dotc/pos-test-pickling.blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ i7740b.scala
i6507b.scala
i12299a.scala

# Tree is huge and blows stack for printing Text
i7034.scala

# Stale symbol: package object scala
seqtype-cycle

Expand Down Expand Up @@ -66,4 +69,4 @@ i2797a
# GADT cast applied to singleton type difference
i4176-gadt.scala

java-inherited-type1
java-inherited-type1
Loading

0 comments on commit 81c96d7

Please sign in to comment.