Skip to content
Prev Previous commit
Next Next commit
Comments and general polishing
  • Loading branch information
odersky committed Dec 9, 2025
commit 3e8c9cf26dd929c3487a1ef67f27d9002fda62c2
20 changes: 10 additions & 10 deletions compiler/src/dotty/tools/dotc/cc/CaptureOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,14 @@ def ccState(using Context): CCState =
extension (tree: Tree)

/** The type representing the capture set of @retains, @retainsCap or @retainsByName
* annotation tree.
* annotation tree (represented as an Apply node).
*/
def retainedSet(using Context): Type =
val rcap = defn.RetainsCapAnnot
if tree.symbol == rcap || tree.symbol.maybeOwner == rcap then
defn.captureRoot.termRef
else tree match
case Apply(TypeApply(_, refs :: Nil), _) => refs.tpe
case _ => NoType
def retainedSet(using Context): Type = tree match
case Apply(TypeApply(_, refs :: Nil), _) => refs.tpe
case _ =>
if tree.symbol.maybeOwner == defn.RetainsCapAnnot
then defn.captureRoot.termRef
else NoType

extension (tp: Type)

Expand All @@ -85,7 +84,7 @@ extension (tp: Type)
def retainedElementsRaw(using Context): List[Type] = tp match
case OrType(tp1, tp2) =>
tp1.retainedElementsRaw ++ tp2.retainedElementsRaw
case AnnotatedType(tp1, ann: RetainingAnnotation) if tp1.derivesFrom(defn.Caps_CapSet) && ann.isStrict =>
case AnnotatedType(tp1, ann: RetainingAnnotation) if tp1.derivesFrom(defn.Caps_CapSet) =>
ann.retainedType.retainedElementsRaw
case tp =>
tp.dealiasKeepAnnots match
Expand Down Expand Up @@ -229,7 +228,8 @@ extension (tp: Type)
if tp.isBoxed || parent.derivesFrom(defn.Caps_CapSet) then tp
else tp.boxed
case tp @ AnnotatedType(parent, ann: RetainingAnnotation)
if ann.isStrict && !parent.derivesFrom(defn.Caps_CapSet) =>
if !parent.derivesFrom(defn.Caps_CapSet) =>
assert(ann.isStrict)
CapturingType(parent, ann.toCaptureSet, boxed = true)
case tp @ AnnotatedType(parent, ann) =>
tp.derivedAnnotatedType(parent.boxDeeply, ann)
Expand Down
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/cc/CaptureSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1672,10 +1672,8 @@ object CaptureSet:
case tp: (TypeRef | TypeParamRef) =>
if tp.derivesFrom(defn.Caps_CapSet) then tp.captureSet
else empty
case CapturingType(parent, refs) =>
case CapturingOrRetainsType(parent, refs) =>
recur(parent) ++ refs
case tp @ AnnotatedType(parent, ann: RetainingAnnotation) if ann.isStrict =>
recur(parent) ++ ann.toCaptureSet
case tpd @ defn.RefinedFunctionOf(rinfo: MethodOrPoly) if followResult =>
ofType(tpd.parent, followResult = false) // pick up capture set from parent type
++ recur(rinfo.resType).freeInResult(rinfo) // add capture set of result
Expand Down
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@ object Annotations {
case class ConcreteAnnotation(t: Tree) extends Annotation:
def tree(using Context): Tree = t

/** A class for optimized, compact annotations that are defined by a type
* instead of a tree. This makes mapping such annotations a lot faster and safer.
* In fact, in retrospect, most annotations would better be represented as
* CompactAnnotations.
*
* CompactAnnotation is extended by cc.RetainingAnnotation, which is reserved
* for @retains, @retainsByName and @retainsCap. For now there are no
* CompactAnnotations other than RetainingAnnotations but this could be changed
* in the future, after 3.9 has shipped.
*/
class CompactAnnotation(val tpe: Type) extends Annotation:
assert(tpe.isInstanceOf[AppliedType | TypeRef], tpe)

Expand Down
Loading