Skip to content

Commit 8fa8ee9

Browse files
committed
Patch the files to make them compile without JDK21
1 parent 22afd66 commit 8fa8ee9

File tree

4 files changed

+114
-115
lines changed

4 files changed

+114
-115
lines changed

tests/neg-custom-args/captures/gears/CCBehavior.scala

Lines changed: 86 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -25,93 +25,90 @@ object Result:
2525
case Left(value) => boundary.break(Left(value))
2626
case Right(value) => value
2727

28-
class CaptureCheckingBehavior extends munit.FunSuite:
29-
import Result.*
30-
import caps.use
31-
import scala.collection.mutable
32-
33-
test("good") {
34-
// don't do this in real code! capturing Async.blocking's Async context across functions is hard to track
35-
Async.blocking: async ?=>
36-
def good1[T, E](@use frs: List[Future[Result[T, E]]^]): Future[Result[List[T], E]]^{frs*, async} =
28+
import Result.*
29+
30+
def good =
31+
// don't do this in real code! capturing Async.blocking's Async context across functions is hard to track
32+
Async.blocking: async ?=>
33+
def good1[T, E](@caps.use frs: List[Future[Result[T, E]]^]): Future[Result[List[T], E]]^{frs*, async} =
34+
Future: fut ?=>
35+
Result: ret ?=>
36+
frs.map(_.await.ok)
37+
38+
def good2[T, E](@caps.use rf: Result[Future[T]^, E]): Future[Result[T, E]]^{rf*, async} =
39+
Future:
40+
Result:
41+
rf.ok.await // OK, Future argument has type Result[T]
42+
43+
def useless4[T, E](fr: Future[Result[T, E]]^) =
44+
fr.await.map(Future(_))
45+
46+
47+
def `bad - collectors` =
48+
val futs: Seq[Future[Int]^] = Async.blocking: async ?=> // error
49+
val fs: Seq[Future[Int]^{async}] = (0 to 10).map(i => Future { i })
50+
fs
51+
Async.blocking:
52+
futs.awaitAll // error
53+
54+
55+
def `future withResolver capturing` = {
56+
class File() extends caps.Capability:
57+
def close() = ()
58+
def read(callback: Int => Unit) = ()
59+
val f = File()
60+
val read = Future.withResolver[Int, caps.CapSet^{f}]: r =>
61+
f.read(r.resolve)
62+
r.onCancel(f.close)
63+
}
64+
65+
def `awaitAll/awaitFirst` = {
66+
trait File extends caps.Capability:
67+
def readFut(): Future[Int]^{this}
68+
object File:
69+
def open[T](filename: String)(body: File => T)(using Async): T = ???
70+
71+
def readAll(@caps.use files: (File^)*) = files.map(_.readFut())
72+
73+
Async.blocking: // error
74+
File.open("a.txt"): a => // error
75+
File.open("b.txt"): b => // error
76+
val futs = readAll(a, b)
77+
val allFut = Future(futs.awaitAll)
78+
allFut
79+
// .await // uncomment to leak
80+
}
81+
82+
def `channel` = {
83+
trait File extends caps.Capability:
84+
def read(): Int = ???
85+
Async.blocking:
86+
val ch = SyncChannel[File]() // error
87+
// Sender
88+
val sender = Future:
89+
val f = new File {}
90+
ch.send(f)
91+
val recv = Future:
92+
val f = ch.read().right.get
93+
f.read()
94+
}
95+
96+
def `upcasting to any` = {
97+
Async.blocking: async ?=>
98+
def fail3[T, E](fr: Future[Result[T, E]]^): Result[Any, Any] =
99+
Result: label ?=> // escaping label from Result, not yet err
37100
Future: fut ?=>
38-
Result: ret ?=>
39-
frs.map(_.await.ok)
40-
41-
def good2[T, E](@use rf: Result[Future[T]^, E]): Future[Result[T, E]]^{rf*, async} =
42-
Future:
43-
Result:
44-
rf.ok.await // OK, Future argument has type Result[T]
45-
46-
def useless4[T, E](fr: Future[Result[T, E]]^) =
47-
fr.await.map(Future(_))
48-
}
49-
50-
// test("bad - collectors") {
51-
// val futs: Seq[Future[Int]^] = Async.blocking: async ?=>
52-
// val fs: Seq[Future[Int]^{async}] = (0 to 10).map(i => Future { i })
53-
// fs
54-
// Async.blocking:
55-
// futs.awaitAll // should not compile
56-
// }
57-
58-
test("future withResolver capturing") {
59-
class File() extends caps.Capability:
60-
def close() = ()
61-
def read(callback: Int => Unit) = ()
62-
val f = File()
63-
val read = Future.withResolver[Int, caps.CapSet^{f}]: r =>
64-
f.read(r.resolve)
65-
r.onCancel(f.close)
66-
}
67-
68-
test("awaitAll/awaitFirst") {
69-
trait File extends caps.Capability:
70-
def readFut(): Future[Int]^{this}
71-
object File:
72-
def open[T](filename: String)(body: File => T)(using Async): T = ???
73-
74-
def readAll(@caps.use files: (File^)*) = files.map(_.readFut())
75-
76-
Async.blocking:
77-
File.open("a.txt"): a =>
78-
File.open("b.txt"): b =>
79-
val futs = readAll(a, b)
80-
val allFut = Future(futs.awaitAll)
81-
allFut
82-
.await // uncomment to leak
83-
}
84-
85-
// test("channel") {
86-
// trait File extends caps.Capability:
87-
// def read(): Int = ???
88-
// Async.blocking:
89-
// val ch = SyncChannel[File]()
90-
// // Sender
91-
// val sender = Future:
92-
// val f = new File {}
93-
// ch.send(f)
94-
// val recv = Future:
95-
// val f = ch.read().right.get
96-
// f.read()
97-
// }
98-
99-
test("very bad") {
100-
Async.blocking: async ?=>
101-
def fail3[T, E](fr: Future[Result[T, E]]^): Result[Any, Any] =
102-
Result: label ?=>
103-
Future: fut ?=>
104-
fr.await.ok // error, escaping label from Result
105-
106-
// val fut = Future(Left(5))
107-
// val res = fail3(fut)
108-
// println(res.right.get.asInstanceOf[Future[Any]].awaitResult)
109-
}
110-
111-
// test("bad") {
112-
// Async.blocking: async ?=>
113-
// def fail3[T, E](fr: Future[Result[T, E]]^): Result[Future[T]^{async}, E] =
114-
// Result: label ?=>
115-
// Future: fut ?=>
116-
// fr.await.ok // error, escaping label from Result
117-
// }
101+
fr.await.ok
102+
103+
// val fut = Future(Left(5))
104+
// val res = fail3(fut)
105+
// println(res.right.get.asInstanceOf[Future[Any]].awaitResult)
106+
}
107+
108+
def `bad` = {
109+
Async.blocking: async ?=>
110+
def fail3[T, E](fr: Future[Result[T, E]]^): Result[Future[T]^{async}, E] =
111+
Result: label ?=> // error, escaping label from Result
112+
Future: fut ?=>
113+
fr.await.ok
114+
}

