Skip to content

Commit

Permalink
Store definition capture set information in class denotation
Browse files Browse the repository at this point in the history
  • Loading branch information
noti0na1 committed Apr 12, 2024
1 parent 56dac81 commit 238c8af
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 18 deletions.
11 changes: 0 additions & 11 deletions compiler/src/dotty/tools/dotc/cc/CaptureOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,6 @@ extension (tp: Type)
case _: TypeRef | _: AppliedType => tp.typeSymbol.hasAnnotation(defn.CapabilityAnnot)
case _ => false

/** Check if the class has universal capability, which means:
* 1. the class has a capability annotation,
* 2. the class is an impure function type,
* 3. or one of its base classes has universal capability.
*/
def hasUniversalCapability(using Context): Boolean = tp match
case CapturingType(parent, ref) =>
ref.isUniversal || parent.hasUniversalCapability
case tp =>
tp.isCapabilityClassRef || tp.parents.exists(_.hasUniversalCapability)

/** Drop @retains annotations everywhere */
def dropAllRetains(using Context): Type = // TODO we should drop retains from inferred types before unpickling
val tm = new TypeMap:
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,7 @@ class CheckCaptures extends Recheck, SymTransformer:
*/
def addParamArgRefinements(core: Type, initCs: CaptureSet): (Type, CaptureSet) =
var refined: Type = core
var allCaptures: CaptureSet = if core.hasUniversalCapability
then CaptureSet.universal else initCs
var allCaptures: CaptureSet = core.classSymbol.denot.asClass.definitionCaptureSet ++ initCs
for (getterName, argType) <- mt.paramNames.lazyZip(argTypes) do
val getter = cls.info.member(getterName).suchThat(_.is(ParamAccessor)).symbol
if getter.termRef.isTracked && !getter.is(Private) then
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/cc/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,11 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
if t1 ne t.ref then t1 else t
case t: TypeVar =>
this(t.underlying)
case t =>
case t: TypeRef =>
// Map references to capability classes C to C^
if t.hasUniversalCapability
then CapturingType(t, defn.expandedUniversalSet, boxed = false)
else recur(t)
CapturingType(t, t.classSymbol.denot.asClass.definitionCaptureSet, boxed = false)
case t =>
recur(t)
end expandAliases

val tp1 = expandAliases(tp) // TODO: Do we still need to follow aliases?
Expand Down
13 changes: 12 additions & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import scala.util.control.NonFatal
import config.Config
import reporting.*
import collection.mutable
import cc.{CapturingType, derivedCapturingType, stripCapturing}
import cc.{CaptureSet, CapturingType, derivedCapturingType, stripCapturing}

import scala.annotation.internal.sharable
import scala.compiletime.uninitialized
Expand Down Expand Up @@ -1820,6 +1820,8 @@ object SymDenotations {
private var baseDataCache: BaseData = BaseData.None
private var memberNamesCache: MemberNames = MemberNames.None

private var myDefinitionCaptureSet: CaptureSet | Null = null

private def memberCache(using Context): EqHashMap[Name, PreDenotation] = {
if (myMemberCachePeriod != ctx.period) {
myMemberCache = EqHashMap()
Expand Down Expand Up @@ -2029,6 +2031,15 @@ object SymDenotations {
&& (base ne defn.NothingClass)
)

final def definitionCaptureSet(using Context): CaptureSet =
if myDefinitionCaptureSet == null then
myDefinitionCaptureSet = if symbol.hasAnnotation(defn.CapabilityAnnot)
then CaptureSet.universal
else parentTypes.foldLeft[CaptureSet](CaptureSet.empty) { (set, parent) =>
set ++ parent.captureSet ++ parent.classSymbol.denot.asClass.definitionCaptureSet
}
myDefinitionCaptureSet.nn

/** Is it possible that a class inherits both `this` and `that`?
*
* @note The test is based on single-class inheritance and the closed
Expand Down

0 comments on commit 238c8af

Please sign in to comment.