Skip to content

Commit 128cf25

Browse files
committed
Make Mutable extend Unscoped
Fix: the APPLY rule had to be changed so that it does not kick in if the result has Unscoped capabilities. These need to be preserved, we cannot approximate by the (possibly pure) function type.
1 parent 695e18f commit 128cf25

31 files changed

+185
-159
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ object Capabilities:
566566
def derivesFromCapability(using Context): Boolean = derivesFromCapTrait(defn.Caps_Capability)
567567
def derivesFromStateful(using Context): Boolean = derivesFromCapTrait(defn.Caps_Stateful)
568568
def derivesFromShared(using Context): Boolean = derivesFromCapTrait(defn.Caps_SharedCapability)
569+
def derivesFromUnscoped(using Context): Boolean = derivesFromCapTrait(defn.Caps_Unscoped)
569570

570571
/** The capture set consisting of exactly this reference */
571572
def singletonCaptureSet(using Context): CaptureSet.Const =

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ extension (tp: Type)
397397
def derivesFromCapability(using Context): Boolean = derivesFromCapTrait(defn.Caps_Capability)
398398
def derivesFromStateful(using Context): Boolean = derivesFromCapTrait(defn.Caps_Stateful)
399399
def derivesFromShared(using Context): Boolean = derivesFromCapTrait(defn.Caps_SharedCapability)
400-
def derivesFromExclusive(using Context): Boolean = derivesFromCapTrait(defn.Caps_ExclusiveCapability)
400+
def derivesFromUnscoped(using Context): Boolean = derivesFromCapTrait(defn.Caps_Unscoped)
401401

402402
/** Drop @retains annotations everywhere */
403403
def dropAllRetains(using Context): Type = // TODO we should drop retains from inferred types before unpickling

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ class CheckCaptures extends Recheck, SymTransformer:
864864
&& !resultType.isBoxedCapturing
865865
&& !tree.fun.symbol.isConstructor
866866
&& !resultType.captureSet.containsResultCapability
867+
&& !resultType.captureSet.elems.exists(_.derivesFromUnscoped)
867868
&& qualCaptures.mightSubcapture(refs)
868869
&& argCaptures.forall(_.mightSubcapture(refs)) =>
869870
val callCaptures = argCaptures.foldLeft(qualCaptures)(_ ++ _)

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
288288
if elideCapabilityCaps
289289
&& parent.derivesFromCapability
290290
&& refs.containsTerminalCapability
291-
&& (!parent.derivesFromExclusive || refs.isReadOnly)
291+
&& (!parent.derivesFromStateful || refs.isReadOnly)
292292
then toText(parent)
293293
else toTextCapturing(parent, refs, boxText)
294294
case tp @ RetainingType(parent, refSet) =>

library/src/scala/caps/package.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ trait Separate extends Stateful
9696
trait Unscoped extends Stateful, Classifier
9797

9898
@experimental
99-
trait Mutable extends Stateful, Separate//, Unscoped
99+
trait Mutable extends Stateful, Separate, Unscoped
100100

101101
/** Marker trait for classes with reader methods, typically extended by Mutable classes */
102102
@experimental

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@
5858
| Fields capturing a root capability need to be given an explicit type unless the capability is already
5959
| subsumed by the computed capability of the enclosing class.
6060
|
61-
| where: ^ refers to a fresh root capability in the type of value count
61+
| where: ^ refers to a fresh root capability classified as Unscoped in the type of value count

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
| Footprint set of function result : {a}
1414
| The two sets overlap at : {a}
1515
|
16-
|where: ^ refers to a fresh root capability in the type of value a
17-
| ^² refers to a fresh root capability created in method test1 when checking argument to parameter x of method apply
16+
|where: ^ refers to a fresh root capability classified as Unscoped in the type of value a
17+
| ^² refers to a fresh root capability classified as Unscoped created in method test1 when checking argument to parameter x of method apply
1818
-- Error: tests/neg-custom-args/captures/i23726.scala:16:5 -------------------------------------------------------------
1919
16 | f3(b) // error
2020
| ^
@@ -30,8 +30,8 @@
3030
| Footprint set of function result : {op, b}
3131
| The two sets overlap at : {b}
3232
|
33-
|where: ^ refers to a fresh root capability in the type of value b
34-
| ^² refers to a fresh root capability created in method test1 when checking argument to parameter x of method apply
33+
|where: ^ refers to a fresh root capability classified as Unscoped in the type of value b
34+
| ^² refers to a fresh root capability classified as Unscoped created in method test1 when checking argument to parameter x of method apply
3535
-- Error: tests/neg-custom-args/captures/i23726.scala:24:5 -------------------------------------------------------------
3636
24 | f7(a) // error
3737
| ^
@@ -47,5 +47,5 @@
4747
| Footprint set of function prefix : {f7*, a, b}
4848
| The two sets overlap at : {a}
4949
|
50-
|where: ^ refers to a fresh root capability in the type of value a
51-
| ^² refers to a fresh root capability created in method test1 when checking argument to parameter x of method apply
50+
|where: ^ refers to a fresh root capability classified as Unscoped in the type of value a
51+
| ^² refers to a fresh root capability classified as Unscoped created in method test1 when checking argument to parameter x of method apply

tests/neg-custom-args/captures/i24310.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Ref extends Mutable:
55
def get(): Int = value
66
update def set(v: Int): Unit = value = v
77

8-
class Matrix(val f: () => Int) extends Mutable:
8+
class Matrix(val f: () => Int) extends Stateful:
99
self: Matrix^ =>
1010
def run() = f() // error <- note the missing update
1111
update def add(): Unit = ()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
| Fields capturing a root capability need to be given an explicit type unless the capability is already
1515
| subsumed by the computed capability of the enclosing class.
1616
|
17-
| where: ^ refers to a fresh root capability in the type of value r
17+
| where: ^ refers to a fresh root capability classified as Unscoped in the type of value r

tests/neg-custom-args/captures/lazyvals-sep.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
|Note that {cap} is an exclusive capture set of the stateful type Ref^,
3333
|it cannot subsume a read-only capture set of the stateful type Ref^{TestClass.this.r.rd}.
3434
|
35-
|where: ^ and cap refer to a fresh root capability created in lazy value lazyVal8 when checking argument to parameter ref of constructor Wrapper
35+
|where: ^ and cap refer to a fresh root capability classified as Unscoped created in lazy value lazyVal8 when checking argument to parameter ref of constructor Wrapper
3636
|
3737
| longer explanation available when compiling with `-explain`
3838
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyvals-sep.scala:77:12 ---------------------------------
@@ -44,7 +44,7 @@
4444
|Note that {cap} is an exclusive capture set of the stateful type Ref^,
4545
|it cannot subsume a read-only capture set of the stateful type Ref^{TestClass.this.r.rd}.
4646
|
47-
|where: ^ and cap refer to a fresh root capability created in lazy value lazyVal9 when checking argument to parameter ref of constructor Wrapper
47+
|where: ^ and cap refer to a fresh root capability classified as Unscoped created in lazy value lazyVal9 when checking argument to parameter ref of constructor Wrapper
4848
|
4949
| longer explanation available when compiling with `-explain`
5050
-- Error: tests/neg-custom-args/captures/lazyvals-sep.scala:82:8 -------------------------------------------------------

0 commit comments

Comments
 (0)