Skip to content

Commit 28bb69c

Browse files
committed
Flatten nested capture sets in retainedElementsRaw
Without the added clause, i23570 looks like this after typer: ```scala [[syntax trees at end of typer]] // i23570.scala package <empty> { final lazy module val i23570$package: i23570$package = new i23570$package() final module class i23570$package() extends Object() { this: i23570$package.type => def f[C >: scala.caps.CapSet <: scala.caps.CapSet^{cap}]( xs: List[(() -> Unit)^{C}]): List[(() -> Unit)^{C}] = xs.reverse def test(io: Object^{cap}, async: Object^{cap}): Unit = { val ok: List[() ->{scala.caps.CapSet^{io}} Unit] = f[_root_.scala.caps.CapSet^{io}](Nil) val x: List[() ->{scala.caps.CapSet^{io}} Unit] -> List[() ->{scala.caps.CapSet^{io}} Unit] = (xs: List[() ->{scala.caps.CapSet^{io}} Unit]) => f[_root_.scala.caps.CapSet^{io}](xs) val y: List[() ->{scala.caps.CapSet^{io, async}} Unit] -> List[() ->{scala.caps.CapSet^{io, async}} Unit] = (xs: List[() ->{scala.caps.CapSet^{io, async}} Unit]) => f[_root_.scala.caps.CapSet^{io, async}](xs) () } } } ``` Note the nested capture sets in the types of `x` and `y`. Fixes #23570
1 parent fb66af2 commit 28bb69c

File tree

2 files changed

+9
-0
lines changed

2 files changed

+9
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ extension (tp: Type)
9494
def retainedElementsRaw(using Context): List[Type] = tp match
9595
case OrType(tp1, tp2) =>
9696
tp1.retainedElementsRaw ++ tp2.retainedElementsRaw
97+
case AnnotatedType(tp1, ann) if tp1.derivesFrom(defn.Caps_CapSet) && ann.symbol.isRetains =>
98+
ann.tree.retainedSet.retainedElementsRaw
9799
case tp =>
98100
// Nothing is a special type to represent the empty set
99101
if tp.isNothingType then Nil
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
def f[C^](xs: List[() ->{C} Unit]): List[() ->{C} Unit] =
2+
xs.reverse
3+
4+
def test(io: Object^, async: Object^): Unit =
5+
val ok = f[{io}](Nil)
6+
val x = f[{io}] // was error
7+
val y = f[{io, async}] // was error

0 commit comments

Comments
 (0)