@@ -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
2222
@@ -132,17 +132,39 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
132132 case _ =>
133133 case _ =>
134134
135+ /** Returns a copy of the given tree with all symbols fresh.
136+ *
137+ * Used to guarantee that no symbols are shared between trees in different
138+ * annotations.
139+ */
140+ private def copySymbols (tree : Tree )(using Context ) =
141+ Stats .trackTime(" Annotations copySymbols" ):
142+ val ttm =
143+ new TreeTypeMap :
144+ override def withMappedSyms (syms : List [Symbol ]) =
145+ withMappedSyms(syms, mapSymbols(syms, this , true ))
146+ ttm(tree)
147+
148+ /** Transforms the given annotation tree. */
135149 private def transformAnnot (annot : Tree )(using Context ): Tree = {
136150 val saved = inJavaAnnot
137151 inJavaAnnot = annot.symbol.is(JavaDefined )
138152 if (inJavaAnnot) checkValidJavaAnnotation(annot)
139- try transform(annot)
153+ try transform(copySymbols( annot) )
140154 finally inJavaAnnot = saved
141155 }
142156
143157 private def transformAnnot (annot : Annotation )(using Context ): Annotation =
144158 annot.derivedAnnotation(transformAnnot(annot.tree))
145159
160+ /** Transforms all annotations in the given type. */
161+ private def transformAnnots (using Context ) =
162+ new TypeMap :
163+ def apply (tp : Type ) = tp match
164+ case tp @ AnnotatedType (parent, annot) =>
165+ tp.derivedAnnotatedType(mapOver(parent), transformAnnot(annot))
166+ case _ => mapOver(tp)
167+
146168 private def processMemberDef (tree : Tree )(using Context ): tree.type = {
147169 val sym = tree.symbol
148170 Checking .checkValidOperator(sym)
@@ -460,12 +482,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
460482 report.error(em " type ${alias.tpe} outside bounds $bounds" , tree.srcPos)
461483 super .transform(tree)
462484 case tree : TypeTree =>
463- tree.withType(
464- tree.tpe match {
465- case AnnotatedType (tpe, annot) => AnnotatedType (tpe, transformAnnot(annot))
466- case tpe => tpe
467- }
468- )
485+ tree.withType(transformAnnotsIn(tpe))
469486 case Typed (Ident (nme.WILDCARD ), _) =>
470487 withMode(Mode .Pattern )(super .transform(tree))
471488 // The added mode signals that bounds in a pattern need not
0 commit comments