@@ -109,10 +109,15 @@ class ReifyQuotes extends MacroTransformWithImplicits {
109
109
def inSplice = outer != null && ! inQuote
110
110
111
111
/** A map from type ref T to expressions of type `quoted.Type[T]`".
112
- * These will be turned into splices using `addTags`
112
+ * These will be turned into splices using `addTags` and represent type variables
113
+ * that can be possibly healed.
113
114
*/
114
115
val importedTags = new mutable.LinkedHashMap [TypeRef , Tree ]()
115
116
117
+ /** A map from type ref T to expressions of type `quoted.Type[T]`" like `importedTags`
118
+ * These will be turned into splices using `addTags` and represent types spliced
119
+ * explicitly.
120
+ */
116
121
val explicitTags = new mutable.LinkedHashSet [TypeRef ]()
117
122
118
123
/** A stack of entered symbols, to be unwound after scope exit */
@@ -130,41 +135,43 @@ class ReifyQuotes extends MacroTransformWithImplicits {
130
135
* defined versions. As a side effect, prepend the expressions `tag1, ..., `tagN`
131
136
* as splices to `embedded`.
132
137
*/
133
- private def addTags (expr : Tree )(implicit ctx : Context ): Tree =
138
+ private def addTags (expr : Tree )(implicit ctx : Context ): Tree = {
139
+
140
+ def mkTagSymbolAndAssignType (typeRef : TypeRef , tag : Tree ): Tree = {
141
+ val rhs = transform(tag.select(tpnme.UNARY_~ ))
142
+ val alias = ctx.typeAssigner.assignType(untpd.TypeBoundsTree (rhs, rhs), rhs, rhs)
143
+
144
+ val original = typeRef.symbol.asType
145
+
146
+ val local = ctx.newSymbol(
147
+ owner = ctx.owner,
148
+ name = UniqueName .fresh(" T" .toTermName).toTypeName,
149
+ flags = Synthetic ,
150
+ info = TypeAlias (tag.tpe.select(tpnme.UNARY_~ )),
151
+ coord = typeRef.prefix.termSymbol.coord).asType
152
+
153
+ ctx.typeAssigner.assignType(untpd.TypeDef (local.name, alias), local)
154
+ }
155
+
134
156
if (importedTags.isEmpty && explicitTags.isEmpty) expr
135
157
else {
136
158
val itags = importedTags.toList
159
+ // The tree of the tag for each tag comes from implicit search in `tryHeal`
137
160
val typeDefs = for ((tref, tag) <- itags) yield {
138
- val rhs = transform(tag.select(tpnme.UNARY_~ ))
139
- val alias = ctx.typeAssigner.assignType(untpd.TypeBoundsTree (rhs, rhs), rhs, rhs)
140
- val original = tref.symbol.asType
141
- val local = original.copy(
142
- owner = ctx.owner,
143
- name = (original.name + " $$" ).toTypeName,
144
- flags = Synthetic ,
145
- info = TypeAlias (tag.tpe.select(tpnme.UNARY_~ ))).asType
146
-
147
- ctx.typeAssigner.assignType(untpd.TypeDef (local.name, alias), local)
161
+ mkTagSymbolAndAssignType(tref, tag)
148
162
}
149
163
importedTags.clear()
150
164
151
-
165
+ // The tree of the tag for each tag comes from a type ref e.g., ~t
152
166
val explicitTypeDefs = for (tref <- explicitTags) yield {
153
167
val tag = ref(tref.prefix.termSymbol)
154
- val rhs = transform(tag.select(tpnme.UNARY_~ ))
155
-
156
- val alias = ctx.typeAssigner.assignType(untpd.TypeBoundsTree (rhs, rhs), rhs, rhs)
157
-
158
- val local = ctx.newSymbol(
159
- owner = ctx.owner,
160
- name = UniqueName .fresh(" ttt" .toTermName).toTypeName,
161
- flags = Synthetic ,
162
- info = TypeAlias (tag.tpe.select(tpnme.UNARY_~ )),
163
- coord = tref.prefix.termSymbol.coord).asType
164
-
165
- (tref, ctx.typeAssigner.assignType(untpd.TypeDef (local.name, alias), local))
168
+ mkTagSymbolAndAssignType(tref, tag)
166
169
}
167
- val map : Map [Type , Type ] = explicitTypeDefs.map(x => (x._1, x._2.symbol.typeRef)).toMap
170
+ val tagsExplicitTypeDefsPairs = explicitTags.zip(explicitTypeDefs)
171
+ explicitTags.clear()
172
+
173
+ // Maps type splices to type references of tags e.g., ~t -> some type T$1
174
+ val map : Map [Type , Type ] = tagsExplicitTypeDefsPairs.map(x => (x._1, x._2.symbol.typeRef)).toMap
168
175
val tMap = new TypeMap () {
169
176
override def apply (tp : Type ): Type = {
170
177
if (map.contains(tp))
@@ -174,11 +181,14 @@ class ReifyQuotes extends MacroTransformWithImplicits {
174
181
}
175
182
}
176
183
177
- Block (typeDefs ++ explicitTypeDefs.map(_._2),
178
- new TreeTypeMap (typeMap = tMap,
179
- substFrom = itags.map(_._1.symbol), substTo = typeDefs.map(_.symbol))
180
- .apply(expr))
184
+ Block (typeDefs ++ tagsExplicitTypeDefsPairs.map(_._2),
185
+ new TreeTypeMap (
186
+ typeMap = tMap,
187
+ substFrom = itags.map(_._1.symbol),
188
+ substTo = typeDefs.map(_.symbol)
189
+ ).apply(expr))
181
190
}
191
+ }
182
192
183
193
/** Enter staging level of symbol defined by `tree`, if applicable. */
184
194
def markDef (tree : Tree )(implicit ctx : Context ) = tree match {
@@ -449,6 +459,11 @@ class ReifyQuotes extends MacroTransformWithImplicits {
449
459
tree match {
450
460
case Quoted (quotedTree) =>
451
461
quotation(quotedTree, tree)
462
+ case tree : TypeTree if tree.tpe.typeSymbol.isSplice =>
463
+ val splicedType = tree.tpe.asInstanceOf [TypeRef ].prefix.termSymbol
464
+ splice(ref(splicedType).select(tpnme.UNARY_~ ))
465
+ case tree : TypeApply =>
466
+ super .transform(tree)
452
467
case tree : Select if tree.symbol.isSplice =>
453
468
splice(tree)
454
469
case tree : RefTree if needsLifting(tree) =>
@@ -458,7 +473,6 @@ class ReifyQuotes extends MacroTransformWithImplicits {
458
473
val last = enteredSyms
459
474
stats.foreach(markDef)
460
475
mapOverTree(last)
461
-
462
476
case Inlined (call, bindings, InlineSplice (expansion @ Select (body, name))) =>
463
477
// To maintain phase consistency, we move the binding of the this parameter into the spliced code
464
478
val (splicedBindings, stagedBindings) = bindings.partition {
0 commit comments