@@ -48,7 +48,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
48
48
super .transform(tree)
49
49
else tree match {
50
50
51
- // Type tress
51
+ // Type trees
52
52
53
53
case _ : TypTree =>
54
54
if needsHealing(tree.tpe) then TypeTree (healType(tree.sourcePos)(tree.tpe)).withSpan(tree.span)
@@ -82,6 +82,54 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
82
82
super .transform(tree)
83
83
}
84
84
85
+ /** Transform quoted trees while maintaining phase correctness */
86
+ override protected def transformQuotation (body : Tree , quote : Tree )(implicit ctx : Context ): Tree = {
87
+ val taggedTypes = new PCPCheckAndHeal .QuoteTypeTags (quote.span)(using ctx)
88
+ if (ctx.property(InAnnotation ).isDefined)
89
+ ctx.error(" Cannot have a quote in an annotation" , quote.sourcePos)
90
+
91
+ val contextWithQuote =
92
+ if level == 0 then contextWithQuoteTypeTags(taggedTypes)(quoteContext)
93
+ else quoteContext
94
+ val inQuoteOrSpliceOld = inQuoteOrSplice
95
+ inQuoteOrSplice = true
96
+ val body1 = transform(body)(contextWithQuote)
97
+ inQuoteOrSplice = inQuoteOrSpliceOld
98
+ val body2 =
99
+ taggedTypes.getTypeTags match
100
+ case Nil => body1
101
+ case tags => tpd.Block (tags, body1).withSpan(body.span)
102
+
103
+ super .transformQuotation(body2, quote)
104
+ }
105
+
106
+ /** Transform splice
107
+ * - If inside a quote, transform the contents of the splice.
108
+ * - If inside inlined code, expand the macro code.
109
+ * - If inside of a macro definition, check the validity of the macro.
110
+ */
111
+ protected def transformSplice (body : Tree , splice : Tree )(implicit ctx : Context ): Tree = {
112
+ val inQuoteOrSpliceOld = inQuoteOrSplice
113
+ inQuoteOrSplice = true
114
+ val body1 = transform(body)(spliceContext)
115
+ inQuoteOrSplice = inQuoteOrSpliceOld
116
+ splice match {
117
+ case Apply (fun @ TypeApply (_, _ :: Nil ), _) if splice.isTerm =>
118
+ // Type of the splice itsel must also be healed
119
+ // internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
120
+ val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
121
+ cpy.Apply (splice)(cpy.TypeApply (fun)(fun.fun, tpd.TypeTree (tp) :: Nil ), body1 :: Nil )
122
+ case Apply (f @ Apply (fun @ TypeApply (_, _), qctx :: Nil ), _) if splice.isTerm =>
123
+ // Type of the splice itsel must also be healed
124
+ // internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
125
+ val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
126
+ cpy.Apply (splice)(cpy.Apply (f)(cpy.TypeApply (fun)(fun.fun, tpd.TypeTree (tp) :: Nil ), qctx :: Nil ), body1 :: Nil )
127
+ case splice : Select =>
128
+ val tagRef = getQuoteTypeTags.getTagRef(splice.qualifier.tpe.asInstanceOf [TermRef ])
129
+ ref(tagRef).withSpan(splice.span)
130
+ }
131
+ }
132
+
85
133
/** Check that annotations do not contain quotes and and that splices are valid */
86
134
private def checkAnnotations (tree : Tree )(using Context ): Unit =
87
135
tree match
@@ -158,6 +206,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
158
206
tree
159
207
}
160
208
209
+ // TODO return new type or else old?
161
210
protected def tryHeal (sym : Symbol , tp : TypeRef , pos : SourcePosition )(implicit ctx : Context ): Option [TypeRef ] = {
162
211
val reqType = defn.QuotedTypeClass .typeRef.appliedTo(tp)
163
212
val tag = ctx.typer.inferImplicitArg(reqType, pos.span)
@@ -190,53 +239,6 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
190
239
None
191
240
}
192
241
193
- /** Transform quoted trees while maintaining phase correctness */
194
- override protected def transformQuotation (body : Tree , quote : Tree )(implicit ctx : Context ): Tree = {
195
- val taggedTypes = new PCPCheckAndHeal .QuoteTypeTags (quote.span)(using ctx)
196
- if (ctx.property(InAnnotation ).isDefined)
197
- ctx.error(" Cannot have a quote in an annotation" , quote.sourcePos)
198
-
199
- val contextWithQuote =
200
- if level == 0 then contextWithQuoteTypeTags(taggedTypes)(quoteContext)
201
- else quoteContext
202
- val inQuoteOrSpliceOld = inQuoteOrSplice
203
- inQuoteOrSplice = true
204
- val body1 = transform(body)(contextWithQuote)
205
- inQuoteOrSplice = inQuoteOrSpliceOld
206
- val body2 =
207
- taggedTypes.getTypeTags match
208
- case Nil => body1
209
- case tags => tpd.Block (tags, body1).withSpan(body.span)
210
-
211
- super .transformQuotation(body2, quote)
212
- }
213
-
214
- /** Transform splice
215
- * - If inside a quote, transform the contents of the splice.
216
- * - If inside inlined code, expand the macro code.
217
- * - If inside of a macro definition, check the validity of the macro.
218
- */
219
- protected def transformSplice (body : Tree , splice : Tree )(implicit ctx : Context ): Tree = {
220
- val inQuoteOrSpliceOld = inQuoteOrSplice
221
- inQuoteOrSplice = true
222
- val body1 = transform(body)(spliceContext)
223
- inQuoteOrSplice = inQuoteOrSpliceOld
224
- splice match {
225
- case Apply (fun @ TypeApply (_, _ :: Nil ), _) if splice.isTerm =>
226
- // Type of the splice itsel must also be healed
227
- // internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
228
- val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
229
- cpy.Apply (splice)(cpy.TypeApply (fun)(fun.fun, tpd.TypeTree (tp) :: Nil ), body1 :: Nil )
230
- case Apply (f @ Apply (fun @ TypeApply (_, _), qctx :: Nil ), _) if splice.isTerm =>
231
- // Type of the splice itsel must also be healed
232
- // internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
233
- val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
234
- cpy.Apply (splice)(cpy.Apply (f)(cpy.TypeApply (fun)(fun.fun, tpd.TypeTree (tp) :: Nil ), qctx :: Nil ), body1 :: Nil )
235
- case splice : Select =>
236
- val tagRef = getQuoteTypeTags.getTagRef(splice.qualifier.tpe.asInstanceOf [TermRef ])
237
- ref(tagRef).withSpan(splice.span)
238
- }
239
- }
240
242
}
241
243
242
244
object PCPCheckAndHeal {
0 commit comments