Skip to content

Commit

Permalink
Fix toFunctionType for methods containing reach capabilities in the r…
Browse files Browse the repository at this point in the history
…esult type
  • Loading branch information
odersky committed Nov 3, 2024
1 parent 0c5573a commit 571119a
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 3 deletions.
7 changes: 5 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ import config.Printers.{core, typr, matchTypes}
import reporting.{trace, Message}
import java.lang.ref.WeakReference
import compiletime.uninitialized
import cc.{CapturingType, CaptureRef, CaptureSet, SingletonCaptureRef, isTrackableRef,
derivedCapturingType, isBoxedCapturing, isCaptureChecking, isRetains, isRetainsLike}
import cc.*
import CaptureSet.{CompareResult, IdempotentCaptRefMap, IdentityCaptRefMap}

import scala.annotation.internal.sharable
Expand Down Expand Up @@ -4074,6 +4073,10 @@ object Types extends TypeUtils {
range(defn.NothingType, atVariance(1)(apply(tp.underlying)))
case CapturingType(_, _) =>
mapOver(tp)
case ReachCapability(tp1) =>
apply(tp1) match
case tp1a: CaptureRef if tp1a.isTrackableRef => tp1a.reach
case _ => defn.captureRoot.termRef
case AnnotatedType(parent, ann) if ann.refersToParamOf(thisLambdaType) =>
val parent1 = mapOver(parent)
if ann.symbol.isRetainsLike then
Expand Down
14 changes: 14 additions & 0 deletions tests/neg-custom-args/captures/depfun-reach.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/depfun-reach.scala:13:4 ----------------------------------
13 | op // error
| ^^
| Found: (xs: List[(X, box () ->{io} Unit)]) ->{op} List[box () ->{xs*} Unit]
| Required: (xs: List[(X, box () ->{io} Unit)]) => List[() -> Unit]
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/depfun-reach.scala:20:60 ---------------------------------
20 | val b: (xs: List[() ->{io} Unit]) => List[() ->{} Unit] = a // error
| ^
| Found: (xs: List[box () ->{io} Unit]) ->{a} List[box () ->{xs*} Unit]
| Required: (xs: List[box () ->{io} Unit]) => List[() -> Unit]
|
| longer explanation available when compiling with `-explain`
20 changes: 20 additions & 0 deletions tests/neg-custom-args/captures/depfun-reach.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import language.experimental.captureChecking
import caps.cap

def test(io: Object^, async: Object^) =
def compose(op: List[(() ->{cap} Unit, () ->{cap} Unit)]): List[() ->{op*} Unit] =
List(() => op.foreach((f,g) => { f(); g() }))

def compose1(op: List[(() ->{async} Unit, () ->{io} Unit)]): List[() ->{op*} Unit] =
compose(op)

def foo[X](op: (xs: List[(X, () ->{io} Unit)]) => List[() ->{xs*} Unit])
: (xs: List[(X, () ->{io} Unit)]) => List[() ->{} Unit] =
op // error

def boom(op: List[(() ->{async} Unit, () ->{io} Unit)]): List[() ->{} Unit] =
foo(compose1)(op)

def test2(io: Object^) =
val a: (xs: List[() ->{io} Unit]) => List[() ->{xs*} Unit] = ???
val b: (xs: List[() ->{io} Unit]) => List[() ->{} Unit] = a // error
7 changes: 6 additions & 1 deletion tests/pos-custom-args/captures/gears-problem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ extension [T](@use fs: Seq[Future[T]^])
val collector: Collector[T]{val futures: Seq[Future[T]^{fs*}]}
= Collector(fs)
// val ch = collector.results // also errors
val fut: Future[T]^{fs*} = collector.results.read().right.get // found ...^{caps.cap}
val fut: Future[T]^{fs*} = collector.results.read().right.get // found ...^{caps.cap}

val ch = collector.results
val item = ch.read()
val r = item.right
val fut2: Future[T]^{fs*} = r.get

0 comments on commit 571119a

Please sign in to comment.