Skip to content

Commit 3371325

Browse files
committed
Disallow inheriting both SharedCapability and Mutable
1 parent 3674c7f commit 3371325

File tree

5 files changed

+21
-3
lines changed

5 files changed

+21
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ object Capabilities:
438438
*/
439439
final def isExclusive(using Context): Boolean =
440440
!isReadOnly
441-
&& !classifier.isSubClass(defn.Caps_SharedCapability)
441+
&& !classifier.derivesFrom(defn.Caps_SharedCapability)
442442
&& (isTerminalCapability || captureSetOfInfo.isExclusive)
443443

444444
/** Similar to isExlusive, but also includes capabilties with capture

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ class CheckCaptures extends Recheck, SymTransformer:
702702
* type `pt` to `ref`. Expand the marked tree accordingly to take account of
703703
* the added path. Example:
704704
* If we have `x` and the expected type says we select that with `.a.b`
705-
* where `b` is a read-only method, we charge `x.a.b.rd` for tree `x.a.b`
705+
* where `b` is a read-only method, we charge `x.a.rd` for tree `x.a.b`
706706
* instead of just charging `x`.
707707
*/
708708
private def markPathFree(ref: TermRef | ThisType, pt: Type, tree: Tree)(using Context): Unit = pt match

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,10 +952,12 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
952952
case c :: cs1 =>
953953
for c1 <- cs1 do
954954
if !c.derivesFrom(c1) && !c1.derivesFrom(c) then
955-
report.error(i"$cls inherits two unrelated classifier traits: $c and $c1", cls.srcPos)
955+
report.error(em"$cls inherits two unrelated classifier traits: $c and $c1", cls.srcPos)
956956
recur(cs1)
957957
case Nil =>
958958
recur(cls.baseClasses.filter(_.isClassifiedCapabilityClass).distinct)
959+
if cls.derivesFrom(defn.Caps_SharedCapability) && cls.derivesFrom(defn.Caps_Mutable) then
960+
report.error(em"$cls cannot inheit from both SharaedCapability and Mutable", cls.srcPos)
959961

960962
// ------ Checks to run after main capture checking --------------------------
961963

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Error: tests/neg-custom-args/captures/classified-inheritance2.scala:4:6 ---------------------------------------------
2+
4 |class Logger extends SharedCapability, Mutable: // error (1) does this make sense?
3+
| ^
4+
| class Logger cannot inheit from both SharaedCapability and Mutable
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import language.experimental.captureChecking
2+
import language.experimental.separationChecking
3+
import caps.*
4+
class Logger extends SharedCapability, Mutable: // error (1) does this make sense?
5+
private var _state: Int = 0
6+
update def log(msg: String): Unit = ()
7+
8+
def onlyShared(x: Object^{cap.only[SharedCapability]}): Unit = ()
9+
10+
def main(): Unit =
11+
onlyShared(Logger()) // even if we allow (1), why would this type check?
12+
val t: Logger^{} = Logger() // and this type checks too, thus the above line I guess

0 commit comments

Comments
 (0)