Skip to content

Commit 4314cdd

Browse files
committed
Fix retainedElements throwing exceptions on illegal refs too early
1 parent bdaef8a commit 4314cdd

File tree

4 files changed

+17
-12
lines changed

4 files changed

+17
-12
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,22 @@ extension (tree: Tree)
7878

7979
extension (tp: Type)
8080

81-
def retainedElements(using Context): List[CaptureRef] = tp match
81+
def retainedElementsRaw(using Context): List[Type] = tp match
8282
case ReachCapability(tp1) =>
8383
tp1.reach :: Nil
8484
case ReadOnlyCapability(tp1) =>
8585
tp1.readOnly :: Nil
86-
case tp: CaptureRef =>
86+
case OrType(tp1, tp2) =>
87+
tp1.retainedElementsRaw ++ tp2.retainedElementsRaw
88+
case tp =>
89+
// Nothing is a special type to represent the empty set
8790
if tp.isNothingType then Nil
8891
else tp :: Nil // should be checked by wellformedness
89-
case OrType(tp1, tp2) =>
90-
tp1.retainedElements ++ tp2.retainedElements
91-
case _ =>
92-
throw IllegalCaptureRef(tp)
92+
93+
def retainedElements(using Context): List[CaptureRef] =
94+
retainedElementsRaw.map:
95+
case tp: CaptureRef => tp
96+
case tp => throw IllegalCaptureRef(tp)
9397

9498
/** Is this type a CaptureRef that can be tracked?
9599
* This is true for

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ object CheckCaptures:
105105
report.error(em"$elem cannot be tracked since it is not a parameter or local value", pos)
106106
case tpe =>
107107
report.error(em"$elem: $tpe is not a legal element of a capture set", pos)
108-
for elem <- ann.retainedSet.retainedElements do
108+
for elem <- ann.retainedSet.retainedElementsRaw do
109109
elem match
110110
case ref: TypeRef =>
111111
val refSym = ref.symbol

tests/neg-custom-args/captures/capt1.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
| longer explanation available when compiling with `-explain`
5656
-- Error: tests/neg-custom-args/captures/capt1.scala:38:13 -------------------------------------------------------------
5757
38 | val z3 = h[(() -> Cap) @retains[x.type]](() => x)(() => C()) // error
58-
| ^^^^^^^^^^^^^^^^^^^^^^^
58+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959
| Type variable X of method h cannot be instantiated to box () ->{x} C^ since
6060
| the part C^ of that type captures the root capability `cap`.
6161
|
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1+
import language.experimental.captureChecking
12
import caps.*
23

34
trait AbstractWrong:
45
type C <: CapSet
56
def f(): Unit^{C} // error
67

78
trait Abstract1:
8-
type C >: CapSet <: CapSet^
9+
type C >: CapSet <: CapSet^ // error
910
def f(): Unit^{C}
1011

11-
// class Abstract2:
12-
// type C^
13-
// def f(): Unit^{C^}
12+
trait Abstract2:
13+
type C <: {cap}
14+
def f(): Unit^{C}

0 commit comments

Comments
 (0)