Skip to content

Commit f583aa9

Browse files
authored
Merge pull request scala#8417 from som-snytt/tweak/reachability
Improve reachability test
2 parents 7986814 + a977abd commit f583aa9

File tree

2 files changed

+11
-14
lines changed

2 files changed

+11
-14
lines changed

src/testkit/scala/tools/testkit/AssertUtil.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,24 @@ object AssertUtil {
107107
*/
108108
def assertNotReachable[A <: AnyRef](a: => A, roots: AnyRef*)(body: => Unit): Unit = {
109109
val wkref = new WeakReference(a)
110-
def refs(root: AnyRef): mutable.Set[AnyRef] = {
110+
// fail if following strong references from root discovers referent. Quit if ref is empty.
111+
def assertNoRef(root: AnyRef): Unit = {
111112
val seen = new IdentityHashMap[AnyRef, Unit]
112113
def loop(o: AnyRef): Unit =
113114
if (wkref.nonEmpty && o != null && !seen.containsKey(o)) {
114115
seen.put(o, ())
116+
assertTrue(s"Root $root held reference $o", o ne wkref.get)
115117
for {
116118
f <- o.getClass.allFields
117119
if !Modifier.isStatic(f.getModifiers)
118120
if !f.getType.isPrimitive
119121
if !classOf[Reference[_]].isAssignableFrom(f.getType)
120-
} loop(f follow o)
122+
} loop(f.follow(o))
121123
}
122124
loop(root)
123-
seen.keySet.asScala
124125
}
125126
body
126-
for (r <- roots if wkref.nonEmpty) {
127-
assertFalse(s"Root $r held reference", refs(r) contains wkref.get)
128-
}
127+
roots.foreach(assertNoRef)
129128
}
130129

131130
/** Assert no new threads, with some margin for arbitrary threads to exit. */

test/junit/scala/collection/IteratorTest.scala

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ class IteratorTest {
631631

632632
@Test def `flatMap is memory efficient in previous element`(): Unit = {
633633
import java.lang.ref._
634+
import scala.util.chaining._
634635
// Array.iterator holds onto array reference; by contrast, iterating over List walks tail.
635636
// Avoid reaching seq1 through test class. Avoid testing Array.iterator.
636637
class C extends Iterable[String] {
@@ -641,11 +642,7 @@ class IteratorTest {
641642

642643
def hasNext = i < ss.length
643644

644-
def next() =
645-
if (hasNext) {
646-
val res = ss(i); i += 1; res
647-
}
648-
else Iterator.empty.next()
645+
def next() = if (hasNext) ss(i).tap(_ => i += 1) else Iterator.empty.next()
649646
}
650647

651648
def apply(i: Int) = ss(i)
@@ -654,13 +651,14 @@ class IteratorTest {
654651
val seq2 = List("third")
655652
val it0: Iterator[Int] = Iterator(1, 2)
656653
lazy val it: Iterator[String] = it0.flatMap {
657-
case 1 => seq1.get
658-
case _ => check(); seq2
654+
case 1 => Option(seq1.get).getOrElse(Nil)
655+
case 2 => check(); seq2
656+
case _ => ???
659657
}
660658

661659
def check() = assertNotReachable(seq1.get, it)(())
662660

663-
def checkHasElement() = assertNotReachable(seq1.get.apply(1), it)(())
661+
def checkHasElement() = assertNotReachable(Option(seq1.get).map(_.apply(1)).orNull, it)(())
664662

665663
assert(it.hasNext)
666664
assertEquals("first", it.next())

0 commit comments

Comments
 (0)