Skip to content

fix #7034: make mapWithIndexConserve tailrec #12972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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