Skip to content

Commit e648b42

Browse files
committed
Cache result of toCaptureSet in RetainingAnnotation
1 parent b9e6eb9 commit e648b42

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

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

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,38 @@ import config.Feature
1010
/** A class for annotations @retains, @retainsByName and @retainsCap */
1111
class RetainingAnnotation(tpe: Type) extends CompactAnnotation(tpe):
1212

13-
/** Sanitize @retains arguments to approximate illegal types that could cause a compilation
14-
* time blowup before they are dropped ot detected. This means mapping all all skolems
15-
* (?n: T) to (?n: Any), and mapping all recursive captures that are not on CapSet to `^`.
16-
* Skolems and capturing types on types other than CapSet are not allowed in a
17-
* @retains annotation anyway, so the underlying type does not matter as long as it is also
18-
* illegal. See i24556.scala and i24556a.scala.
19-
*/
20-
override protected def sanitize(tp: Type)(using Context): Type = tp match
21-
case SkolemType(_) =>
22-
SkolemType(defn.AnyType)
23-
case tp @ AnnotatedType(parent, ann)
24-
if ann.symbol.isRetainsLike && parent.typeSymbol != defn.Caps_CapSet =>
25-
tp.derivedAnnotatedType(parent, ann.derivedClassAnnotation(defn.RetainsCapAnnot))
26-
case tp @ OrType(tp1, tp2) =>
27-
tp.derivedOrType(sanitize(tp1), sanitize(tp2))
28-
case _ =>
29-
tp
30-
31-
override def mapWith(tm: TypeMap)(using Context): Annotation =
32-
if Feature.ccEnabledSomewhere then mapWithCtd(tm) else EmptyAnnotation
33-
34-
def isStrict(using Context): Boolean = symbol.isRetains
35-
36-
def retainedType(using Context): Type =
37-
if symbol == defn.RetainsCapAnnot then defn.captureRoot.termRef
38-
else argumentType(0)
39-
40-
def toCaptureSet(using Context): CaptureSet =
41-
CaptureSet(retainedType.retainedElements*)
13+
/** Sanitize @retains arguments to approximate illegal types that could cause a compilation
14+
* time blowup before they are dropped ot detected. This means mapping all all skolems
15+
* (?n: T) to (?n: Any), and mapping all recursive captures that are not on CapSet to `^`.
16+
* Skolems and capturing types on types other than CapSet are not allowed in a
17+
* @retains annotation anyway, so the underlying type does not matter as long as it is also
18+
* illegal. See i24556.scala and i24556a.scala.
19+
*/
20+
override protected def sanitize(tp: Type)(using Context): Type = tp match
21+
case SkolemType(_) =>
22+
SkolemType(defn.AnyType)
23+
case tp @ AnnotatedType(parent, ann)
24+
if ann.symbol.isRetainsLike && parent.typeSymbol != defn.Caps_CapSet =>
25+
tp.derivedAnnotatedType(parent, ann.derivedClassAnnotation(defn.RetainsCapAnnot))
26+
case tp @ OrType(tp1, tp2) =>
27+
tp.derivedOrType(sanitize(tp1), sanitize(tp2))
28+
case _ =>
29+
tp
30+
31+
override def mapWith(tm: TypeMap)(using Context): Annotation =
32+
if Feature.ccEnabledSomewhere then mapWithCtd(tm) else EmptyAnnotation
33+
34+
def isStrict(using Context): Boolean = symbol.isRetains
35+
36+
def retainedType(using Context): Type =
37+
if symbol == defn.RetainsCapAnnot then defn.captureRoot.termRef
38+
else argumentType(0)
39+
40+
private var myCaptureSet: CaptureSet | Null = null
41+
42+
def toCaptureSet(using Context): CaptureSet =
43+
if myCaptureSet == null then
44+
myCaptureSet = CaptureSet(retainedType.retainedElements*)
45+
myCaptureSet.nn
4246

4347
end RetainingAnnotation

0 commit comments

Comments
 (0)