1
- package dotty .tools .dotc
2
- package transform
3
-
4
- import core ._
5
- import Decorators ._ , Flags ._ , Types ._ , Contexts ._ , Symbols ._ , Constants ._
6
- import ast .Trees ._
7
- import ast .{TreeTypeMap , untpd }
8
- import util .Positions ._
9
- import tasty .TreePickler .Hole
10
- import SymUtils ._
11
- import NameKinds ._
12
- import dotty .tools .dotc .ast .tpd
13
- import typer .Implicits .SearchFailureType
1
+ package dotty .tools .dotc .transform
2
+
3
+ import dotty .tools .dotc .ast .Trees ._
4
+ import dotty .tools .dotc .ast .{TreeTypeMap , tpd , untpd }
5
+ import dotty .tools .dotc .core .Constants ._
6
+ import dotty .tools .dotc .core .Contexts ._
7
+ import dotty .tools .dotc .core .Decorators ._
8
+ import dotty .tools .dotc .core .Flags ._
9
+ import dotty .tools .dotc .core .NameKinds ._
10
+ import dotty .tools .dotc .core .Symbols ._
11
+ import dotty .tools .dotc .core .Types ._
12
+ import dotty .tools .dotc .core .tasty .TreePickler .Hole
13
+ import dotty .tools .dotc .reporting
14
+ import dotty .tools .dotc .transform .SymUtils ._
15
+ import dotty .tools .dotc .typer .Implicits .SearchFailureType
16
+ import dotty .tools .dotc .util .Positions ._
17
+ import dotty .tools .dotc .util .SourcePosition
14
18
15
19
import scala .collection .mutable
16
20
import dotty .tools .dotc .core .StdNames ._
17
21
import dotty .tools .dotc .core .quoted ._
18
- import dotty .tools .dotc .util .SourcePosition
19
22
20
23
21
24
/** Checks that the phase consistency principle (PCP) holds, heals types and expand macros.
@@ -83,7 +86,7 @@ class Staging extends MacroTransformWithImplicits {
83
86
* These will be turned into splices using `addTags` and represent types spliced
84
87
* explicitly.
85
88
*/
86
- val explicitTags = new mutable.LinkedHashSet [TypeRef ]()
89
+ val explicitTags = new mutable.LinkedHashSet [( TypeRef , Position ) ]()
87
90
88
91
/** A stack of entered symbols, to be unwound after scope exit */
89
92
var enteredSyms : List [Symbol ] = Nil
@@ -111,7 +114,8 @@ class Staging extends MacroTransformWithImplicits {
111
114
name = UniqueName .fresh(" T" .toTermName).toTypeName,
112
115
flags = Synthetic ,
113
116
info = TypeAlias (tag.tpe.select(tpnme.UNARY_~ )),
114
- coord = typeRef.prefix.termSymbol.coord).asType
117
+ coord = alias.pos
118
+ ).asType
115
119
116
120
ctx.typeAssigner.assignType(untpd.TypeDef (local.name, alias), local)
117
121
}
@@ -126,11 +130,11 @@ class Staging extends MacroTransformWithImplicits {
126
130
importedTags.clear()
127
131
128
132
// The tree of the tag for each tag comes from a type ref e.g., ~t
129
- val explicitTypeDefs = for (tref <- explicitTags) yield {
130
- val tag = ref(tref.prefix.termSymbol)
133
+ val explicitTypeDefs = for (( tref, pos) <- explicitTags) yield {
134
+ val tag = ref(tref.prefix.termSymbol).withPos(pos)
131
135
mkTagSymbolAndAssignType(tref, tag)
132
136
}
133
- val tagsExplicitTypeDefsPairs = explicitTags.zip(explicitTypeDefs)
137
+ val tagsExplicitTypeDefsPairs = explicitTags.map(_._1). zip(explicitTypeDefs)
134
138
explicitTags.clear()
135
139
136
140
// Maps type splices to type references of tags e.g., ~t -> some type T$1
@@ -150,8 +154,52 @@ class Staging extends MacroTransformWithImplicits {
150
154
}
151
155
}
152
156
157
+ /** Type tree map that does not tag type at level 0 */
158
+ class QuoteTreeTypeMap (
159
+ typeMap : Type => Type = IdentityTypeMap ,
160
+ treeMap : tpd.Tree => tpd.Tree = identity _,
161
+ oldOwners : List [Symbol ] = Nil ,
162
+ newOwners : List [Symbol ] = Nil ,
163
+ substFrom : List [Symbol ] = Nil ,
164
+ substTo : List [Symbol ] = Nil
165
+ )(implicit ctx : Context ) extends TreeTypeMap (typeMap, treeMap, oldOwners, newOwners, substFrom, substTo) { self =>
166
+
167
+ protected var level = 1 // TODO use context to keep track of the level
168
+
169
+ override def transform (tree : tpd.Tree )(implicit ctx : Context ): tpd.Tree = {
170
+ if (level == 0 ) {
171
+ // Keep transforming but do not replace insert the taged types. Types in nested quotes are also not taged.
172
+ val (sFrom, sTo) = substFrom.zip(substTo).filterNot(_._2.is(Synthetic )).unzip // TODO Syntetic is probably not enugh to distinguish added types
173
+ new TreeTypeMap (typeMap, treeMap,
174
+ oldOwners, newOwners,
175
+ sFrom, sTo
176
+ ).transform(tree)
177
+ }
178
+ else if (tree.symbol.isSplice) {
179
+ level -= 1
180
+ try super .transform(tree)
181
+ finally level += 1
182
+ } else if (tree.symbol.isQuote) {
183
+ level += 1
184
+ try super .transform(tree)
185
+ finally level -= 1
186
+ }
187
+ else super .transform(tree)
188
+
189
+ }
190
+
191
+ protected override def newTreeTypeMap (typeMap : Type => Type , treeMap : tpd.Tree => tpd.Tree ,
192
+ oldOwners : List [Symbol ], newOwners : List [Symbol ],
193
+ substFrom : List [Symbol ], substTo : List [Symbol ]) = {
194
+ new QuoteTreeTypeMap (typeMap, treeMap, oldOwners, newOwners, substFrom, substTo) {
195
+ level = self.level
196
+ }
197
+ }
198
+
199
+ }
200
+
153
201
Block (typeDefs ++ explicitTypeDefs,
154
- new TreeTypeMap (
202
+ new QuoteTreeTypeMap (
155
203
treeMap = trMap,
156
204
typeMap = tpMap,
157
205
substFrom = itags.map(_._1.symbol),
@@ -243,7 +291,7 @@ class Staging extends MacroTransformWithImplicits {
243
291
tp match {
244
292
case tp : TypeRef if tp.symbol.isSplice =>
245
293
if (inQuote) {
246
- explicitTags += tp
294
+ explicitTags += Tuple2 (tp, pos)
247
295
outer.checkType(pos).foldOver(acc, tp)
248
296
}
249
297
else {
@@ -333,7 +381,7 @@ class Staging extends MacroTransformWithImplicits {
333
381
}
334
382
else if (enclosingInlineds.nonEmpty) { // level 0 in an inlined call
335
383
val spliceCtx = ctx.outer // drop the last `inlineContext`
336
- val pos : SourcePosition = Decorators . sourcePos(enclosingInlineds.head.pos)(spliceCtx)
384
+ val pos : SourcePosition = sourcePos(enclosingInlineds.head.pos)(spliceCtx)
337
385
val evaluatedSplice = Splicer .splice(splice.qualifier, pos, macroClassLoader)(spliceCtx).withPos(splice.pos)
338
386
if (ctx.reporter.hasErrors) splice else transform(evaluatedSplice)
339
387
}
@@ -396,7 +444,7 @@ class Staging extends MacroTransformWithImplicits {
396
444
tree.rhs match {
397
445
case InlineSplice (_) =>
398
446
mapOverTree(enteredSyms) // Ignore output, only check PCP
399
- cpy. DefDef ( tree)(rhs = defaultValue(tree.rhs.tpe))
447
+ tree
400
448
case _ =>
401
449
ctx.error(
402
450
""" Malformed macro.
0 commit comments