From 24168c7f24889a0901438f3547d5bf7b82ec0d6a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 7 Jan 2021 15:31:28 +0100 Subject: [PATCH] Add regression test Fixes #9254 --- tests/pos-macros/i9254/Macros_1.scala | 59 +++++++++++++++++++++++++++ tests/pos-macros/i9254/Test_2.scala | 5 +++ 2 files changed, 64 insertions(+) create mode 100644 tests/pos-macros/i9254/Macros_1.scala create mode 100644 tests/pos-macros/i9254/Test_2.scala diff --git a/tests/pos-macros/i9254/Macros_1.scala b/tests/pos-macros/i9254/Macros_1.scala new file mode 100644 index 000000000000..69a78b865d6f --- /dev/null +++ b/tests/pos-macros/i9254/Macros_1.scala @@ -0,0 +1,59 @@ +package cps + +import scala.quoted._ + +trait CpsMonad[F[_]] + +trait ComputationBound[T] + +implicit object ComputationBoundMonad extends CpsMonad[ComputationBound] + +inline def async[F[_]](using am:CpsMonad[F]): Async.InferAsyncArg[F] = + new Async.InferAsyncArg[F] + +object PFHelper { + def create[X,Y](x:Boolean):PartialFunction[X,Y] = ??? +} + +object Async { + + class InferAsyncArg[F[_]](using am:CpsMonad[F]) { + + inline def apply[T](inline expr: T):Unit = + ${ + Async.transformImpl[F,T]('expr) + } + + } + + def transformImpl[F[_]:Type,T:Type](f: Expr[T])(using Quotes): Expr[Unit] = + import quotes.reflect._ + + def uninline(t:Term):Term = + t match + case Inlined(_,_,x) => uninline(x) + case _ => t + + val fu = uninline(f.asTerm) + fu match + case Block(_,Apply(TypeApply(Select(q,n),tparams),List(param))) => + param.tpe match + case AppliedType(tp,tparams1) => + val fromTypeOrBounds = tparams1.head + val fromType = fromTypeOrBounds match + case bounds: TypeBounds => bounds.low + case tp: TypeRepr => tp + case np: NoPrefix => ??? + val toType = tparams1.tail.head + val fType = TypeRepr.of[F] + val toWrapped = fType.appliedTo(toType) + val helper = '{ cps.PFHelper }.asTerm + val helperSelect = Select.unique(helper,"create") + val createPF = Apply( + TypeApply(helperSelect,List(Inferred(fromType),Inferred(toWrapped))), + List(Literal(BooleanConstant(true))) + ) + val createPfApply = Apply(Select.unique(createPF,"apply"),List(Literal(IntConstant(1)))) + Block(List(createPfApply),Literal(UnitConstant())).asExpr.asInstanceOf[Expr[Unit]] + +} diff --git a/tests/pos-macros/i9254/Test_2.scala b/tests/pos-macros/i9254/Test_2.scala new file mode 100644 index 000000000000..102bfe6ae958 --- /dev/null +++ b/tests/pos-macros/i9254/Test_2.scala @@ -0,0 +1,5 @@ +package cps + +val c = async[ComputationBound]{ + List(1,2,3,4).collectFirst{ case x if x > 0 => x > 3 } +}