Skip to content

Commit a3dde8b

Browse files
authored
Exclusive capabilities (#22218)
implement capybara-like mutation checking - [x] Add read-only capabilities `x.rd` - [x] Add `Mutable` and `SharedCapability` as subclasses of `Capability`. - [x] Add update methods. - [x] Implement access rules for `Mutable` types - exclusive if they can invoke an update method, read-only otherwise. - [x] Add `Fresh.Cap` as a family of new top-types that keep track of references that were widened to them - [x] Add a separation checker that checks that references hidden by a `Fresh.Cap` don't appear as aliases - [x] In applications - [x] In sequences of statements and definitions - [x] in the same type - [x] Introduce @consume annotation for parameters - [x] Check that hidden references that are parameters are annotated with `@consume` - [x] Check that parameter references passed in arguments to @consume parameters are also annotated with `@consume`. To be done in a separate PR: Add qualifiers to capture sets so that we can talk of the read-only part of a `Mutable` type.
2 parents aa9db1f + a41c10f commit a3dde8b

File tree

156 files changed

+4075
-744
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+4075
-744
lines changed

compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I, val frontendAcce
285285
// tests/run/serialize.scala and https://github.com/typelevel/cats-effect/pull/2360).
286286
val privateFlag = !sym.isClass && (sym.is(Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass))
287287

288-
val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !sym.is(Mutable, butNot = Accessor) && !sym.enclosingClass.is(Trait)
288+
val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !sym.isMutableVar && !sym.enclosingClass.is(Trait)
289289

290290
import asm.Opcodes.*
291291
import GenBCodeOps.addFlagIf

compiler/src/dotty/tools/dotc/ast/Desugar.scala

+2
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,8 @@ object desugar {
22432243
New(ref(defn.RepeatedAnnot.typeRef), Nil :: Nil))
22442244
else if op.name == nme.CC_REACH then
22452245
Apply(ref(defn.Caps_reachCapability), t :: Nil)
2246+
else if op.name == nme.CC_READONLY then
2247+
Apply(ref(defn.Caps_readOnlyCapability), t :: Nil)
22462248
else
22472249
assert(ctx.mode.isExpr || ctx.reporter.errorsReported || ctx.mode.is(Mode.Interactive), ctx.mode)
22482250
Select(t, op.name)

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
755755
*/
756756
def isVariableOrGetter(tree: Tree)(using Context): Boolean = {
757757
def sym = tree.symbol
758-
def isVar = sym.is(Mutable)
758+
def isVar = sym.isMutableVarOrAccessor
759759
def isGetter =
760760
mayBeVarGetter(sym) && sym.owner.info.member(sym.name.asTermName.setterName).exists
761761

compiler/src/dotty/tools/dotc/ast/untpd.scala

+3
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
206206

207207
case class Var()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Mutable)
208208

209+
case class Mut()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Mutable)
210+
209211
case class Implicit()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Implicit)
210212

211213
case class Given()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Given)
@@ -332,6 +334,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
332334

333335
def isEnumCase: Boolean = isEnum && is(Case)
334336
def isEnumClass: Boolean = isEnum && !is(Case)
337+
def isMutableVar: Boolean = is(Mutable) && mods.exists(_.isInstanceOf[Mod.Var])
335338
}
336339

337340
@sharable val EmptyModifiers: Modifiers = Modifiers()

0 commit comments

Comments
 (0)