@@ -2,7 +2,7 @@ package dotty.tools
2
2
package dotc
3
3
package transform
4
4
5
- import dotty .tools .dotc .ast .{Trees , tpd , untpd , desugar }
5
+ import dotty .tools .dotc .ast .{Trees , tpd , untpd , desugar , TreeTypeMap }
6
6
import scala .collection .mutable
7
7
import core .*
8
8
import dotty .tools .dotc .typer .Checking
@@ -16,7 +16,7 @@ import Symbols.*, NameOps.*
16
16
import ContextFunctionResults .annotateContextResults
17
17
import config .Printers .typr
18
18
import config .Feature
19
- import util .SrcPos
19
+ import util .{ SrcPos , Stats }
20
20
import reporting .*
21
21
import NameKinds .WildcardParamName
22
22
@@ -132,17 +132,39 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
132
132
case _ =>
133
133
case _ =>
134
134
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. */
135
149
private def transformAnnot (annot : Tree )(using Context ): Tree = {
136
150
val saved = inJavaAnnot
137
151
inJavaAnnot = annot.symbol.is(JavaDefined )
138
152
if (inJavaAnnot) checkValidJavaAnnotation(annot)
139
- try transform(annot)
153
+ try transform(copySymbols( annot) )
140
154
finally inJavaAnnot = saved
141
155
}
142
156
143
157
private def transformAnnot (annot : Annotation )(using Context ): Annotation =
144
158
annot.derivedAnnotation(transformAnnot(annot.tree))
145
159
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
+
146
168
private def processMemberDef (tree : Tree )(using Context ): tree.type = {
147
169
val sym = tree.symbol
148
170
Checking .checkValidOperator(sym)
@@ -460,12 +482,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
460
482
report.error(em " type ${alias.tpe} outside bounds $bounds" , tree.srcPos)
461
483
super .transform(tree)
462
484
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))
469
486
case Typed (Ident (nme.WILDCARD ), _) =>
470
487
withMode(Mode .Pattern )(super .transform(tree))
471
488
// The added mode signals that bounds in a pattern need not
0 commit comments