Skip to content

Commit 4618169

Browse files
committed
Fixes to classification scheme
- fix tryClassify and trsnaClassifiers for core capabilities - freeze classifications of FreshCaps in constant sets
1 parent ff2edf6 commit 4618169

File tree

5 files changed

+21
-10
lines changed

5 files changed

+21
-10
lines changed

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ object Capabilities:
152152
val hiddenSet = CaptureSet.HiddenSet(owner, this: @unchecked)
153153
// fails initialization check without the @unchecked
154154

155+
private[Capabilities] var isClassified = false
156+
155157
override def equals(that: Any) = that match
156158
case that: FreshCap => this eq that
157159
case _ => false
@@ -164,6 +166,11 @@ object Capabilities:
164166
case ResultCap(_) | _: ParamRef => false
165167
case _ => true
166168

169+
def adoptClassifier(cls: ClassSymbol, freeze: Boolean)(using Context): Unit =
170+
if !isClassified then
171+
hiddenSet.adoptClassifier(cls)
172+
if freeze then isClassified = true
173+
167174
def descr(using Context) =
168175
val originStr = origin match
169176
case Origin.InDecl(sym) if sym.exists =>
@@ -536,7 +543,8 @@ object Capabilities:
536543
case Reach(_) =>
537544
captureSetOfInfo.transClassifiers
538545
case self: CoreCapability =>
539-
joinClassifiers(toClassifiers(self.classifier), captureSetOfInfo.transClassifiers)
546+
if self.derivesFromCapability then toClassifiers(self.classifier)
547+
else captureSetOfInfo.transClassifiers
540548
if myClassifiers != UnknownClassifier then
541549
classifiersValid == currentId
542550
myClassifiers
@@ -546,7 +554,8 @@ object Capabilities:
546554
cls == defn.AnyClass
547555
|| this.match
548556
case self: FreshCap =>
549-
self.hiddenSet.tryClassifyAs(cls)
557+
if self.isClassified then self.hiddenSet.classifier.derivesFrom(cls)
558+
else self.hiddenSet.tryClassifyAs(cls)
550559
case self: RootCapability =>
551560
true
552561
case Restricted(_, cls1) =>
@@ -559,8 +568,8 @@ object Capabilities:
559568
case Reach(_) =>
560569
captureSetOfInfo.tryClassifyAs(cls)
561570
case self: CoreCapability =>
562-
self.classifier.isSubClass(cls)
563-
&& captureSetOfInfo.tryClassifyAs(cls)
571+
if self.derivesFromCapability then self.derivesFrom(cls)
572+
else captureSetOfInfo.tryClassifyAs(cls)
564573

565574
def isKnownClassifiedAs(cls: ClassSymbol)(using Context): Boolean =
566575
transClassifiers match

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ extension (tp: Type)
470470

471471
def classifier(using Context): ClassSymbol =
472472
tp.classSymbols.map(_.classifier).foldLeft(defn.AnyClass)(leastClassifier)
473+
473474
extension (tp: MethodType)
474475
/** A method marks an existential scope unless it is the prefix of a curried method */
475476
def marksExistentialScope(using Context): Boolean =
@@ -654,7 +655,9 @@ object OnlyCapability:
654655

655656
def unapply(tree: AnnotatedType)(using Context): Option[(Type, ClassSymbol)] = tree match
656657
case AnnotatedType(parent: Type, ann) if ann.hasSymbol(defn.OnlyCapabilityAnnot) =>
657-
Some((parent, ann.tree.tpe.argTypes.head.classSymbol.asClass))
658+
ann.tree.tpe.argTypes.head.classSymbol match
659+
case cls: ClassSymbol => Some((parent, cls))
660+
case _ => None
658661
case _ => None
659662
end OnlyCapability
660663

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ sealed abstract class CaptureSet extends Showable:
274274
elems.exists(_.subsumes(x)(using ctx)(using VarState.ClosedUnrecorded))
275275
|| !x.isTerminalCapability
276276
&& {
277-
val elems = x.captureSetOfInfo.elems
278-
!elems.isEmpty && elems.forall(mightAccountFor)
277+
val xelems = x.captureSetOfInfo.elems
278+
!xelems.isEmpty && xelems.forall(mightAccountFor)
279279
}
280280

281281
/** A more optimistic version of subCaptures used to choose one of two typing rules
@@ -442,7 +442,7 @@ sealed abstract class CaptureSet extends Showable:
442442
def adoptClassifier(cls: ClassSymbol)(using Context): Unit =
443443
for elem <- elems do
444444
elem.stripReadOnly match
445-
case fresh: FreshCap => fresh.hiddenSet.adoptClassifier(cls)
445+
case fresh: FreshCap => fresh.adoptClassifier(cls, freeze = isConst)
446446
case _ =>
447447

448448
/** All capabilities of this set except those Termrefs and FreshCaps that
@@ -761,6 +761,7 @@ object CaptureSet:
761761
else if !levelOK(elem) then
762762
failWith(IncludeFailure(this, elem, levelError = true)) // or `elem` is not visible at the level of the set.
763763
else if !elem.tryClassifyAs(classifier) then
764+
//println(i"cannot classify $elem as $classifier, ${elem.asInstanceOf[CoreCapability].classifier}")
764765
failWith(IncludeFailure(this, elem))
765766
else
766767
// id == 108 then assert(false, i"trying to add $elem to $this")

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ object CapturingType:
4040
apply(parent1, refs ++ refs1, boxed)
4141
case _ =>
4242
if parent.derivesFromMutable then refs.setMutable()
43-
val classifier = parent.classifier
4443
refs.adoptClassifier(parent.classifier)
4544
AnnotatedType(parent, CaptureAnnotation(refs, boxed)(defn.RetainsAnnot))
4645

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,6 @@ class CheckCaptures extends Recheck, SymTransformer:
700700
capt.println(i"pick one of $qualType, ${selType.widen}, $qualCs, $selCs ${selWiden.captureSet} in $tree")
701701

702702
if qualCs.mightSubcapture(selCs)
703-
//&& !selCs.mightSubcapture(qualCs)
704703
&& !pt.stripCapturing.isInstanceOf[SingletonType]
705704
then
706705
selWiden.stripCapturing.capturing(qualCs)

0 commit comments

Comments
 (0)