Skip to content

Commit 181d96e

Browse files
committed
A more realistic test case
Showing leak detection with simulated stdlib classes
1 parent 2043885 commit 181d96e

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Error: tests/neg-custom-args/captures/leaking-iterators.scala:56:2 --------------------------------------------------
2+
56 | usingLogFile: log => // error
3+
| ^^^^^^^^^^^^
4+
| local reference log leaks into outer capture set of type parameter R of method usingLogFile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package cctest
2+
import java.io.*
3+
4+
trait IterableOnce[+A]:
5+
//this: IterableOnce[A]^ =>
6+
def iterator: Iterator[A]^{this}
7+
8+
trait Iterable[+A] extends IterableOnce[A]:
9+
//this: IterableOnce[A]^ =>
10+
def iterator: Iterator[A]^{this}
11+
12+
trait List[+A] extends Iterable[A]:
13+
def head: A
14+
def tail: List[A]
15+
def length: Int
16+
def foldLeft[B](z: B)(op: (B, A) => B): B
17+
def foldRight[B](z: B)(op: (A, B) => B): B
18+
def foreach(f: A => Unit): Unit
19+
def iterator: Iterator[A]
20+
def map[B](f: A => B): List[B]
21+
def flatMap[B](f: A => IterableOnce[B]^): List[B]
22+
def ++[B >: A](xs: IterableOnce[B]^): List[B]
23+
object List:
24+
def apply[A](xs: A*): List[A] = ???
25+
26+
trait Iterator[+A] extends IterableOnce[A]:
27+
this: Iterator[A]^ =>
28+
def hasNext: Boolean
29+
def next(): A
30+
def foldLeft[B](z: B)(op: (B, A) => B): B
31+
def foldRight[B](z: B)(op: (A, B) => B): B
32+
def foreach(f: A => Unit): Unit
33+
34+
def map[B](f: A => B): Iterator[B]^{this, f}
35+
def flatMap[B](f: A => IterableOnce[B]^): Iterator[B]^{this, f}
36+
def ++[B >: A](xs: IterableOnce[B]^): Iterator[B]^{this, xs}
37+
end Iterator
38+
39+
private[this] final class ConcatIteratorCell[A](head: => IterableOnce[A]^):
40+
def headIterator: Iterator[A]^{this} = head.iterator
41+
42+
def usingLogFile[sealed R](op: FileOutputStream^ => R): R =
43+
val logFile = FileOutputStream("log")
44+
val result = op(logFile)
45+
logFile.close()
46+
result
47+
48+
def test =
49+
val xs = List(1, 2, 3)
50+
51+
usingLogFile: log =>
52+
xs.map: x =>
53+
log.write(x)
54+
x * x
55+
56+
usingLogFile: log => // error
57+
xs.iterator.map: x =>
58+
log.write(x)
59+
x * x
60+

0 commit comments

Comments
 (0)