tests/neg-custom-args/captures/gears/VThreadSupport.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import scala.annotation.constructorOnly
1010
import scala.collection.mutable
1111

1212
object VThreadScheduler extends Scheduler:
13-
private val VTFactory = Thread
14-
.ofVirtual()
15-
.name("gears.async.VThread-", 0L)
16-
.factory()
13+
private val VTFactory = new java.util.concurrent.ThreadFactory:
14+
def newThread(r: Runnable): Thread =
15+
new Thread(null, r, "gears.async.VThread-", 0L)
1716

1817
override def execute(body: Runnable): Unit =
1918
val th = VTFactory.newThread(body)

tests/neg-custom-args/captures/gears/clientAndServerUDP.scala

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ import PosixLikeIO.{PIOHelper, SocketUDP}
2222
serverSocket.send(ByteBuffer.wrap(responseMessage), got.getAddress.toString.substring(1), got.getPort)
2323
sleep(50)
2424

25-
def client(value: Int): Future[Unit] =
26-
Future:
27-
PIOHelper.withSocketUDP(): clientSocket =>
28-
val data: Array[Byte] = value.toString.getBytes
29-
clientSocket.send(ByteBuffer.wrap(data), "localhost", 8134).awaitResult.get
30-
val responseDatagram = clientSocket.receive().awaitResult.get
31-
val messageReceived = String(responseDatagram.getData.slice(0, responseDatagram.getLength), "UTF-8").toInt
32-
println("Sent " + value.toString + " and got " + messageReceived.toString + " in return.")
25+
def client(value: Int)(using Async) =
26+
PIOHelper.withSocketUDP(): clientSocket =>
27+
val data: Array[Byte] = value.toString.getBytes
28+
clientSocket.send(ByteBuffer.wrap(data), "localhost", 8134).awaitResult.get
29+
val responseDatagram = clientSocket.receive().awaitResult.get
30+
val messageReceived = String(responseDatagram.getData.slice(0, responseDatagram.getLength), "UTF-8").toInt
31+
println("Sent " + value.toString + " and got " + messageReceived.toString + " in return.")
3332

