@@ -7,7 +7,7 @@ import ast.tpd, tpd.*
77import util .Spans .Span
88import printing .{Showable , Printer }
99import printing .Texts .Text
10- import cc .isRetainsLike
10+ import cc .{ isRetainsLike , RetainingAnnotation }
1111import config .Feature
1212import Decorators .*
1313
@@ -130,12 +130,12 @@ object Annotations {
130130 case class ConcreteAnnotation (t : Tree ) extends Annotation :
131131 def tree (using Context ): Tree = t
132132
133- case class CompactAnnotation (tp : Type ) extends Annotation :
134- assert(tp .isInstanceOf [AppliedType | TypeRef ], tp )
133+ class CompactAnnotation (val tpe : Type ) extends Annotation :
134+ assert(tpe .isInstanceOf [AppliedType | TypeRef ], tpe )
135135
136- def tree (using Context ) = TypeTree (tp )
136+ def tree (using Context ) = TypeTree (tpe )
137137
138- override def symbol (using Context ) = tp .typeSymbol
138+ override def symbol (using Context ) = tpe .typeSymbol
139139
140140 override def derivedAnnotation (tree : Tree )(using Context ): Annotation =
141141 derivedAnnotation(tree.tpe)
@@ -144,12 +144,12 @@ object Annotations {
144144 derivedAnnotation(cls.typeRef)
145145
146146 def derivedAnnotation (tp : Type )(using Context ): Annotation =
147- if tp eq this .tp then this else CompactAnnotation (tp)
147+ if tp eq this .tpe then this else CompactAnnotation (tp)
148148
149149 override def arguments (using Context ): List [Tree ] =
150150 argumentTypes.map(TypeTree (_))
151151
152- override def argumentTypes (using Context ): List [Type ] = tp .argTypes
152+ override def argumentTypes (using Context ): List [Type ] = tpe .argTypes
153153
154154 def argumentType (i : Int )(using Context ): Type =
155155 val args = argumentTypes
@@ -160,49 +160,39 @@ object Annotations {
160160 case ConstantType (c) => Some (c)
161161 case _ => None
162162
163- /** Sanitize @retains arguments to approximate illegal types that could cause a compilation
164- * time blowup before they are dropped ot detected. This means mapping all all skolems
165- * (?n: T) to (?n: Any), and mapping all recursive captures that are not on CapSet to `^`.
166- * Skolems and capturing types on types other than CapSet are not allowed in a
167- * @retains annotation anyway, so the underlying type does not matter as long as it is also
168- * illegal. See i24556.scala and i24556a.scala.
163+ /** A hook to transform the type argument of a mapped annotation. Overridden in
164+ * RetainingAnnotation to avoid compilation time blowups for annotations that
165+ * are not valid capture annotations.
169166 */
170- private def sanitize (tp : Type )(using Context ): Type = tp match
171- case SkolemType (_) =>
172- SkolemType (defn.AnyType )
173- case tp @ AnnotatedType (parent, ann)
174- if ann.symbol.isRetainsLike && parent.typeSymbol != defn.Caps_CapSet =>
175- tp.derivedAnnotatedType(parent, ann.derivedClassAnnotation(defn.RetainsCapAnnot ))
176- case tp @ OrType (tp1, tp2) =>
177- tp.derivedOrType(sanitize(tp1), sanitize(tp2))
167+ protected def sanitize (tp : Type )(using Context ): Type = tp
168+
169+ protected def mapWithCtd (tm : TypeMap )(using Context ): Annotation = tm(tpe) match
170+ case tp1 @ AppliedType (tycon, args) =>
171+ derivedAnnotation(tp1.derivedAppliedType(tycon, args.mapConserve(sanitize)))
172+ case tp1 : TypeRef =>
173+ derivedAnnotation(tp1)
178174 case _ =>
179- tp
175+ EmptyAnnotation
180176
181177 override def mapWith (tm : TypeMap )(using Context ): Annotation =
182- val isRetains = symbol.isRetainsLike
183- if isRetains && ! Feature .ccEnabledSomewhere then EmptyAnnotation
184- else tm(tp) match
185- case tp1 @ AppliedType (tycon, args) =>
186- val args1 = if isRetains then args.mapConserve(sanitize) else args
187- derivedAnnotation(tp1.derivedAppliedType(tycon, args1))
188- case tp1 : TypeRef =>
189- derivedAnnotation(tp1)
190- case _ =>
191- EmptyAnnotation
178+ assert(! symbol.isRetainsLike)
179+ mapWithCtd(tm)
192180
193181 override def refersToParamOf (tl : TermLambda )(using Context ): Boolean =
194- refersToLambdaParam(tp , tl)
182+ refersToLambdaParam(tpe , tl)
195183
196- override def hash : Int = tp .hash
184+ override def hash : Int = tpe .hash
197185 override def eql (that : Annotation ) = that match
198- case that : CompactAnnotation => this .tp `eql` that.tp
186+ case that : CompactAnnotation => this .tpe `eql` that.tpe
199187 case _ => false
200188
201189 object CompactAnnotation :
190+ def apply (tp : Type )(using Context ): CompactAnnotation =
191+ if tp.typeSymbol.isRetainsLike then RetainingAnnotation (tp)
192+ else new CompactAnnotation (tp)
202193 def apply (tree : Tree )(using Context ): CompactAnnotation =
203194 val argTypes = tpd.allArguments(tree).map(_.tpe)
204195 apply(annotClass(tree).typeRef.appliedTo(argTypes))
205-
206196 end CompactAnnotation
207197
208198 private def isLambdaParam (t : Type , tl : TermLambda ): Boolean = t match
@@ -314,7 +304,7 @@ object Annotations {
314304
315305 def apply (atp : Type , args : List [Tree ], span : Span )(using Context ): Annotation =
316306 if atp.typeSymbol.isRetainsLike && args.isEmpty
317- then CompactAnnotation (atp)
307+ then RetainingAnnotation (atp)
318308 else apply(New (atp, args).withSpan(span))
319309
320310 /** Create an annotation where the tree is computed lazily. */
0 commit comments