Skip to content

Commit 6e08077

Browse files
committed
Update test to show where the difference lies
1 parent c8722e4 commit 6e08077

File tree

2 files changed

+49
-45
lines changed

2 files changed

+49
-45
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
-- Error: tests/neg-custom-args/captures/effect-swaps.scala:62:6 -------------------------------------------------------
2-
61 | Result:
3-
62 | Future: // error, escaping label from Result
4-
| ^
5-
|local reference contextual$1 from (using contextual$1: boundary.Label[box Result[box Future[box T^?]^{fr, contextual$1, contextual$1}, box E^?]^?]^):
6-
| box Result[box Future[box T^?]^{fr, contextual$1, contextual$1}, box E^?]^? leaks into outer capture set of type parameter T of method apply in object boundary
7-
63 | fr.await.ok
1+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/effect-swaps.scala:64:8 ----------------------------------
2+
63 | Result:
3+
64 | Future: // error, escaping label from Result
4+
| ^
5+
| Found: Result.Ok[box Future[box T^?]^{fr, contextual$1}]
6+
| Required: Result[Future[T], Nothing]
7+
65 | fr.await.ok
88
|--------------------------------------------------------------------------------------------------------------------
99
|Inline stack trace
1010
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
11-
|This location contains code that was inlined from effect-swaps.scala:37
12-
37 | boundary:
13-
| ^^^^^^^^
11+
|This location contains code that was inlined from effect-swaps.scala:41
12+
41 | boundary(Ok(body))
13+
| ^^^^^^^^
1414
--------------------------------------------------------------------------------------------------------------------
15-
-- Error: tests/neg-custom-args/captures/effect-swaps.scala:66:11 ------------------------------------------------------
16-
66 | Result.make: // error, escaping label from Result
17-
| ^^^^^^^^^^^
15+
|
16+
| longer explanation available when compiling with `-explain`
17+
-- Error: tests/neg-custom-args/captures/effect-swaps.scala:68:15 ------------------------------------------------------
18+
68 | Result.make: //lbl ?=> // error, escaping label from Result
19+
| ^^^^^^^^^^^
1820
|local reference contextual$9 from (using contextual$9: boundary.Label[Result[box Future[box T^?]^{fr, contextual$9}, box E^?]]^):
1921
| box Future[box T^?]^{fr, contextual$9} leaks into outer capture set of type parameter T of method make in object Result

tests/neg-custom-args/captures/effect-swaps.scala

+34-32
Original file line numberDiff line numberDiff line change
@@ -14,55 +14,57 @@ end boundary
1414

1515
import boundary.{Label, break}
1616

17-
class Async
17+
@capability trait Async
18+
object Async:
19+
def blocking[T](body: Async ?=> T): T = ???
20+
1821
class Future[+T]:
1922
this: Future[T]^ =>
20-
def await(using Async^): T = ???
23+
def await(using Async): T = ???
2124
object Future:
22-
def apply[T](op: Async^ ?=> T)(using Async): Future[T]^{op} = ???
25+
def apply[T](op: Async ?=> T)(using Async): Future[T]^{op} = ???
26+
27+
enum Result[+T, +E]:
28+
case Ok[+T](value: T) extends Result[T, Nothing]
29+
case Err[+E](error: E) extends Result[Nothing, E]
2330

24-
abstract class Result[+T, +E]
25-
case class Ok[+T](value: T) extends Result[T, Nothing]
26-
case class Err[+E](value: E) extends Result[Nothing, E]
2731

2832
object Result:
29-
extension [T, E](r: Result[T, E])
33+
extension [T, E](r: Result[T, E]^)(using Label[Err[E]])
3034

3135
/** `_.ok` propagates Err to current Label */
32-
inline def ok(using Label[Result[Nothing, E]]): T = r match
33-
case r: Ok[_] => r.value
34-
case err => break(err.asInstanceOf[Err[E]])
36+
def ok: T = r match
37+
case Ok(value) => value
38+
case Err(value) => break[Err[E]](Err(value))
3539

3640
transparent inline def apply[T, E](inline body: Label[Result[T, E]] ?=> T): Result[T, E] =
37-
boundary:
38-
val result = body
39-
Ok(result)
41+
boundary(Ok(body))
4042

4143
// same as apply, but not an inline method
4244
def make[T, E](body: Label[Result[T, E]] ?=> T): Result[T, E] =
43-
boundary:
44-
val result = body
45-
Ok(result)
45+
boundary(Ok(body))
4646

4747
end Result
4848

4949
def test[T, E](using Async) =
50-
val good1: List[Future[Result[T, E]]] => Future[Result[List[T], E]] = frs =>
51-
Future:
52-
Result:
53-
frs.map(_.await.ok) // OK
50+
import Result.*
51+
Async.blocking: async ?=>
52+
val good1: List[Future[Result[T, E]]] => Future[Result[List[T], E]] = frs =>
53+
Future:
54+
Result:
55+
frs.map(_.await.ok) // OK
5456

55-
val good2: Result[Future[T], E] => Future[Result[T, E]] = rf =>
56-
Future:
57-
Result:
58-
rf.ok.await // OK, Future argument has type Result[T]
57+
val good2: Result[Future[T], E] => Future[Result[T, E]] = rf =>
58+
Future:
59+
Result:
60+
rf.ok.await // OK, Future argument has type Result[T]
5961

60-
def fail3(fr: Future[Result[T, E]]^) =
61-
Result:
62-
Future: // error, escaping label from Result
63-
fr.await.ok
62+
def fail3(fr: Future[Result[T, E]]^) =
63+
Result:
64+
Future: // error, escaping label from Result
65+
fr.await.ok
6466

65-
def fail4(fr: Future[Result[T, E]]^) =
66-
Result.make: // error, escaping label from Result
67-
Future:
68-
fr.await.ok
67+
def fail4[T, E](fr: Future[Result[T, E]]^) =
68+
Result.make: //lbl ?=> // error, escaping label from Result
69+
Future: fut ?=>
70+
fr.await.ok

0 commit comments

Comments
 (0)