Skip to content

Commit 4a84557

Browse files
committed
Add unsafeAssumePure method
Add unsafeAssumePure method as an escape hatch which is more specific than a cast.
1 parent 08de2ba commit 4a84557

File tree

5 files changed

+19
-2
lines changed

5 files changed

+19
-2
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,14 @@ class CheckCaptures extends Recheck, SymTransformer:
351351
val argType = super.recheckFinish(argType0, arg, pt)
352352
super.recheckFinish(argType, tree, pt)
353353

354-
if meth == defn.Caps_unsafeBox then
354+
if meth == defn.Caps_unsafeAssumePure then
355+
val arg :: Nil = tree.args: @unchecked
356+
val argType0 = recheck(arg, pt.capturing(CaptureSet.universal))
357+
val argType = if argType0.captureSet.isAlwaysEmpty then argType0
358+
else argType0.widen.stripCapturing
359+
capt.println(i"rechecking $arg with ${pt.capturing(CaptureSet.universal)}: $argType")
360+
super.recheckFinish(argType, tree, pt)
361+
else if meth == defn.Caps_unsafeBox then
355362
mapArgUsing(_.forceBoxStatus(true))
356363
else if meth == defn.Caps_unsafeUnbox then
357364
mapArgUsing(_.forceBoxStatus(false))

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ class Definitions {
972972
@tu lazy val CapsModule: Symbol = requiredModule("scala.caps")
973973
@tu lazy val captureRoot: TermSymbol = CapsModule.requiredValue("cap")
974974
@tu lazy val CapsUnsafeModule: Symbol = requiredModule("scala.caps.unsafe")
975+
@tu lazy val Caps_unsafeAssumePure: Symbol = CapsUnsafeModule.requiredMethod("unsafeAssumePure")
975976
@tu lazy val Caps_unsafeBox: Symbol = CapsUnsafeModule.requiredMethod("unsafeBox")
976977
@tu lazy val Caps_unsafeUnbox: Symbol = CapsUnsafeModule.requiredMethod("unsafeUnbox")
977978
@tu lazy val Caps_unsafeBoxFunArg: Symbol = CapsUnsafeModule.requiredMethod("unsafeBoxFunArg")

library/src/scala/annotation/internal/WithPureFuns.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package scala.annotation
22
package internal
3-
import annotation.experimental
43

54
/** A marker annotation on a toplevel class that indicates
65
* that the class was typed with the pureFunctions language import.

library/src/scala/caps.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ import annotation.experimental
1414
object unsafe:
1515

1616
extension [T](x: T)
17+
/** A specific cast operation to remove a capture set.
18+
* If argument is of type `T^C`, assume it is of type `T` instead.
19+
* Calls to this method are treated specially by the capture checker.
20+
*/
21+
def unsafeAssumePure: T = x
22+
1723
/** If argument is of type `cs T`, converts to type `box cs T`. This
1824
* avoids the error that would be raised when boxing `*`.
1925
*/
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class C
2+
import caps.unsafe.*
3+
4+
def foo(x: C^): C = x.unsafeAssumePure

0 commit comments

Comments
 (0)