File tree Expand file tree Collapse file tree 4 files changed +57
-6
lines changed
compiler/src/dotty/tools/dotc Expand file tree Collapse file tree 4 files changed +57
-6
lines changed Original file line number Diff line number Diff line change @@ -227,6 +227,14 @@ extension (tp: Type)
227
227
case tp : OrType => tp.tp1.isBoxedCapturing || tp.tp2.isBoxedCapturing
228
228
case _ => false
229
229
230
+ /** Is the box status of `tp` and `tp2` compatible? I.ee they are
231
+ * box boxed, or both unboxed, or one of them has an empty capture set.
232
+ */
233
+ def isBoxCompatibleWith (tp2 : Type )(using Context ): Boolean =
234
+ isBoxedCapturing == tp2.isBoxedCapturing
235
+ || tp.captureSet.isAlwaysEmpty
236
+ || tp2.captureSet.isAlwaysEmpty
237
+
230
238
/** If this type is a capturing type, the version with boxed statues as given by `boxed`.
231
239
* If it is a TermRef of a capturing type, and the box status flips, widen to a capturing
232
240
* type that captures the TermRef.
Original file line number Diff line number Diff line change @@ -2403,7 +2403,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2403
2403
else
2404
2404
def mergedGlb (tp1 : Type , tp2 : Type ): Type =
2405
2405
val tp1a = dropIfSuper(tp1, tp2)
2406
- if tp1a ne tp1 then glb(tp1a, tp2)
2406
+ if tp1a ne tp1 then
2407
+ glb(tp1a, tp2)
2407
2408
else
2408
2409
val tp2a = dropIfSuper(tp2, tp1)
2409
2410
if tp2a ne tp2 then glb(tp1, tp2a)
@@ -2721,11 +2722,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2721
2722
case tp1 : TypeVar if tp1.isInstantiated =>
2722
2723
tp1.underlying & tp2
2723
2724
case CapturingType (parent1, refs1) =>
2724
- val refs2 = tp2.captureSet
2725
- if subCaptures(refs2, refs1, frozen = true ).isOK
2726
- && tp1.isBoxedCapturing == tp2.isBoxedCapturing
2727
- then (parent1 & tp2).capturing(refs2 )
2728
- else tp1.derivedCapturingType(parent1 & tp2, refs1)
2725
+ val jointRefs = refs1 ** tp2.captureSet
2726
+ if jointRefs.isAlwaysEmpty then parent1 & tp2
2727
+ else if tp1.isBoxCompatibleWith( tp2) then
2728
+ tp1.derivedCapturingType (parent1 & tp2, jointRefs )
2729
+ else NoType
2729
2730
case tp1 : AnnotatedType if ! tp1.isRefining =>
2730
2731
tp1.underlying & tp2
2731
2732
case _ =>
Original file line number Diff line number Diff line change
1
+ import language .experimental .captureChecking
2
+
3
+ trait Future [+ T ]:
4
+ def await : T
5
+
6
+ trait Channel [+ T ]:
7
+ def read (): Ok [T ]
8
+
9
+ class Collector [T ](val futures : Seq [Future [T ]^ ]):
10
+ val results : Channel [Future [T ]^ {futures* }] = ???
11
+ end Collector
12
+
13
+ class Result [+ T , + E ]:
14
+ def get : T = ???
15
+
16
+ case class Err [+ E ](e : E ) extends Result [Nothing , E ]
17
+ case class Ok [+ T ](x : T ) extends Result [T , Nothing ]
18
+
19
+ extension [T ](fs : Seq [Future [T ]^ ])
20
+ def awaitAll =
21
+ val collector // : Collector[T]{val futures: Seq[Future[T]^{fs*}]}
22
+ = Collector (fs)
23
+ // val ch = collector.results // also errors
24
+ val fut : Future [T ]^ {fs* } = collector.results.read().get // found ...^{caps.cap}
Original file line number Diff line number Diff line change
1
+ import language .experimental .captureChecking
2
+
3
+ trait Future [+ T ]:
4
+ def await : T
5
+
6
+ trait Channel [T ]:
7
+ def read (): Either [Nothing , T ]
8
+
9
+ class Collector [T ](val futures : Seq [Future [T ]^ ]):
10
+ val results : Channel [Future [T ]^ {futures* }] = ???
11
+ end Collector
12
+
13
+ extension [T ](fs : Seq [Future [T ]^ ])
14
+ def awaitAll =
15
+ val collector : Collector [T ]{val futures : Seq [Future [T ]^ {fs* }]}
16
+ = Collector (fs)
17
+ // val ch = collector.results // also errors
18
+ val fut : Future [T ]^ {fs* } = collector.results.read().right.get // found ...^{caps.cap}
You can’t perform that action at this time.
0 commit comments