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