@@ -108,10 +108,15 @@ class ReifyQuotes extends MacroTransformWithImplicits {
108108 val embedded = new mutable.ListBuffer [Tree ]
109109
110110 /** 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.
112113 */
113114 val importedTags = new mutable.LinkedHashMap [TypeRef , Tree ]()
114115
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+ */
115120 val explicitTags = new mutable.LinkedHashSet [TypeRef ]()
116121
117122 /** A stack of entered symbols, to be unwound after scope exit */
@@ -129,41 +134,43 @@ class ReifyQuotes extends MacroTransformWithImplicits {
129134 * defined versions. As a side effect, prepend the expressions `tag1, ..., `tagN`
130135 * as splices to `embedded`.
131136 */
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+
133155 if (importedTags.isEmpty && explicitTags.isEmpty) expr
134156 else {
135157 val itags = importedTags.toList
158+ // The tree of the tag for each tag comes from implicit search in `tryHeal`
136159 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)
147161 }
148162 importedTags.clear()
149163
150-
164+ // The tree of the tag for each tag comes from a type ref e.g., ~t
151165 val explicitTypeDefs = for (tref <- explicitTags) yield {
152166 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)
165168 }
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
167174 val tMap = new TypeMap () {
168175 override def apply (tp : Type ): Type = {
169176 if (map.contains(tp))
@@ -173,11 +180,14 @@ class ReifyQuotes extends MacroTransformWithImplicits {
173180 }
174181 }
175182
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))
180189 }
190+ }
181191
182192 /** Enter staging level of symbol defined by `tree`, if applicable. */
183193 def markDef (tree : Tree )(implicit ctx : Context ) = tree match {
@@ -450,6 +460,11 @@ class ReifyQuotes extends MacroTransformWithImplicits {
450460 tree match {
451461 case Quoted (quotedTree) =>
452462 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)
453468 case tree : Select if tree.symbol.isSplice =>
454469 splice(tree)
455470 case tree : RefTree if needsLifting(tree) =>
@@ -459,7 +474,6 @@ class ReifyQuotes extends MacroTransformWithImplicits {
459474 val last = enteredSyms
460475 stats.foreach(markDef)
461476 mapOverTree(last)
462-
463477 case Inlined (call, bindings, InlineSplice (expansion @ Select (body, name))) =>
464478 // To maintain phase consistency, we move the binding of the this parameter into the spliced code
465479 val (splicedBindings, stagedBindings) = bindings.partition {
0 commit comments