@@ -109,10 +109,15 @@ class ReifyQuotes extends MacroTransformWithImplicits {
109109 def inSplice = outer != null && ! inQuote
110110
111111 /** 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.
113114 */
114115 val importedTags = new mutable.LinkedHashMap [TypeRef , Tree ]()
115116
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+ */
116121 val explicitTags = new mutable.LinkedHashSet [TypeRef ]()
117122
118123 /** A stack of entered symbols, to be unwound after scope exit */
@@ -130,41 +135,43 @@ class ReifyQuotes extends MacroTransformWithImplicits {
130135 * defined versions. As a side effect, prepend the expressions `tag1, ..., `tagN`
131136 * as splices to `embedded`.
132137 */
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+
134156 if (importedTags.isEmpty && explicitTags.isEmpty) expr
135157 else {
136158 val itags = importedTags.toList
159+ // The tree of the tag for each tag comes from implicit search in `tryHeal`
137160 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)
148162 }
149163 importedTags.clear()
150164
151-
165+ // The tree of the tag for each tag comes from a type ref e.g., ~t
152166 val explicitTypeDefs = for (tref <- explicitTags) yield {
153167 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)
166169 }
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
168175 val tMap = new TypeMap () {
169176 override def apply (tp : Type ): Type = {
170177 if (map.contains(tp))
@@ -174,11 +181,14 @@ class ReifyQuotes extends MacroTransformWithImplicits {
174181 }
175182 }
176183
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))
181190 }
191+ }
182192
183193 /** Enter staging level of symbol defined by `tree`, if applicable. */
184194 def markDef (tree : Tree )(implicit ctx : Context ) = tree match {
@@ -449,6 +459,11 @@ class ReifyQuotes extends MacroTransformWithImplicits {
449459 tree match {
450460 case Quoted (quotedTree) =>
451461 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)
452467 case tree : Select if tree.symbol.isSplice =>
453468 splice(tree)
454469 case tree : RefTree if needsLifting(tree) =>
@@ -458,7 +473,6 @@ class ReifyQuotes extends MacroTransformWithImplicits {
458473 val last = enteredSyms
459474 stats.foreach(markDef)
460475 mapOverTree(last)
461-
462476 case Inlined (call, bindings, InlineSplice (expansion @ Select (body, name))) =>
463477 // To maintain phase consistency, we move the binding of the this parameter into the spliced code
464478 val (splicedBindings, stagedBindings) = bindings.partition {
0 commit comments