@@ -175,68 +175,65 @@ class ReifyQuotes extends MacroTransform {
175
175
* `scala.quoted.Unpickler.unpickleExpr` that matches `tpe` with
176
176
* core and splices as arguments.
177
177
*/
178
- override protected def transformQuotation (body : Tree , quote : Tree )(implicit ctx : Context ): Tree = {
178
+ override protected def transformQuotation (body : Tree , qctx : Tree , quote : Tree )(implicit ctx : Context ): Tree = {
179
179
val isType = quote.symbol eq defn.InternalQuoted_typeQuote
180
- assert(! (body.symbol.isSplice && (body.isInstanceOf [GenericApply [_]] || body.isInstanceOf [Select ])))
181
180
if (level > 0 ) {
182
181
val body1 = nested(isQuote = true ).transform(body)(quoteContext)
183
- super .transformQuotation(body1, quote)
182
+ super .transformQuotation(body1, qctx, quote)
184
183
}
185
184
else body match {
186
185
case body : RefTree if isCaptured(body.symbol, level + 1 ) =>
187
186
// Optimization: avoid the full conversion when capturing `x`
188
187
// in '{ x } to '{ ${x$1} } and go directly to `x$1`
189
- capturers(body.symbol)(body)
188
+ capturers(body.symbol)(body).select(nme.apply).appliedTo(qctx)
190
189
case _=>
191
190
val (body1, splices) = nested(isQuote = true ).splitQuote(body)(quoteContext)
192
191
if (level == 0 ) {
193
192
val body2 =
194
193
if (body1.isType) body1
195
194
else Inlined (Inliner .inlineCallTrace(ctx.owner, quote.sourcePos), Nil , body1)
196
- pickledQuote(body2, splices, body.tpe, isType).withSpan(quote.span)
195
+ pickledQuote(body2, splices, qctx, body.tpe, isType).withSpan(quote.span)
197
196
}
198
197
else {
199
198
body
200
199
}
201
200
}
202
201
}
203
202
204
- private def pickledQuote (body : Tree , splices : List [Tree ], originalTp : Type , isType : Boolean )(implicit ctx : Context ) = {
205
-
206
- def liftedValue [T ](value : T , name : TermName , qctx : Tree ) =
203
+ private def pickledQuote (body : Tree , splices : List [Tree ], qctx : Tree , originalTp : Type , isType : Boolean )(implicit ctx : Context ) = {
204
+ def liftedValue [T ](value : T , name : TermName ) =
207
205
ref(defn.LiftableModule ).select(name).select(" toExpr" .toTermName).appliedTo(Literal (Constant (value))).appliedTo(qctx)
208
206
209
207
def pickleAsValue [T ](value : T ) = {
210
- val qctx = ctx.typer.inferImplicitArg(defn.QuoteContextClass .typeRef, body.span)
211
- if (qctx.tpe.isInstanceOf [SearchFailureType ])
212
- ctx.error(ctx.typer.missingArgMsg(qctx, defn.QuoteContextClass .typeRef, " " ), ctx.source.atSpan(body.span))
213
208
value match {
214
209
case null => ref(defn.QuotedExprModule ).select(" nullExpr" .toTermName).appliedTo(qctx)
215
210
case _ : Unit => ref(defn.QuotedExprModule ).select(" unitExpr" .toTermName).appliedTo(qctx)
216
- case _ : Boolean => liftedValue(value, " Liftable_Boolean_delegate" .toTermName, qctx )
217
- case _ : Byte => liftedValue(value, " Liftable_Byte_delegate" .toTermName, qctx )
218
- case _ : Short => liftedValue(value, " Liftable_Short_delegate" .toTermName, qctx )
219
- case _ : Int => liftedValue(value, " Liftable_Int_delegate" .toTermName, qctx )
220
- case _ : Long => liftedValue(value, " Liftable_Long_delegate" .toTermName, qctx )
221
- case _ : Float => liftedValue(value, " Liftable_Float_delegate" .toTermName, qctx )
222
- case _ : Double => liftedValue(value, " Liftable_Double_delegate" .toTermName, qctx )
223
- case _ : Char => liftedValue(value, " Liftable_Char_delegate" .toTermName, qctx )
224
- case _ : String => liftedValue(value, " Liftable_String_delegate" .toTermName, qctx )
211
+ case _ : Boolean => liftedValue(value, " Liftable_Boolean_delegate" .toTermName)
212
+ case _ : Byte => liftedValue(value, " Liftable_Byte_delegate" .toTermName)
213
+ case _ : Short => liftedValue(value, " Liftable_Short_delegate" .toTermName)
214
+ case _ : Int => liftedValue(value, " Liftable_Int_delegate" .toTermName)
215
+ case _ : Long => liftedValue(value, " Liftable_Long_delegate" .toTermName)
216
+ case _ : Float => liftedValue(value, " Liftable_Float_delegate" .toTermName)
217
+ case _ : Double => liftedValue(value, " Liftable_Double_delegate" .toTermName)
218
+ case _ : Char => liftedValue(value, " Liftable_Char_delegate" .toTermName)
219
+ case _ : String => liftedValue(value, " Liftable_String_delegate" .toTermName)
225
220
}
226
221
}
227
222
228
223
def pickleAsTasty () = {
229
224
val meth =
230
225
if (isType) ref(defn.Unpickler_unpickleType ).appliedToType(originalTp)
231
226
else ref(defn.Unpickler_unpickleExpr ).appliedToType(originalTp.widen)
232
- def wildcardQuotedType = defn.QuotedTypeClass .typeRef.appliedTo(WildcardType )
233
227
val spliceResType =
234
- if (isType) wildcardQuotedType
235
- else defn.QuotedExprClass .typeRef.appliedTo(defn.AnyType ) | wildcardQuotedType
236
- meth.appliedTo(
237
- liftList(PickledQuotes .pickleQuote(body).map(x => Literal (Constant (x))), defn.StringType ),
238
- liftList(splices, defn.FunctionType (1 ).appliedTo(defn.SeqType .appliedTo(defn.AnyType ), spliceResType)))
228
+ if (isType) defn.QuotedTypeClass .typeRef.appliedTo(WildcardType )
229
+ else defn.FunctionType (1 , isContextual = true ).appliedTo(defn.QuoteContextClass .typeRef, defn.QuotedExprClass .typeRef.appliedTo(defn.AnyType )) | defn.QuotedTypeClass .typeRef.appliedTo(WildcardType )
230
+ val pickledQuoteStrings = liftList(PickledQuotes .pickleQuote(body).map(x => Literal (Constant (x))), defn.StringType )
231
+ val splicesList = liftList(splices, defn.FunctionType (1 ).appliedTo(defn.SeqType .appliedTo(defn.AnyType ), spliceResType))
232
+ val pickled = meth.appliedTo(pickledQuoteStrings, splicesList)
233
+ if (isType) pickled
234
+ else pickled.appliedTo(qctx)
239
235
}
236
+
240
237
if (splices.nonEmpty) pickleAsTasty()
241
238
else if (isType) {
242
239
def tag (tagName : String ) = ref(defn.QuotedTypeModule ).select(tagName.toTermName)
@@ -315,7 +312,7 @@ class ReifyQuotes extends MacroTransform {
315
312
assert(tpw.isInstanceOf [ValueType ])
316
313
val argTpe =
317
314
if (tree.isType) defn.QuotedTypeClass .typeRef.appliedTo(tpw)
318
- else defn.QuotedExprClass .typeRef.appliedTo(tpw)
315
+ else defn.FunctionType ( 1 , isContextual = true ).appliedTo(defn. QuoteContextClass .typeRef, defn. QuotedExprClass .typeRef.appliedTo(tpw) )
319
316
val selectArg = arg.select(nme.apply).appliedTo(Literal (Constant (i))).cast(argTpe)
320
317
val capturedArg = SyntheticValDef (UniqueName .fresh(tree.symbol.name.toTermName).toTermName, selectArg)
321
318
i += 1
@@ -356,7 +353,9 @@ class ReifyQuotes extends MacroTransform {
356
353
val tree2 = transform(tree)
357
354
capturers --= outer.localSymbols
358
355
359
- seq(captured.result().valuesIterator.toList, tree2)
356
+ val captures = captured.result().valuesIterator.toList
357
+ if (captures.isEmpty) tree2
358
+ else Block (captures, tree2)
360
359
}
361
360
362
361
/** Returns true if this tree will be captured by `makeLambda`. Checks phase consistency and presence of capturer. */
0 commit comments