Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/cc/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,12 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
else if cls.isPureClass then
// is cls is known to be pure, nothing needs to be added to self type
selfInfo
else if cls.derivesFrom(defn.Caps_Capability) then
// If cls is a capability class, we need to add a fresh capability to
// ensure we cannot treat itself as pure.
CapturingType(cinfo.selfType,
CaptureSet.fresh(Origin.InDecl(cls)).readOnly
++ CaptureSet.Var(cls, level = ccState.currentLevel))
else if !cls.isEffectivelySealed && !cls.baseClassHasExplicitNonUniversalSelfType then
// assume {cap} for completely unconstrained self types of publicly extensible classes
CapturingType(cinfo.selfType, CaptureSet.universal)
Expand Down
12 changes: 12 additions & 0 deletions tests/neg-custom-args/captures/i23223.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import language.experimental.captureChecking
import caps.*

class A:
def a: A = this

class B extends A, Capability // error

def leak(b: B): A = b.a

class C extends Capability:
def c: C^{} = this // error
4 changes: 4 additions & 0 deletions tests/pos-custom-args/captures/i20237.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import language.experimental.captureChecking
import caps.*

class Cap extends caps.Capability:
def use[T](body: Cap ?=> T) = body(using this)

class Cap2 extends caps.Capability:
def use[T](body: Cap2 => T) = body(this)

class Box[T](body: Cap ?=> T):
inline def open(using cap: Cap) = cap.use(body)

Expand Down
Loading