34-
client(100).await
33+
client(100)
3534
server.await

tests/neg-custom-args/captures/gears/measureTimes.scala

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ import scala.util.Try
1616

1717
import PosixLikeIO.PIOHelper
1818

19+
private val VTFactory = new java.util.concurrent.ThreadFactory:
20+
def newThread(r: Runnable): Thread =
21+
new Thread(null, r, "gears.async.VThread-", 0L)
22+
1923
case class TimeMeasurementResult(millisecondsPerOperation: Double, standardDeviation: Double)
2024

2125
def measureIterations[T](action: () => T): Int =
2226
val counter = AtomicInteger(0)
2327

24-
val t1 = Thread.startVirtualThread: () =>
28+
val t1 = VTFactory.newThread: () =>
2529
try {
2630
while (!Thread.interrupted()) {
2731
action()
@@ -41,7 +45,7 @@ def measureIterations[T](action: () => T): Int =
4145
given ExecutionContext = ExecutionContext.global
4246

4347
val threadJoins = measureIterations: () =>
44-
val t = Thread.startVirtualThread: () =>
48+
val t = VTFactory.newThread: () =>
4549
var z = 1
4650
t.join()
4751

@@ -114,21 +118,21 @@ def measureIterations[T](action: () => T): Int =
114118

115119
val c2: Double = measureIterations: () =>
116120
@volatile var i1 = true
117-
val f11 = Thread.startVirtualThread(() => { Thread.sleep(10); i1 = false })
118-
val f12 = Thread.startVirtualThread(() => { Thread.sleep(50); i1 = false })
119-
val f13 = Thread.startVirtualThread(() => { Thread.sleep(100); i1 = false })
121+
val f11 = VTFactory.newThread(() => { Thread.sleep(10); i1 = false })
122+
val f12 = VTFactory.newThread(() => { Thread.sleep(50); i1 = false })
123+
val f13 = VTFactory.newThread(() => { Thread.sleep(100); i1 = false })
120124
while (i1) ()
121125

122126
@volatile var i2 = true
123-
val f21 = Thread.startVirtualThread(() => { Thread.sleep(100); i2 = false })
124-
val f22 = Thread.startVirtualThread(() => { Thread.sleep(10); i2 = false })
125-
val f23 = Thread.startVirtualThread(() => { Thread.sleep(50); i2 = false })
127+
val f21 = VTFactory.newThread(() => { Thread.sleep(100); i2 = false })
128+
val f22 = VTFactory.newThread(() => { Thread.sleep(10); i2 = false })
129+
val f23 = VTFactory.newThread(() => { Thread.sleep(50); i2 = false })
126130
while (i2) ()
127131

128132
@volatile var i3 = true
129-
val f31 = Thread.startVirtualThread(() => { Thread.sleep(50); i3 = false })
130-
val f32 = Thread.startVirtualThread(() => { Thread.sleep(100); i3 = false })
131-
val f33 = Thread.startVirtualThread(() => { Thread.sleep(10); i3 = false })
133+
val f31 = VTFactory.newThread(() => { Thread.sleep(50); i3 = false })
134+
val f32 = VTFactory.newThread(() => { Thread.sleep(100); i3 = false })
135+
val f33 = VTFactory.newThread(() => { Thread.sleep(10); i3 = false })
132136
while (i3) ()
133137

134138
f11.interrupt()
@@ -164,7 +168,7 @@ def measureIterations[T](action: () => T): Int =
164168
// java
165169
@volatile var shared: Long = 0
166170
@volatile var timeForWriting = true
167-
val t1 = Thread.startVirtualThread: () =>
171+
val t1 = VTFactory.newThread: () =>
168172
var i: Long = 0
169173
while (true) {
170174
while (!timeForWriting) ()
@@ -173,7 +177,7 @@ def measureIterations[T](action: () => T): Int =
173177
i += 1
174178
}
175179

176-
val t2 = Thread.startVirtualThread: () =>
180+
val t2 = VTFactory.newThread: () =>
177181
while (true) {
178182
while (timeForWriting) ()
179183
var z = shared

0 commit comments

Comments
 (0)