Skip to content

Commit 238c8af

Browse files
committed
Store definition capture set information in class denotation
1 parent 56dac81 commit 238c8af

File tree

4 files changed

+17
-18
lines changed

4 files changed

+17
-18
lines changed

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,6 @@ extension (tp: Type)
207207
case _: TypeRef | _: AppliedType => tp.typeSymbol.hasAnnotation(defn.CapabilityAnnot)
208208
case _ => false
209209

210-
/** Check if the class has universal capability, which means:
211-
* 1. the class has a capability annotation,
212-
* 2. the class is an impure function type,
213-
* 3. or one of its base classes has universal capability.
214-
*/
215-
def hasUniversalCapability(using Context): Boolean = tp match
216-
case CapturingType(parent, ref) =>
217-
ref.isUniversal || parent.hasUniversalCapability
218-
case tp =>
219-
tp.isCapabilityClassRef || tp.parents.exists(_.hasUniversalCapability)
220-
221210
/** Drop @retains annotations everywhere */
222211
def dropAllRetains(using Context): Type = // TODO we should drop retains from inferred types before unpickling
223212
val tm = new TypeMap:

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,7 @@ class CheckCaptures extends Recheck, SymTransformer:
528528
*/
529529
def addParamArgRefinements(core: Type, initCs: CaptureSet): (Type, CaptureSet) =
530530
var refined: Type = core
531-
var allCaptures: CaptureSet = if core.hasUniversalCapability
532-
then CaptureSet.universal else initCs
531+
var allCaptures: CaptureSet = core.classSymbol.denot.asClass.definitionCaptureSet ++ initCs
533532
for (getterName, argType) <- mt.paramNames.lazyZip(argTypes) do
534533
val getter = cls.info.member(getterName).suchThat(_.is(ParamAccessor)).symbol
535534
if getter.termRef.isTracked && !getter.is(Private) then

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,11 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
290290
if t1 ne t.ref then t1 else t
291291
case t: TypeVar =>
292292
this(t.underlying)
293-
case t =>
293+
case t: TypeRef =>
294294
// Map references to capability classes C to C^
295-
if t.hasUniversalCapability
296-
then CapturingType(t, defn.expandedUniversalSet, boxed = false)
297-
else recur(t)
295+
CapturingType(t, t.classSymbol.denot.asClass.definitionCaptureSet, boxed = false)
296+
case t =>
297+
recur(t)
298298
end expandAliases
299299

300300
val tp1 = expandAliases(tp) // TODO: Do we still need to follow aliases?

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import scala.util.control.NonFatal
2323
import config.Config
2424
import reporting.*
2525
import collection.mutable
26-
import cc.{CapturingType, derivedCapturingType, stripCapturing}
26+
import cc.{CaptureSet, CapturingType, derivedCapturingType, stripCapturing}
2727

2828
import scala.annotation.internal.sharable
2929
import scala.compiletime.uninitialized
@@ -1820,6 +1820,8 @@ object SymDenotations {
18201820
private var baseDataCache: BaseData = BaseData.None
18211821
private var memberNamesCache: MemberNames = MemberNames.None
18221822

1823+
private var myDefinitionCaptureSet: CaptureSet | Null = null
1824+
18231825
private def memberCache(using Context): EqHashMap[Name, PreDenotation] = {
18241826
if (myMemberCachePeriod != ctx.period) {
18251827
myMemberCache = EqHashMap()
@@ -2029,6 +2031,15 @@ object SymDenotations {
20292031
&& (base ne defn.NothingClass)
20302032
)
20312033

2034+
final def definitionCaptureSet(using Context): CaptureSet =
2035+
if myDefinitionCaptureSet == null then
2036+
myDefinitionCaptureSet = if symbol.hasAnnotation(defn.CapabilityAnnot)
2037+
then CaptureSet.universal
2038+
else parentTypes.foldLeft[CaptureSet](CaptureSet.empty) { (set, parent) =>
2039+
set ++ parent.captureSet ++ parent.classSymbol.denot.asClass.definitionCaptureSet
2040+
}
2041+
myDefinitionCaptureSet.nn
2042+
20322043
/** Is it possible that a class inherits both `this` and `that`?
20332044
*
20342045
* @note The test is based on single-class inheritance and the closed

0 commit comments

Comments
 (0)