@@ -98,46 +98,47 @@ class CrossStageSafety extends TreeMapWithStages {
9898 }
9999
100100 /** Transform quoted trees while maintaining level correctness */
101- override protected def transformQuotation (body : Tree , quote : Apply )(using Context ): Tree = {
102- val taggedTypes = new QuoteTypeTags (quote.span)
103-
101+ override protected def transformQuotedExpr (body : Tree , quote : Apply )(using Context ): Tree = {
104102 if (ctx.property(InAnnotation ).isDefined)
105103 report.error(" Cannot have a quote in an annotation" , quote.srcPos)
106104
107105 val stripAnnotsDeep : TypeMap = new TypeMap :
108106 def apply (tp : Type ): Type = mapOver(tp.stripAnnots)
107+ val transformedBody = transformQuoteBody(body, quote)
108+ // `quoted.runtime.Expr.quote[T](<body>)` --> `quoted.runtime.Expr.quote[T2](<body2>)`
109+ val TypeApply (fun, targs) = quote.fun: @ unchecked
110+ val targs2 = targs.map(targ => TypeTree (healType(quote.fun.srcPos)(stripAnnotsDeep(targ.tpe))))
111+ cpy.Apply (quote)(cpy.TypeApply (quote.fun)(fun, targs2), transformedBody :: Nil )
112+ }
109113
110- def transformBody () =
111- val contextWithQuote =
112- if level == 0 then contextWithQuoteTypeTags(taggedTypes)(using quoteContext)
113- else quoteContext
114- val transformedBody = transform(body)(using contextWithQuote)
115- taggedTypes.getTypeTags match
116- case Nil => transformedBody
117- case tags => tpd.Block (tags, transformedBody).withSpan(body.span)
118-
119- if body.isTerm then
120- val transformedBody = transformBody()
121- // `quoted.runtime.Expr.quote[T](<body>)` --> `quoted.runtime.Expr.quote[T2](<body2>)`
122- val TypeApply (fun, targs) = quote.fun: @ unchecked
123- val targs2 = targs.map(targ => TypeTree (healType(quote.fun.srcPos)(stripAnnotsDeep(targ.tpe))))
124- cpy.Apply (quote)(cpy.TypeApply (quote.fun)(fun, targs2), transformedBody :: Nil )
125- else
126- body.tpe match
127- case DirectTypeOf (termRef) =>
128- // Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
129- ref(termRef).withSpan(quote.span)
130- case _ =>
131- transformBody() match
132- case DirectTypeOf .Healed (termRef) =>
133- // Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
134- ref(termRef).withSpan(quote.span)
135- case transformedBody =>
136- val quotes = quote.args.mapConserve(transform)
137- // `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
138- val TypeApply (fun, _) = quote.fun: @ unchecked
139- cpy.Apply (quote)(cpy.TypeApply (quote.fun)(fun, transformedBody :: Nil ), quotes)
114+ override protected def transformQuotedType (body : Tree , quote : Apply )(using Context ): Tree = {
115+ if (ctx.property(InAnnotation ).isDefined)
116+ report.error(" Cannot have a quote in an annotation" , quote.srcPos)
117+ body.tpe match
118+ case DirectTypeOf (termRef) =>
119+ // Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
120+ ref(termRef).withSpan(quote.span)
121+ case _ =>
122+ transformQuoteBody(body, quote) match
123+ case DirectTypeOf .Healed (termRef) =>
124+ // Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
125+ ref(termRef).withSpan(quote.span)
126+ case transformedBody =>
127+ val quotes = quote.args.mapConserve(transform)
128+ // `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
129+ val TypeApply (fun, _) = quote.fun: @ unchecked
130+ cpy.Apply (quote)(cpy.TypeApply (quote.fun)(fun, transformedBody :: Nil ), quotes)
131+ }
140132
133+ private def transformQuoteBody (body : Tree , quote : Apply )(using Context ): Tree = {
134+ val taggedTypes = new QuoteTypeTags (quote.span)
135+ val contextWithQuote =
136+ if level == 0 then contextWithQuoteTypeTags(taggedTypes)(using quoteContext)
137+ else quoteContext
138+ val transformedBody = transform(body)(using contextWithQuote)
139+ taggedTypes.getTypeTags match
140+ case Nil => transformedBody
141+ case tags => tpd.Block (tags, transformedBody).withSpan(body.span)
141142 }
142143
143144 /** Transform splice
0 commit comments