@@ -2,7 +2,7 @@ package dotty.tools
22package dotc
33package transform
44
5- import dotty .tools .dotc .ast .{Trees , tpd , untpd , desugar }
5+ import dotty .tools .dotc .ast .{Trees , tpd , untpd , desugar , TreeTypeMap }
66import scala .collection .mutable
77import core .*
88import dotty .tools .dotc .typer .Checking
@@ -16,7 +16,7 @@ import Symbols.*, NameOps.*
1616import ContextFunctionResults .annotateContextResults
1717import config .Printers .typr
1818import config .Feature
19- import util .SrcPos
19+ import util .{ SrcPos , Stats }
2020import reporting .*
2121import NameKinds .WildcardParamName
2222import cc .*
@@ -154,17 +154,39 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
154154 case _ =>
155155 case _ =>
156156
157+ /** Returns a copy of the given tree with all symbols fresh.
158+ *
159+ * Used to guarantee that no symbols are shared between trees in different
160+ * annotations.
161+ */
162+ private def copySymbols (tree : Tree )(using Context ) =
163+ Stats .trackTime(" Annotations copySymbols" ):
164+ val ttm =
165+ new TreeTypeMap :
166+ override def withMappedSyms (syms : List [Symbol ]) =
167+ withMappedSyms(syms, mapSymbols(syms, this , true ))
168+ ttm(tree)
169+
170+ /** Transforms the given annotation tree. */
157171 private def transformAnnot (annot : Tree )(using Context ): Tree = {
158172 val saved = inJavaAnnot
159173 inJavaAnnot = annot.symbol.is(JavaDefined )
160174 if (inJavaAnnot) checkValidJavaAnnotation(annot)
161- try transform(annot)
175+ try transform(copySymbols( annot) )
162176 finally inJavaAnnot = saved
163177 }
164178
165179 private def transformAnnot (annot : Annotation )(using Context ): Annotation =
166180 annot.derivedAnnotation(transformAnnot(annot.tree))
167181
182+ /** Transforms all annotations in the given type. */
183+ private def transformAnnots (using Context ) =
184+ new TypeMap :
185+ def apply (tp : Type ) = tp match
186+ case tp @ AnnotatedType (parent, annot) =>
187+ tp.derivedAnnotatedType(mapOver(parent), transformAnnot(annot))
188+ case _ => mapOver(tp)
189+
168190 private def processMemberDef (tree : Tree )(using Context ): tree.type = {
169191 val sym = tree.symbol
170192 Checking .checkValidOperator(sym)
@@ -524,11 +546,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
524546 super .transform(tree)
525547 case tree : TypeTree =>
526548 val tpe = if tree.isInferred then CleanupRetains ()(tree.tpe) else tree.tpe
527- tree.withType:
528- tpe match
529- case AnnotatedType (parent, annot) =>
530- AnnotatedType (parent, transformAnnot(annot)) // TODO: Also map annotations embedded in type?
531- case _ => tpe
549+ tree.withType(transformAnnots(tpe))
532550 case Typed (Ident (nme.WILDCARD ), _) =>
533551 withMode(Mode .Pattern )(super .transform(tree))
534552 // The added mode signals that bounds in a pattern need not
0 commit comments