@@ -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