Skip to content

Commit 496c866

Browse files
committed
Fix dcs for invariant type parameters
Also: add test that reach capabilities are contained inside boxes
1 parent adf6a25 commit 496c866

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,13 +1116,15 @@ object CaptureSet:
11161116
/** The deep capture set of a type is the union of all covariant occurrences of
11171117
* capture sets. Nested existential sets are approximated with `cap`.
11181118
* NOTE: The traversal logic needs to be in sync with narrowCaps in CaptureOps, which
1119-
* replaces caps with reach capabilties.
1119+
* replaces caps with reach capabilties. The one exception to this is invariant
1120+
* arguments. This have to be included to be conservative in dcs but must be
1121+
* excluded in narrowCaps.
11201122
*/
11211123
def ofTypeDeeply(tp: Type)(using Context): CaptureSet =
11221124
val collect = new TypeAccumulator[CaptureSet]:
11231125
val seen = util.HashSet[Symbol]()
11241126
def apply(cs: CaptureSet, t: Type) =
1125-
if variance <= 0 then cs
1127+
if variance < 0 then cs
11261128
else t.dealias match
11271129
case t @ CapturingType(p, cs1) =>
11281130
this(cs, p) ++ cs1
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Box[A](val elem: A)
2+
class CoBox[+A](val elem: A)
3+
4+
def applyAll[A](fs: Box[A => Unit], x: A): Box[() ->{fs*} Unit] =
5+
Box(() => fs.elem(x))
6+
7+
def applyAllCo[A](fs: CoBox[A => Unit], x: A): CoBox[() ->{fs*} Unit] =
8+
CoBox(() => fs.elem(x))
9+
10+
// Same with inferred result types
11+
def test =
12+
def applyAll[A](fs: Box[A => Unit], x: A) =
13+
Box(() => fs.elem(x))
14+
15+
def applyAllCo[A](fs: CoBox[A => Unit], x: A) =
16+
CoBox(() => fs.elem(x))
17+

0 commit comments

Comments
 (0)