diff --git a/compiler/src/dotty/tools/dotc/cc/Setup.scala b/compiler/src/dotty/tools/dotc/cc/Setup.scala index c9b4546c8c37..69bfa96df836 100644 --- a/compiler/src/dotty/tools/dotc/cc/Setup.scala +++ b/compiler/src/dotty/tools/dotc/cc/Setup.scala @@ -735,7 +735,12 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI: // Infer the self type for the rest, which is all classes without explicit // self types (to which we also add nested module classes), provided they are // neither pure, nor are publicily extensible with an unconstrained self type. - CapturingType(cinfo.selfType, CaptureSet.Var(cls, level = ccState.currentLevel)) + val cs = CaptureSet.Var(cls, level = ccState.currentLevel) + if cls.derivesFrom(defn.Caps_Capability) then + // If cls is a capability class, we need to add a fresh readonly capability to + // ensure we cannot treat the class as pure. + CaptureSet.fresh(Origin.InDecl(cls)).readOnly.subCaptures(cs) + CapturingType(cinfo.selfType, cs) // Compute new parent types val ps1 = inContext(ctx.withOwner(cls)): diff --git a/tests/neg-custom-args/captures/i23223.scala b/tests/neg-custom-args/captures/i23223.scala new file mode 100644 index 000000000000..e606875b840a --- /dev/null +++ b/tests/neg-custom-args/captures/i23223.scala @@ -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 diff --git a/tests/pos-custom-args/captures/i20237.scala b/tests/pos-custom-args/captures/i20237.scala index 973f5d2025e3..53efbb2e7583 100644 --- a/tests/pos-custom-args/captures/i20237.scala +++ b/tests/pos-custom-args/captures/i20237.scala @@ -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)