@@ -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,7 +132,21 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
132
132
case _ =>
133
133
case _ =>
134
134
135
- private def transformAnnot (annot : Tree )(using Context ): Tree = {
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. */
149
+ private def transformAnnotTree (annot : Tree )(using Context ): Tree = {
136
150
val saved = inJavaAnnot
137
151
inJavaAnnot = annot.symbol.is(JavaDefined )
138
152
if (inJavaAnnot) checkValidJavaAnnotation(annot)
@@ -141,7 +155,19 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
141
155
}
142
156
143
157
private def transformAnnot (annot : Annotation )(using Context ): Annotation =
144
- annot.derivedAnnotation(transformAnnot(annot.tree))
158
+ val tree1 =
159
+ annot match
160
+ case _ : BodyAnnotation => annot.tree
161
+ case _ => copySymbols(annot.tree)
162
+ annot.derivedAnnotation(transformAnnotTree(tree1))
163
+
164
+ /** Transforms all annotations in the given type. */
165
+ private def transformAnnotsIn (using Context ) =
166
+ new TypeMap :
167
+ def apply (tp : Type ) = tp match
168
+ case tp @ AnnotatedType (parent, annot) =>
169
+ tp.derivedAnnotatedType(mapOver(parent), transformAnnot(annot))
170
+ case _ => mapOver(tp)
145
171
146
172
private def processMemberDef (tree : Tree )(using Context ): tree.type = {
147
173
val sym = tree.symbol
@@ -438,7 +464,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
438
464
Checking .checkRealizable(tree.tpt.tpe, tree.srcPos, " SAM type" )
439
465
super .transform(tree)
440
466
case tree @ Annotated (annotated, annot) =>
441
- cpy.Annotated (tree)(transform(annotated), transformAnnot (annot))
467
+ cpy.Annotated (tree)(transform(annotated), transformAnnotTree (annot))
442
468
case tree : AppliedTypeTree =>
443
469
if (tree.tpt.symbol == defn.andType)
444
470
Checking .checkNonCyclicInherited(tree.tpe, tree.args.tpes, EmptyScope , tree.srcPos)
@@ -460,12 +486,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
460
486
report.error(em " type ${alias.tpe} outside bounds $bounds" , tree.srcPos)
461
487
super .transform(tree)
462
488
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
- )
489
+ tree.withType(transformAnnotsIn(tree.tpe))
469
490
case Typed (Ident (nme.WILDCARD ), _) =>
470
491
withMode(Mode .Pattern )(super .transform(tree))
471
492
// The added mode signals that bounds in a pattern need not
0 commit comments