@@ -155,10 +155,9 @@ class ReifyQuotes extends MacroTransform {
155155 */
156156 def pickleAsLiteral (lit : Literal ) = {
157157 val exprType = defn.QuotedExprClass .typeRef.appliedTo(body.tpe)
158- val tpe = MethodType (defn.QuoteContextClass .typeRef :: Nil , exprType)
159- val meth = newSymbol(ctx.owner, UniqueName .fresh(nme.ANON_FUN ), Synthetic | Method , tpe)
160- def mkConst (tss : List [List [Tree ]]) = {
161- val reflect = tss.head.head.select(" reflect" .toTermName)
158+ val lambdaTpe = MethodType (defn.QuoteContextClass .typeRef :: Nil , exprType)
159+ def mkConst (ts : List [Tree ]) = {
160+ val reflect = ts.head.select(" reflect" .toTermName)
162161 val typeName = body.tpe.typeSymbol.name
163162 val literalValue =
164163 if lit.const.tag == Constants .NullTag || lit.const.tag == Constants .UnitTag then Nil
@@ -167,7 +166,7 @@ class ReifyQuotes extends MacroTransform {
167166 val literal = reflect.select(" Literal" .toTermName).select(nme.apply).appliedTo(constant)
168167 reflect.select(" TreeMethods" .toTermName).select(" asExpr" .toTermName).appliedTo(literal).asInstance(exprType)
169168 }
170- Closure (meth , mkConst).withSpan(body.span)
169+ Lambda (lambdaTpe , mkConst).withSpan(body.span)
171170 }
172171
173172 def pickleAsValue (lit : Literal ) = {
@@ -190,13 +189,30 @@ class ReifyQuotes extends MacroTransform {
190189 }
191190 }
192191
192+ /** Encode quote using QuoteContextInternal.{unpickleExpr, unpickleType}
193+ *
194+ * Generate the code
195+ * ```scala
196+ * qctx => qctx.asInstanceOf[QuoteContextInternal].<unpickleExpr|unpickleType>[<type>](
197+ * <pickledQuote>
198+ * )
199+ * ```
200+ * this closure is always applied directly to the actual context and the BetaReduce phase removes it.
201+ */
193202 def pickleAsTasty () = {
194- val unpickleMeth = if isType then defn.PickledQuote_unpickleType else defn.PickledQuote_unpickleExpr
195203 val pickledQuoteStrings = liftList(PickledQuotes .pickleQuote(body).map(x => Literal (Constant (x))), defn.StringType )
196204 // TODO: generate an instance of PickledSplices directly instead of passing through a List
197205 val splicesList = liftList(splices, defn.FunctionType (1 ).appliedTo(defn.SeqType .appliedTo(defn.AnyType ), defn.AnyType ))
198206 val pickledQuote = ref(defn.PickledQuote_make ).appliedTo(pickledQuoteStrings, splicesList)
199- ref(unpickleMeth).appliedToType(originalTp).appliedTo(pickledQuote)
207+ val quoteClass = if isType then defn.QuotedTypeClass else defn.QuotedExprClass
208+ val quotedType = quoteClass.typeRef.appliedTo(originalTp)
209+ val lambdaTpe = MethodType (defn.QuoteContextClass .typeRef :: Nil , quotedType)
210+ def callUnpickle (ts : List [Tree ]) = {
211+ val qctx = ts.head.asInstance(defn.QuoteContextInternalClass .typeRef)
212+ val unpickleMethName = if isType then " unpickleType" else " unpickleExpr"
213+ qctx.select(unpickleMethName.toTermName).appliedToType(originalTp).appliedTo(pickledQuote)
214+ }
215+ Lambda (lambdaTpe, callUnpickle).withSpan(body.span)
200216 }
201217
202218 /** Encode quote using Reflection.TypeRepr.typeConstructorOf
@@ -212,14 +228,13 @@ class ReifyQuotes extends MacroTransform {
212228 def taggedType () =
213229 val typeType = defn.QuotedTypeClass .typeRef.appliedTo(body.tpe)
214230 val classTree = TypeApply (ref(defn.Predef_classOf .termRef), body :: Nil )
215- val tpe = MethodType (defn.QuoteContextClass .typeRef :: Nil , typeType)
216- val meth = newSymbol(ctx.owner, UniqueName .fresh(nme.ANON_FUN ), Synthetic | Method , tpe)
217- def mkConst (tss : List [List [Tree ]]) = {
218- val reflect = tss.head.head.select(" reflect" .toTermName)
231+ val lambdaTpe = MethodType (defn.QuoteContextClass .typeRef :: Nil , typeType)
232+ def callTypeConstructorOf (ts : List [Tree ]) = {
233+ val reflect = ts.head.select(" reflect" .toTermName)
219234 val typeRepr = reflect.select(" TypeRepr" .toTermName).select(" typeConstructorOf" .toTermName).appliedTo(classTree)
220235 reflect.select(" TypeReprMethods" .toTermName).select(" asType" .toTermName).appliedTo(typeRepr).asInstance(typeType)
221236 }
222- Closure (meth, mkConst ).withSpan(body.span)
237+ Lambda (lambdaTpe, callTypeConstructorOf ).withSpan(body.span)
223238
224239 if (isType) {
225240 if (splices.isEmpty && body.symbol.isPrimitiveValueClass) taggedType()
0 commit comments