diff --git a/community-build/community-projects/scalatest b/community-build/community-projects/scalatest index d0a6e95ee50d..8e59b4800d4f 160000 --- a/community-build/community-projects/scalatest +++ b/community-build/community-projects/scalatest @@ -1 +1 @@ -Subproject commit d0a6e95ee50d6a73eb62dc7c44e980009b63a1dc +Subproject commit 8e59b4800d4fb247e78a82314afec2ea233325e8 diff --git a/community-build/community-projects/stdLib213 b/community-build/community-projects/stdLib213 index b7f2511439d1..4cd834f7e4bc 160000 --- a/community-build/community-projects/stdLib213 +++ b/community-build/community-projects/stdLib213 @@ -1 +1 @@ -Subproject commit b7f2511439d14b298e26147ac7aaa02eedb91c25 +Subproject commit 4cd834f7e4bc48482c2d98c0d9dca3d022650237 diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 5a9bbc5eb84e..bc72b843fd75 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -134,7 +134,7 @@ class ScalaSettings extends Settings.SettingGroup { val YprintDebug: Setting[Boolean] = BooleanSetting("-Yprint-debug", "when printing trees, print some extra information useful for debugging.") val YprintDebugOwners: Setting[Boolean] = BooleanSetting("-Yprint-debug-owners", "when printing trees, print owners of definitions.") val YshowPrintErrors: Setting[Boolean] = BooleanSetting("-Yshow-print-errors", "don't suppress exceptions thrown during tree printing.") - val YshowRawQuoteTrees: Setting[Boolean] = BooleanSetting("-Yshow-raw-tree", "don't remove quote artifacts") + val YshowRawQuoteTrees: Setting[Boolean] = BooleanSetting("-Yshow-raw-quote-tree", "don't remove quote artifacts") val YtestPickler: Setting[Boolean] = BooleanSetting("-Ytest-pickler", "self-test for pickling functionality; should be used with -Ystop-after:pickler") val YcheckReentrant: Setting[Boolean] = BooleanSetting("-Ycheck-reentrant", "check that compiled program does not contain vars that can be accessed from a global root.") val YdropComments: Setting[Boolean] = BooleanSetting("-Ydrop-comments", "Drop comments when scanning source files.") diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 8f17da8500de..27cf7e18a8fc 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -745,15 +745,26 @@ class Definitions { lazy val QuotedMatchingBindingType: TypeRef = ctx.requiredClassRef("scala.quoted.matching.Bind") def QuotedMatchingBindingClass(implicit ctx: Context): ClassSymbol = QuotedMatchingBindingType.symbol.asClass - def Unpickler_unpickleExpr: TermSymbol = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleExpr") - def Unpickler_liftedExpr: TermSymbol = ctx.requiredMethod("scala.runtime.quoted.Unpickler.liftedExpr") - def Unpickler_unpickleType: TermSymbol = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType") + lazy val UnpicklerModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.quoted.Unpickler") + def UnpicklerModule(implicit ctx: Context): Symbol = UnpicklerModuleRef.symbol + lazy val UnpicklerType: TypeRef = ctx.requiredClassRef("scala.runtime.quoted.Unpickler") + def UnpicklerClass(implicit ctx: Context): ClassSymbol = UnpicklerType.symbol.asClass + + lazy val Unpickler_unpickleExprR: TermRef = UnpicklerModule.requiredMethodRef("unpickleExpr") + def Unpickler_unpickleExpr: Symbol = Unpickler_unpickleExprR.symbol + lazy val Unpickler_liftedExprR: TermRef = UnpicklerModule.requiredMethodRef("liftedExpr") + def Unpickler_liftedExpr: Symbol = Unpickler_liftedExprR.symbol + lazy val Unpickler_unpickleTypeR: TermRef = UnpicklerModule.requiredMethodRef("unpickleType") + def Unpickler_unpickleType: Symbol = Unpickler_unpickleTypeR.symbol lazy val TastyReflectionType: TypeRef = ctx.requiredClassRef("scala.tasty.Reflection") def TastyReflectionClass(implicit ctx: Context): ClassSymbol = TastyReflectionType.symbol.asClass - lazy val TastyReflectionModule: TermSymbol = ctx.requiredModule("scala.tasty.Reflection") - lazy val TastyReflection_macroContext: TermSymbol = TastyReflectionModule.requiredMethod("macroContext") + lazy val StagingContextType: TypeRef = ctx.requiredClassRef("scala.quoted.StagingContext") + def StagingContextClass(implicit ctx: Context): ClassSymbol = StagingContextType.symbol.asClass + + lazy val StagingContextModule: TermSymbol = ctx.requiredModule("scala.quoted.StagingContext") + lazy val StagingContext_macroContext: TermSymbol = StagingContextModule.requiredMethod("macroContext") lazy val EqlType: TypeRef = ctx.requiredClassRef("scala.Eql") def EqlClass(implicit ctx: Context): ClassSymbol = EqlType.symbol.asClass diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 19e8f23e6ae0..202f20752a38 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -34,40 +34,46 @@ object PickledQuotes { /** Transform the expression into its fully spliced Tree */ def quotedExprToTree[T](expr: quoted.Expr[T])(implicit ctx: Context): Tree = expr match { - case expr: TastyExpr[_] => - val unpickled = unpickleExpr(expr) - val force = new TreeTraverser { - def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = traverseChildren(tree) - } - force.traverse(unpickled) - unpickled case expr: LiftedExpr[T] => expr.value match { case value: Class[_] => ref(defn.Predef_classOf).appliedToType(classToType(value)) case value => Literal(Constant(value)) } - case expr: TastyTreeExpr[Tree] @unchecked => healOwner(expr.tree) + case expr: TastyTreeExpr[Tree] @unchecked => + if (contextId != expr.ctxId) + throw new scala.quoted.QuoteError( + """Quote used outside of the `Staging` context where it was defined. + |This usualy indicated that a `run` was called within another `run` or a macro. + """.stripMargin) + healOwner(expr.tree) case expr: FunctionAppliedTo[_] => functionAppliedTo(quotedExprToTree(expr.f), expr.args.map(arg => quotedExprToTree(arg)).toList) } /** Transform the expression into its fully spliced TypeTree */ def quotedTypeToTree(expr: quoted.Type[_])(implicit ctx: Context): Tree = expr match { - case expr: TastyType[_] => unpickleType(expr) case expr: TaggedType[_] => classTagToTypeTree(expr.ct) case expr: TreeType[Tree] @unchecked => healOwner(expr.typeTree) } /** Unpickle the tree contained in the TastyExpr */ - private def unpickleExpr(expr: TastyExpr[_])(implicit ctx: Context): Tree = { - val tastyBytes = TastyString.unpickle(expr.tasty) - unpickle(tastyBytes, expr.args, isType = false)(ctx.addMode(Mode.ReadPositions)) + def unpickleExpr(tasty: scala.runtime.quoted.Unpickler.Pickled, args: Seq[Any])(implicit ctx: Context): Tree = { + val tastyBytes = TastyString.unpickle(tasty) + val unpickled = unpickle(tastyBytes, args, isType = false)(ctx.addMode(Mode.ReadPositions)) + force.traverse(unpickled) + unpickled } /** Unpickle the tree contained in the TastyType */ - private def unpickleType(ttpe: TastyType[_])(implicit ctx: Context): Tree = { - val tastyBytes = TastyString.unpickle(ttpe.tasty) - unpickle(tastyBytes, ttpe.args, isType = true)(ctx.addMode(Mode.ReadPositions)) + def unpickleType(tasty: scala.runtime.quoted.Unpickler.Pickled, args: Seq[Any])(implicit ctx: Context): Tree = { + val tastyBytes = TastyString.unpickle(tasty) + val unpickled = unpickle(tastyBytes, args, isType = true)(ctx.addMode(Mode.ReadPositions)) + force.traverse(unpickled) + unpickled + } + + private def force = new TreeTraverser { + def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = traverseChildren(tree) } // TASTY picklingtests/pos/quoteTest.scala @@ -193,4 +199,12 @@ object PickledQuotes { case _ => tree } } + + /** Id of the current compilation (macros) or Expr[_] run */ + def contextId(implicit ctx: Context): Int = { + def root(ctx: Context): Context = + if (ctx.outer != NoContext) root(ctx.outer) else ctx + root(ctx).hashCode + } + } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 7184b368af62..7e474eb9de4e 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -31,6 +31,7 @@ import scala.collection.mutable.ListBuffer import scala.collection.mutable import config.Printers.pickling import core.quoted.PickledQuotes +import core.quoted.Quoted import scala.quoted import scala.quoted.Types.TreeType @@ -1272,7 +1273,7 @@ class TreeUnpickler(reader: TastyReader, val args = until(end)(readTerm()) val splice = splices(idx) def wrap(arg: Tree) = - if (arg.isTerm) new TastyTreeExpr(arg) + if (arg.isTerm) new TastyTreeExpr(arg, PickledQuotes.contextId) else new TreeType(arg) val reifiedArgs = args.map(wrap) val filled = if (isType) { diff --git a/compiler/src/dotty/tools/dotc/quoted/ExprCompilationUnit.scala b/compiler/src/dotty/tools/dotc/quoted/ExprCompilationUnit.scala index 0dffbb82b7a3..32cd6b39cfef 100644 --- a/compiler/src/dotty/tools/dotc/quoted/ExprCompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/quoted/ExprCompilationUnit.scala @@ -3,9 +3,7 @@ package dotty.tools.dotc.quoted import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.util.NoSource -import scala.quoted.Expr +import scala.quoted.{Expr, StagingContext} /* Compilation unit containing the contents of a quoted expression */ -class ExprCompilationUnit(val expr: Expr[_]) extends CompilationUnit(NoSource) { - override def toString: String = s"Expr($expr)" -} +class ExprCompilationUnit(val expr: StagingContext => Expr[Any]) extends CompilationUnit(NoSource) diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala index 490b11f683ad..53dfa4550792 100644 --- a/compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala @@ -17,9 +17,9 @@ import dotty.tools.dotc.core.quoted.PickledQuotes import dotty.tools.dotc.transform.Staging import dotty.tools.dotc.util.Spans.Span import dotty.tools.dotc.util.SourceFile -import dotty.tools.io.{Path, VirtualFile} +import dotty.tools.io.{VirtualFile} -import scala.quoted.{Expr, Type} +import scala.quoted.{Expr, StagingContext, Type} /** Compiler that takes the contents of a quoted expression `expr` and produces * a class file with `class ' { def apply: Object = expr }`. @@ -50,7 +50,7 @@ class QuoteCompiler extends Compiler { case exprUnit: ExprCompilationUnit => val tree = if (putInClass) inClass(exprUnit.expr) - else PickledQuotes.quotedExprToTree(exprUnit.expr) + else unpickleExpr(exprUnit.expr) val source = SourceFile.virtual("", "") CompilationUnit(source, tree, forceTrees = true) case typeUnit: TypeCompilationUnit => @@ -61,11 +61,16 @@ class QuoteCompiler extends Compiler { } } + private def unpickleExpr(code: StagingContext => Expr[Any])(implicit ctx: Context) = { + val expr = code(new StagingImpl) + PickledQuotes.quotedExprToTree(expr) + } + /** Places the contents of expr in a compilable tree for a class * with the following format. * `package __root__ { class ' { def apply: Any = } }` */ - private def inClass(expr: Expr[_])(implicit ctx: Context): Tree = { + private def inClass(code: StagingContext => Expr[_])(implicit ctx: Context): Tree = { val pos = Span(0) val assocFile = new VirtualFile("") @@ -74,7 +79,7 @@ class QuoteCompiler extends Compiler { cls.enter(ctx.newDefaultConstructor(cls), EmptyScope) val meth = ctx.newSymbol(cls, nme.apply, Method, ExprType(defn.AnyType), coord = pos).entered - val quoted = PickledQuotes.quotedExprToTree(expr)(ctx.withOwner(meth)) + val quoted = unpickleExpr(code)(ctx.withOwner(meth)) val run = DefDef(meth, quoted) val classTree = ClassDef(cls, DefDef(cls.primaryConstructor.asTerm), run :: Nil) @@ -85,7 +90,7 @@ class QuoteCompiler extends Compiler { } class ExprRun(comp: Compiler, ictx: Context) extends Run(comp, ictx) { - def compileExpr(expr: Expr[_]): Unit = { + def compileExpr(expr: StagingContext => Expr[_]): Unit = { val units = new ExprCompilationUnit(expr) :: Nil compileUnits(units) } diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala new file mode 100644 index 000000000000..2794cd257bbb --- /dev/null +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala @@ -0,0 +1,35 @@ +package dotty.tools.dotc.quoted + +import dotty.tools.dotc.core.Contexts._ +import dotty.tools.dotc.core.quoted.PickledQuotes +import dotty.tools.dotc.tastyreflect.ReflectionImpl + +import scala.quoted.{Expr, Type} +import scala.runtime.quoted.Unpickler.Pickled + +class StagingImpl(implicit ctx: Context) extends scala.quoted.StagingContext { + + def unpickleExpr[T](repr: Pickled, args: Seq[Any]): Expr[T] = + new scala.quoted.Exprs.TastyTreeExpr(PickledQuotes.unpickleExpr(repr, args), PickledQuotes.contextId).asInstanceOf[Expr[T]] + + def unpickleType[T](repr: Pickled, args: Seq[Any]): Type[T] = + new scala.quoted.Types.TreeType(PickledQuotes.unpickleType(repr, args)).asInstanceOf[Type[T]] + + def show[T](expr: Expr[T]): String = { + val tree = PickledQuotes.quotedExprToTree(expr) + // TODO freshen names + val tree1 = + if (ctx.settings.YshowRawQuoteTrees.value) tree else (new TreeCleaner).transform(tree) + new ReflectionImpl(ctx).showSourceCode.showTree(tree1) + } + + def show[T](tpe: Type[T]): String = { + val tree = PickledQuotes.quotedTypeToTree(tpe) + // TODO freshen names + val tree1 = if (ctx.settings.YshowRawQuoteTrees.value) tree else (new TreeCleaner).transform(tree) + new ReflectionImpl(ctx).showSourceCode.showTypeOrBoundsTree(tree1) + } + + val reflection: scala.tasty.Reflection = new ReflectionImpl(ctx) + +} diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteDecompiler.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteDecompiler.scala deleted file mode 100644 index 431df7aba75f..000000000000 --- a/compiler/src/dotty/tools/dotc/quoted/QuoteDecompiler.scala +++ /dev/null @@ -1,19 +0,0 @@ -package dotty.tools.dotc.quoted - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Phases.Phase - -/** Compiler that takes the contents of a quoted expression (or type) and outputs it's tree. */ -class QuoteDecompiler(output: tpd.Tree => Context => Unit) extends QuoteCompiler { - override def phases: List[List[Phase]] = List( - List(new QuotedFrontend(putInClass = false)), // Create class from Expr - List(new RefreshNames), - List(new QuoteTreeOutput(output)) - ) - - class QuoteTreeOutput(output: tpd.Tree => Context => Unit) extends Phase { - override def phaseName: String = "quoteOutput" - override def run(implicit ctx: Context): Unit = output(ctx.compilationUnit.tpdTree)(ctx) - } -} diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala index adddbb7d94d9..ad10056e662b 100644 --- a/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala @@ -1,16 +1,16 @@ package dotty.tools.dotc.quoted -import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.Driver import dotty.tools.dotc.core.Contexts.{Context, ContextBase, FreshContext} -import dotty.tools.dotc.tastyreflect.ReflectionImpl import dotty.tools.io.{AbstractFile, Directory, PlainDirectory, VirtualDirectory} import dotty.tools.repl.AbstractFileClassLoader import dotty.tools.dotc.reporting._ -import scala.quoted.{Expr, Type} +import scala.quoted.{Expr, StagingContext} import scala.quoted.Toolbox import java.net.URLClassLoader +import dotty.tools.dotc.core.quoted.PickledQuotes + /** Driver to compile quoted code * * @param appClassloader classloader of the application that generated the quotes @@ -20,7 +20,7 @@ class QuoteDriver(appClassloader: ClassLoader) extends Driver { private[this] val contextBase: ContextBase = new ContextBase - def run[T](expr: Expr[T], settings: Toolbox.Settings): T = { + def run[T](code: StagingContext => Expr[T], settings: Toolbox.Settings): T = { val outDir: AbstractFile = settings.outDir match { case Some(out) => val dir = Directory(out) @@ -34,7 +34,7 @@ class QuoteDriver(appClassloader: ClassLoader) extends Driver { val ctx = setToolboxSettings(ctx0.fresh.setSetting(ctx0.settings.outputDir, outDir), settings) val driver = new QuoteCompiler - driver.newRun(ctx).compileExpr(expr) + driver.newRun(ctx).compileExpr(code) assert(!ctx.reporter.hasErrors) @@ -47,44 +47,6 @@ class QuoteDriver(appClassloader: ClassLoader) extends Driver { method.invoke(inst).asInstanceOf[T] } - private def doShow(tree: Tree, ctx: Context): String = { - implicit val c: Context = ctx - val tree1 = - if (ctx.settings.YshowRawQuoteTrees.value) tree - else (new TreeCleaner).transform(tree) - ReflectionImpl.showTree(tree1) - } - - def show(expr: Expr[_], settings: Toolbox.Settings): String = - withTree(expr, doShow, settings) - - def show(tpe: Type[_], settings: Toolbox.Settings): String = - withTypeTree(tpe, doShow, settings) - - def withTree[T](expr: Expr[_], f: (Tree, Context) => T, settings: Toolbox.Settings): T = { - val ctx = setToolboxSettings(setup(settings.compilerArgs.toArray :+ "dummy.scala", initCtx.fresh)._2.fresh, settings) - - var output: Option[T] = None - def registerTree(tree: tpd.Tree)(ctx: Context): Unit = { - assert(output.isEmpty) - output = Some(f(tree, ctx)) - } - new QuoteDecompiler(registerTree).newRun(ctx).compileExpr(expr) - output.getOrElse(throw new Exception("Could not extract " + expr)) - } - - def withTypeTree[T](tpe: Type[_], f: (TypTree, Context) => T, settings: Toolbox.Settings): T = { - val ctx = setToolboxSettings(setup(settings.compilerArgs.toArray :+ "dummy.scala", initCtx.fresh)._2.fresh, settings) - - var output: Option[T] = None - def registerTree(tree: tpd.Tree)(ctx: Context): Unit = { - assert(output.isEmpty) - output = Some(f(tree.asInstanceOf[TypTree], ctx)) - } - new QuoteDecompiler(registerTree).newRun(ctx).compileType(tpe) - output.getOrElse(throw new Exception("Could not extract " + tpe)) - } - override def initCtx: Context = { val ictx = contextBase.initialCtx ictx.settings.classpath.update(QuoteDriver.currentClasspath(appClassloader))(ictx) diff --git a/compiler/src/dotty/tools/dotc/quoted/RefreshNames.scala b/compiler/src/dotty/tools/dotc/quoted/RefreshNames.scala deleted file mode 100644 index 4b00eb00079e..000000000000 --- a/compiler/src/dotty/tools/dotc/quoted/RefreshNames.scala +++ /dev/null @@ -1,38 +0,0 @@ -package dotty.tools.dotc.quoted - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.DenotTransformers.SymTransformer -import dotty.tools.dotc.core.Flags._ -import dotty.tools.dotc.core.NameKinds.{NumberedInfo, UniqueName} -import dotty.tools.dotc.core.SymDenotations.SymDenotation -import dotty.tools.dotc.transform.MegaPhase.MiniPhase - -/** Refreshes local names starting from the second use of the name. Intended for readability of the pretty printed code. */ -class RefreshNames extends MiniPhase with SymTransformer { - - def phaseName: String = "RefreshNames" - - override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context): tpd.Tree = - tpd.ValDef(tree.symbol.asTerm, tree.rhs) - - override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = - tpd.DefDef(tree.symbol.asTerm, tree.rhs) - - override def transformTypeDef(tree: tpd.TypeDef)(implicit ctx: Context): tpd.Tree = { - val newTypeDef = tpd.TypeDef(tree.symbol.asType) - // keep rhs to keep `type T = ...` instead of `type T >: ... <: ...` - cpy.TypeDef(newTypeDef)(rhs = tree.rhs) - } - - def transformSym(ref: SymDenotation)(implicit ctx: Context): SymDenotation = { - if (ref.is(Package) || ref.isClass || ref.owner != ctx.owner || ref.is(Param)) ref - else { - val newName = UniqueName.fresh(ref.symbol.name.toTermName) - newName.info match { - case info: NumberedInfo if info.num == 1 => ref // Keep the first reference as is to avoid renaming if the code has no duplicated names - case _ => ref.copySymDenotation(name = if (ref.symbol.isType) newName.toTypeName else newName) - } - } - } -} diff --git a/compiler/src/dotty/tools/dotc/quoted/ToolboxImpl.scala b/compiler/src/dotty/tools/dotc/quoted/ToolboxImpl.scala index 77a1e26b8db1..6cf2966679f4 100644 --- a/compiler/src/dotty/tools/dotc/quoted/ToolboxImpl.scala +++ b/compiler/src/dotty/tools/dotc/quoted/ToolboxImpl.scala @@ -1,13 +1,9 @@ package dotty.tools.dotc.quoted -import dotty.tools.dotc.ast.tpd - import scala.quoted._ -import scala.quoted.Exprs.{LiftedExpr, TastyTreeExpr} /** Default runners for quoted expressions */ object ToolboxImpl { - import tpd._ /** Create a new instance of the toolbox using the the classloader of the application. * @@ -19,17 +15,11 @@ object ToolboxImpl { private[this] val driver: QuoteDriver = new QuoteDriver(appClassloader) - def run[T](expr: Expr[T]): T = expr match { - case expr: LiftedExpr[T] => - expr.value - case expr: TastyTreeExpr[Tree] @unchecked => - throw new Exception("Cannot call `Expr.run` on an `Expr` that comes from a macro argument.") - case _ => - synchronized(driver.run(expr, settings)) + protected def runImpl[T](code: StagingContext => Expr[T]): T = { + // TODO check for recursion and throw if possible (i.e. run inside a run) + synchronized(driver.run(code, settings)) } - def show[T](expr: Expr[T]): String = synchronized(driver.show(expr, settings)) - def show[T](tpe: Type[T]): String = synchronized(driver.show(tpe, settings)) } diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 1da497b19109..ccd2b85c910e 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -165,7 +165,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( case Some(l) => l == level || level == -1 && ( - sym == defn.TastyReflection_macroContext || + sym == defn.StagingContext_macroContext || // here we assume that Splicer.canBeSpliced was true before going to level -1, // this implies that all non-inline arguments are quoted and that the following two cases are checked // on inline parameters or type parameters. diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 60f89f5d1815..95fba29eac65 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -17,12 +17,14 @@ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.{NameKinds, TypeErasure} import dotty.tools.dotc.core.Constants.Constant +import dotty.tools.dotc.quoted.StagingImpl import dotty.tools.dotc.tastyreflect.ReflectionImpl import scala.util.control.NonFatal import dotty.tools.dotc.util.SourcePosition import dotty.tools.repl.AbstractFileClassLoader +import scala.quoted.StagingContext import scala.reflect.ClassTag /** Utility class to splice quoted expressions */ @@ -102,7 +104,7 @@ object Splicer { } protected def interpretQuote(tree: Tree)(implicit env: Env): Object = - new scala.quoted.Exprs.TastyTreeExpr(Inlined(EmptyTree, Nil, tree).withSpan(tree.span)) + new scala.quoted.Exprs.TastyTreeExpr(Inlined(EmptyTree, Nil, tree).withSpan(tree.span), PickledQuotes.contextId) protected def interpretTypeQuote(tree: Tree)(implicit env: Env): Object = new scala.quoted.Types.TreeType(tree) @@ -113,7 +115,10 @@ object Splicer { protected def interpretVarargs(args: List[Object])(implicit env: Env): Object = args.toSeq - protected def interpretTastyContext()(implicit env: Env): Object = ReflectionImpl(ctx, pos) + protected def interpretStaging()(implicit env: Env): Object = + new StagingImpl { + override val reflection = ReflectionImpl(ctx, pos) + } protected def interpretStaticMethodCall(moduleClass: Symbol, fn: Symbol, args: => List[Object])(implicit env: Env): Object = { val (inst, clazz) = @@ -285,7 +290,7 @@ object Splicer { protected def interpretLiteral(value: Any)(implicit env: Env): Boolean = true protected def interpretVarargs(args: List[Boolean])(implicit env: Env): Boolean = args.forall(identity) protected def interpretTastyContext()(implicit env: Env): Boolean = true - protected def interpretQuoteContext()(implicit env: Env): Boolean = true + protected def interpretStaging()(implicit env: Env): Boolean = true protected def interpretStaticMethodCall(module: Symbol, fn: Symbol, args: => List[Boolean])(implicit env: Env): Boolean = args.forall(identity) protected def interpretModuleAccess(fn: Symbol)(implicit env: Env): Boolean = true protected def interpretNew(fn: Symbol, args: => List[Boolean])(implicit env: Env): Boolean = args.forall(identity) @@ -307,13 +312,13 @@ object Splicer { protected def interpretTypeQuote(tree: Tree)(implicit env: Env): Result protected def interpretLiteral(value: Any)(implicit env: Env): Result protected def interpretVarargs(args: List[Result])(implicit env: Env): Result - protected def interpretTastyContext()(implicit env: Env): Result + protected def interpretStaging()(implicit env: Env): Result protected def interpretStaticMethodCall(module: Symbol, fn: Symbol, args: => List[Result])(implicit env: Env): Result protected def interpretModuleAccess(fn: Symbol)(implicit env: Env): Result protected def interpretNew(fn: Symbol, args: => List[Result])(implicit env: Env): Result protected def unexpectedTree(tree: Tree)(implicit env: Env): Result - protected final def interpretTree(tree: Tree)(implicit env: Env): Result = tree match { + protected final def interpretTree(tree: Tree)(implicit env: Env): Result = normalized(tree) match { case Apply(TypeApply(fn, _), quoted :: Nil) if fn.symbol == defn.InternalQuoted_exprQuote => val quoted1 = quoted match { case quoted: Ident if quoted.symbol.is(InlineByNameProxy) => @@ -330,8 +335,8 @@ object Splicer { case Literal(Constant(value)) => interpretLiteral(value) - case _ if tree.symbol == defn.TastyReflection_macroContext => - interpretTastyContext() + case _ if tree.symbol == defn.StagingContext_macroContext => + interpretStaging() case Call(fn, args) => if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package)) { @@ -349,7 +354,20 @@ object Splicer { } else if (tree.symbol.is(InlineProxy)) { interpretTree(tree.symbol.defTree.asInstanceOf[ValOrDefDef].rhs) } else { - unexpectedTree(tree) + fn match { + case fn @ Select(Call(fn0, args0), _) if fn0.symbol.isStatic && fn.symbol.info.isImplicitMethod => + // Call implicit function type direct method + interpretStaticMethodCall(fn.symbol.owner, fn0.symbol, (args0 ::: args).map(arg => interpretTree(arg))) + case fn @ Select(Block(stats, Call(fn0, args0)), _) if fn0.symbol.isStatic && fn.symbol.info.isImplicitMethod => + val newEnv = stats.foldLeft(env)((accEnv, stat) => stat match { + case stat: ValDef if stat.symbol.is(Synthetic) => + accEnv.updated(stat.name, interpretTree(stat.rhs)(accEnv)) + case stat => return unexpectedTree(stat) + }) + interpretStaticMethodCall(fn.symbol.owner, fn0.symbol, (args0 ::: args).map(arg => interpretTree(arg)(newEnv)))(newEnv) + case _ => + unexpectedTree(tree) + } } // Interpret `foo(j = x, i = y)` which it is expanded to @@ -375,7 +393,14 @@ object Splicer { unexpectedTree(tree) } - object Call { + private def normalized(tree: Tree): Tree = tree match { + case Apply(Select(Block(stats, expr), nme.apply), args) if defn.isImplicitFunctionType(expr.tpe.widenDealias) => + // To allow Call.unapply to collect all the arguments and apply the implicit function type directly + Block(stats, expr.select(tree.symbol).appliedToArgs(args)) + case _ => tree + } + + private object Call { def unapply(arg: Tree): Option[(RefTree, List[Tree])] = arg match { case Select(Call(fn, args), nme.apply) if defn.isImplicitFunctionType(fn.tpe.widenDealias.finalResultType) => Some((fn, args)) diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 1fa53e79582a..1dee6c4c7e9c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -699,8 +699,8 @@ trait Implicits { self: Typer => } } - def synthesizedTastyContext(formal: Type): Tree = - if (ctx.inInlineMethod || enclosingInlineds.nonEmpty) ref(defn.TastyReflection_macroContext) + def synthesizedStaging(formal: Type): Tree = + if (ctx.inInlineMethod || enclosingInlineds.nonEmpty) ref(defn.StagingContext_macroContext) else EmptyTree /** If `formal` is of the form Eql[T, U], try to synthesize an @@ -820,7 +820,7 @@ trait Implicits { self: Typer => trySpecialCase(defn.ClassTagClass, synthesizedClassTag, trySpecialCase(defn.QuotedTypeClass, synthesizedTypeTag, trySpecialCase(defn.GenericClass, synthesizedGeneric, - trySpecialCase(defn.TastyReflectionClass, synthesizedTastyContext, + trySpecialCase(defn.StagingContextClass, synthesizedStaging, trySpecialCase(defn.EqlClass, synthesizedEq, trySpecialCase(defn.ValueOfClass, synthesizedValueOf, failed)))))) } diff --git a/docs/docs/reference/other-new-features/principled-meta-programming.md b/docs/docs/reference/other-new-features/principled-meta-programming.md index 8c9b2899da5a..1f0a63bb8767 100644 --- a/docs/docs/reference/other-new-features/principled-meta-programming.md +++ b/docs/docs/reference/other-new-features/principled-meta-programming.md @@ -29,7 +29,7 @@ prints it again in an error message if it evaluates to `false`. inline def assert(expr: => Boolean): Unit = ${ assertImpl('{ expr }) } - def assertImpl(expr: Expr[Boolean]) = '{ + def assertImpl(expr: Expr[Boolean])(implicit staging: StagingContext): Expr[Unit] = '{ if !(${ expr }) then throw new AssertionError(s"failed assertion: ${${ showExpr(expr) }}") } @@ -63,6 +63,12 @@ expressions `e` and types `T` we have: ${'[T]} = T '[${T}] = T +An `implicit staging: StagingContext` is also provided to the macro which is used to evaluate the +quotes. It is implicitly provided by in `inline def`s. To reduce syntactic overhead, we can +use instead: + + def assertImpl(expr: Expr[Boolean]): Staged[Unit] + ### Types for Quotations The type signatures of quotes and splices can be described using @@ -322,7 +328,7 @@ program that calls `assert`. inline def assert(expr: => Boolean): Unit = ${ assertImpl('expr) } - def assertImpl(expr: Expr[Boolean]) = + def assertImpl(expr: Expr[Boolean])(implicit staging: StagingContext): Expr[Unit] = '{ if !($expr) then throw new AssertionError(s"failed assertion: ${$expr}") } } @@ -383,7 +389,7 @@ statically known exponent: ```scala inline def power(inline n: Int, x: Double) = ${ powerCode(n, 'x) } - private def powerCode(n: Int, x: Expr[Double]): Expr[Double] = + private def powerCode(n: Int, x: Expr[Double]): Staged[Double] = if (n == 0) '{ 1.0 } else if (n == 1) x else if (n % 2 == 0) '{ val y = $x * $x; ${ powerCode(n / 2, 'y) } } @@ -447,13 +453,19 @@ we currently impose the following restrictions on the use of splices. 4. A macro method is effectively final and it may override no other method. The framework as discussed so far allows code to be staged, i.e. be prepared -to be executed at a later stage. To run that code, there is another method -in class `Expr` called `run`. Note that `$` and `run` both map from `Expr[T]` +to be executed at a later stage. To run that code, there is method prvided in +class `Toolbox` called `run`. Note that `$` and `run` both map from `Expr[T]` to `T` but only `$` is subject to the PCP, whereas `run` is just a normal method. + val tb: Toolbox = Toolbox.make() + tb.run('{ 1 + 2 }) +``` + +Note that `$` and `run` both map from `Expr[T]` to `T` but only `$` is subject +to the PCP, whereas `run` is just a normal method. A runtime `Staging` context +is provided implicitly to enable quotation within its context. ```scala - sealed abstract class Expr[T] { - def run given (toolbox: Toolbox): T // run staged code - def show given (toolbox: Toolbox): String // show staged code + trait Toolbox { + def run[T](code: implicit StagingContext => Expr[T]): T } ``` @@ -476,10 +488,11 @@ to the status of pattern guards in Scala, which are also required, but not verif There is also a problem with `run` in splices. Consider the following expression: ```scala - '{ (x: Int) => ${ ('x).run; 1 } } + val tb = Toolbox.make() + '{ (x: Int) => ${ tb.run('x); 1 } } ``` This is again phase correct, but will lead us into trouble. Indeed, evaluating the splice will reduce the -expression `('x).run` to `x`. But then the result +expression `tb.run('x)` to `x`. But then the result ```scala '{ (x: Int) => ${ x; 1 } } ``` @@ -539,7 +552,7 @@ The `toExpr` extension method is defined in package `quoted`: package quoted implied LiftingOps { - def (x: T) toExpr[T] given (ev: Liftable[T]): Expr[T] = ev.toExpr(x) + def (x: T) toExpr[T] given (ev: Liftable[T]): Staged[T] = ev.toExpr(x) } ``` The extension says that values of types implementing the `Liftable` type class can be @@ -557,7 +570,7 @@ knowing anything about the representation of `Expr` trees. For instance, here is a possible instance of `Liftable[Boolean]`: ```scala implied for Liftable[Boolean] { - def toExpr(b: Boolean) = if (b) '{ true } else '{ false } + def toExpr(b: Boolean): Staged[Boolean] = if (b) '{ true } else '{ false } } ``` Once we can lift bits, we can work our way up. For instance, here is a @@ -565,7 +578,7 @@ possible implementation of `Liftable[Int]` that does not use the underlying tree machinery: ```scala implied for Liftable[Int] { - def toExpr(n: Int): Expr[Int] = n match { + def toExpr(n: Int): Staged[Int] = n match { case Int.MinValue => '{ Int.MinValue } case _ if n < 0 => '{ - ${ toExpr(n) } } case 0 => '{ 0 } @@ -578,7 +591,7 @@ Since `Liftable` is a type class, its instances can be conditional. For example, a `List` is liftable if its element type is: ```scala implied [T: Liftable] for Liftable[List[T]] { - def toExpr(xs: List[T]): Expr[List[T]] = xs match { + def toExpr(xs: List[T]): Staged[List[T]] = xs match { case x :: xs1 => '{ ${ toExpr(x) } :: ${ toExpr(xs1) } } case Nil => '{ Nil: List[T] } } @@ -592,7 +605,7 @@ analogue of lifting. Using lifting, we can now give the missing definition of `showExpr` in the introductory example: ```scala - def showExpr[T](expr: Expr[T]): Expr[String] = { + def showExpr[T](expr: Expr[T]): Staged[String] = { val code = expr.show code.toExpr } diff --git a/library/src-2.x/scala/quoted/StagingContext.scala b/library/src-2.x/scala/quoted/StagingContext.scala new file mode 100644 index 000000000000..fb346d124a78 --- /dev/null +++ b/library/src-2.x/scala/quoted/StagingContext.scala @@ -0,0 +1,25 @@ +package scala.quoted + +import scala.tasty.Reflection + +import scala.annotation.{implicitAmbiguous, implicitNotFound} + +// TODO add @implicitAmbiguous("...") +// TODO add some fake default and give better error message in `Staging` compiler phase +@implicitNotFound("Could not find an implicit StagingContext.\nIf this is a method that returns an `Expr[T]` you can use `Staged[T]` instead.\n\nQuotedContex is provided inside of top level splices in `inline` macros or within a call to `Toolbox.run`.\n") +trait StagingContext extends scala.runtime.quoted.Unpickler { + def show[T](expr: Expr[T]): String + def show[T](tpe: Type[T]): String + + /** AST reflection API. Provides low level reflection capabilities on the definition of the TASTy trees. + * + * Waring: Using this API can break the static type safety of quotes and splices. + * Error will be thrown at reflection time. + */ + val reflection: Reflection +} + +object StagingContext { + /** Compiler `StagingContext` available in a top level `~` of an inline macro */ + implicit def macroContext: StagingContext = throw new Exception("Not in inline macro.") +} diff --git a/library/src/scala/quoted/Toolbox.scala b/library/src-2.x/scala/quoted/Toolbox.scala similarity index 84% rename from library/src/scala/quoted/Toolbox.scala rename to library/src-2.x/scala/quoted/Toolbox.scala index ee834bdf236c..8dee529e9ce9 100644 --- a/library/src/scala/quoted/Toolbox.scala +++ b/library/src-2.x/scala/quoted/Toolbox.scala @@ -1,12 +1,11 @@ package scala.quoted -import scala.annotation.implicitNotFound - -@implicitNotFound("Could not find implicit quoted.Toolbox.\n\nDefault toolbox can be instantiated with:\n `implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)`\n\n") trait Toolbox { - def run[T](expr: Expr[T]): T - def show[T](expr: Expr[T]): String - def show[T](tpe: Type[T]): String + def run[T](code: Staged[T]): T = runImpl(code) + protected def runImpl[T](code: StagingContext => Expr[T]): T // For Scala2 compat in ToolboxImpl + +// def show[T](code: Staged[T]): String = runImpl(ctx => { implicit val c: StagingContext = ctx; code(ctx).show.toExpr }) +// def show[T](code: StagedType[T]): String = runImpl(ctx => { implicit val c: StagingContext = ctx; code(ctx).show.toExpr }) } object Toolbox { diff --git a/library/src-2.x/scala/quoted/package.scala b/library/src-2.x/scala/quoted/package.scala new file mode 100644 index 000000000000..8a91767dabad --- /dev/null +++ b/library/src-2.x/scala/quoted/package.scala @@ -0,0 +1,13 @@ +package scala + +package object quoted { + + type Staged[T] = /*given*/ StagingContext => Expr[T] + + type StagedType[T] = /*given*/ StagingContext => Type[T] + + implicit class LiftExprOps[T](val x: T) extends AnyVal { + def toExpr(implicit ev: Liftable[T], st: StagingContext): Expr[T] = ev.toExpr(x) + } + +} diff --git a/library/src-3.x/scala/quoted/Toolbox.scala b/library/src-3.x/scala/quoted/Toolbox.scala new file mode 100644 index 000000000000..986ed7c09a18 --- /dev/null +++ b/library/src-3.x/scala/quoted/Toolbox.scala @@ -0,0 +1,62 @@ +package scala.quoted + +trait Toolbox { + def run[T](code: Staged[T]): T = runImpl(sc => code given sc) + protected def runImpl[T](code: StagingContext => Expr[T]): T // For Scala2 compat in ToolboxImpl + +// def show[T](code: Staged[T]): String = runImpl(ctx => { implicit val c: StagingContext = ctx; (code given ctx).show.toExpr }) +// def show[T](code: StagedType[T]): String = runImpl(ctx => { implicit val c: StagingContext = ctx; (code given ctx).show.toExpr }) +} + +object Toolbox { + + /** Create a new instance of the toolbox using the the classloader of the application. + * + * Usuage: + * ``` + * implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + * ``` + * + * @param appClassloader classloader of the application that generated the quotes + * @param settings toolbox settings + * @return A new instance of the toolbox + */ + def make(appClassloader: ClassLoader)(implicit settings: Settings): Toolbox = { + try { + val toolboxImplCls = appClassloader.loadClass("dotty.tools.dotc.quoted.ToolboxImpl") + val makeMeth = toolboxImplCls.getMethod("make", classOf[Settings], classOf[ClassLoader]) + makeMeth.invoke(null, settings, appClassloader).asInstanceOf[Toolbox] + } + catch { + case ex: ClassNotFoundException => + throw new ToolboxNotFoundException( + s"""Could not load the Toolbox class `${ex.getMessage}` from the JVM classpath. Make sure that the compiler is on the JVM classpath.""", + ex + ) + } + } + + /** Setting of the Toolbox instance. */ + case class Settings private (outDir: Option[String], showRawTree: Boolean, compilerArgs: List[String], color: Boolean) + + object Settings { + + implicit def default: Settings = make() + + /** Make toolbox settings + * @param outDir Output directory for the compiled quote. If set to None the output will be in memory + * @param color Print output with colors + * @param showRawTree Do not remove quote tree artifacts + * @param compilerArgs Compiler arguments. Use only if you know what you are doing. + */ + def make( // TODO avoid using default parameters (for binary compat) + color: Boolean = false, + showRawTree: Boolean = false, + outDir: Option[String] = None, + compilerArgs: List[String] = Nil + ): Settings = + new Settings(outDir, showRawTree, compilerArgs, color) + } + + class ToolboxNotFoundException(msg: String, cause: ClassNotFoundException) extends Exception(msg, cause) +} diff --git a/library/src-3.x/scala/quoted/Type.scala b/library/src-3.x/scala/quoted/Type.scala index 2ef786907296..30d0fa6be488 100644 --- a/library/src-3.x/scala/quoted/Type.scala +++ b/library/src-3.x/scala/quoted/Type.scala @@ -13,7 +13,7 @@ object Type { implicit class TypeOps[T](tpe: Type[T]) { /** Show a source code like representation of this type */ - def show(implicit toolbox: Toolbox): String = toolbox.show(tpe.asInstanceOf[Type[Any]]) + def show given StagingContext: String = the[StagingContext].show(tpe) } implicit def UnitTag: Type[Unit] = new TaggedType[Unit] diff --git a/library/src-3.x/scala/quoted/package.scala b/library/src-3.x/scala/quoted/package.scala index e96931214e41..5959c45eebdb 100644 --- a/library/src-3.x/scala/quoted/package.scala +++ b/library/src-3.x/scala/quoted/package.scala @@ -2,16 +2,20 @@ package scala package object quoted { + type Staged[T] = given StagingContext => Expr[T] + + type StagedType[T] = given StagingContext => Type[T] + object autolift { - implicit def autoToExpr[T: Liftable](x: T): Expr[T] = x.toExpr + implicit def autoToExpr[T: Liftable](x: T) given StagingContext: Expr[T] = x.toExpr } implicit class LiftExprOps[T](val x: T) extends AnyVal { - def toExpr(implicit ev: Liftable[T]): Expr[T] = ev.toExpr(x) + def toExpr(implicit ev: Liftable[T], st: StagingContext): Expr[T] = ev.toExpr(x) } implicit class ListOfExprOps[T](val list: List[Expr[T]]) extends AnyVal { - def toExprOfList(implicit ev: Type[T]): Expr[List[T]] = { + def toExprOfList(implicit ev: Type[T], st: StagingContext): Expr[List[T]] = { def rec(list: List[Expr[T]]): Expr[List[T]] = list match { case x :: xs => '{ ($x) :: ${rec(xs)} } case Nil => '{Nil} diff --git a/library/src-3.x/scala/testing/typeChecks.scala b/library/src-3.x/scala/testing/typeChecks.scala index a95c70a92137..82d22b74f172 100644 --- a/library/src-3.x/scala/testing/typeChecks.scala +++ b/library/src-3.x/scala/testing/typeChecks.scala @@ -5,7 +5,8 @@ import scala.tasty.Reflection inline def typeChecks(inline code: String): Boolean = ${ typeChecksImpl(code) } -private def typeChecksImpl(code: String)(implicit reflect: Reflection): Expr[Boolean] = { +private def typeChecksImpl(code: String) given StagingContext: Expr[Boolean] = { + val reflect = the[StagingContext].reflection import reflect._ typing.typeChecks(code).toExpr } diff --git a/library/src-non-bootstrapped/scala/quoted/StagingContext.scala b/library/src-non-bootstrapped/scala/quoted/StagingContext.scala new file mode 100644 index 000000000000..d14d0690bd36 --- /dev/null +++ b/library/src-non-bootstrapped/scala/quoted/StagingContext.scala @@ -0,0 +1,25 @@ +package scala.quoted + +import scala.tasty.Reflection + +import scala.annotation.{implicitAmbiguous, implicitNotFound} + +// TODO add @implicitAmbiguous("...") +// TODO add some fake default and give better error message in `Staging` compiler phase +@implicitNotFound("Could not find an implicit StagingContext.\nIf this is a method that returns an `Expr[T]` you can use `Staged[T]` instead.\n\nQuotedContex is provided inside of top level splices in `inline` macros or within a call to `Toolbox.run`.\n") +trait StagingContext extends scala.runtime.quoted.Unpickler { + def show[T](expr: Expr[T]): String + def show[T](tpe: Type[T]): String + + /** AST reflection API. Provides low level reflection capabilities on the definition of the TASTy trees. + * + * Waring: Using this API can break the static type safety of quotes and splices. + * Error will be thrown at reflection time. + */ + val reflection: Reflection +} + +object StagingContext { + /** Compiler `StagingContext` available in a top level `~` of an inline macro */ + def macroContext: StagingContext = throw new Exception("Not in inline macro.") +} diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 79259718051c..4849059f769f 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -1,24 +1,15 @@ package scala.quoted -import scala.runtime.quoted.Unpickler.Pickled - -sealed abstract class Expr[+T] { - - /** Evaluate the contents of this expression and return the result. - * - * May throw a FreeVariableError on expressions that came from a macro. - */ - final def run(implicit toolbox: Toolbox): T = toolbox.run(this) - -} +sealed abstract class Expr[+T] object Expr { // TODO simplify using new extension methods + // TODO apply function eagerly implicit class ExprOps[T](expr: Expr[T]) { /** Show a source code like representation of this expression */ - def show(implicit toolbox: Toolbox): String = toolbox.show(expr) + def show(implicit stCtx: StagingContext): String = stCtx.show(expr) } implicit class AsFunction0[R](private val f: Expr[() => R]) extends AnyVal { @@ -119,10 +110,6 @@ object Expr { * These should never be used directly. */ object Exprs { - /** An Expr backed by a pickled TASTY tree */ - final class TastyExpr[+T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] { - override def toString: String = s"Expr()" - } /** An Expr backed by a lifted value. * Values can only be of type Boolean, Byte, Short, Char, Int, Long, Float, Double, Unit, String or Null. @@ -138,7 +125,7 @@ object Exprs { * * May contain references to code defined outside this TastyTreeExpr instance. */ - final class TastyTreeExpr[Tree](val tree: Tree) extends quoted.Expr[Any] { + final class TastyTreeExpr[Tree](val tree: Tree, val ctxId: Int) extends quoted.Expr[Any] { override def toString: String = s"Expr()" } diff --git a/library/src/scala/quoted/Liftable.scala b/library/src/scala/quoted/Liftable.scala index e56e3bc594d8..33e82e52f25f 100644 --- a/library/src/scala/quoted/Liftable.scala +++ b/library/src/scala/quoted/Liftable.scala @@ -6,7 +6,7 @@ import scala.runtime.quoted.Unpickler.liftedExpr * without going through an explicit `'{...}` operation. */ abstract class Liftable[T] { - def toExpr(x: T): Expr[T] + def toExpr(x: T)(implicit st: StagingContext): Expr[T] } /** Some liftable base types. To be completed with at least all types @@ -17,43 +17,43 @@ abstract class Liftable[T] { object Liftable { implicit def BooleanIsLiftable: Liftable[Boolean] = new Liftable[Boolean] { - def toExpr(x: Boolean): Expr[Boolean] = liftedExpr(x) + def toExpr(x: Boolean)(implicit st: StagingContext): Expr[Boolean] = liftedExpr(x) } implicit def ByteIsLiftable: Liftable[Byte] = new Liftable[Byte] { - def toExpr(x: Byte): Expr[Byte] = liftedExpr(x) + def toExpr(x: Byte)(implicit st: StagingContext): Expr[Byte] = liftedExpr(x) } implicit def CharIsLiftable: Liftable[Char] = new Liftable[Char] { - def toExpr(x: Char): Expr[Char] = liftedExpr(x) + def toExpr(x: Char)(implicit st: StagingContext): Expr[Char] = liftedExpr(x) } implicit def ShortIsLiftable: Liftable[Short] = new Liftable[Short] { - def toExpr(x: Short): Expr[Short] = liftedExpr(x) + def toExpr(x: Short)(implicit st: StagingContext): Expr[Short] = liftedExpr(x) } implicit def IntIsLiftable: Liftable[Int] = new Liftable[Int] { - def toExpr(x: Int): Expr[Int] = liftedExpr(x) + def toExpr(x: Int)(implicit st: StagingContext): Expr[Int] = liftedExpr(x) } implicit def LongIsLiftable: Liftable[Long] = new Liftable[Long] { - def toExpr(x: Long): Expr[Long] = liftedExpr(x) + def toExpr(x: Long)(implicit st: StagingContext): Expr[Long] = liftedExpr(x) } implicit def FloatIsLiftable: Liftable[Float] = new Liftable[Float] { - def toExpr(x: Float): Expr[Float] = liftedExpr(x) + def toExpr(x: Float)(implicit st: StagingContext): Expr[Float] = liftedExpr(x) } implicit def DoubleIsLiftable: Liftable[Double] = new Liftable[Double] { - def toExpr(x: Double): Expr[Double] = liftedExpr(x) + def toExpr(x: Double)(implicit st: StagingContext): Expr[Double] = liftedExpr(x) } implicit def StringIsLiftable: Liftable[String] = new Liftable[String] { - def toExpr(x: String): Expr[String] = liftedExpr(x) + def toExpr(x: String)(implicit st: StagingContext): Expr[String] = liftedExpr(x) } implicit def ClassIsLiftable[T]: Liftable[Class[T]] = new Liftable[Class[T]] { - def toExpr(x: Class[T]): Expr[Class[T]] = liftedExpr(x) + def toExpr(x: Class[T])(implicit st: StagingContext): Expr[Class[T]] = liftedExpr(x) } } diff --git a/library/src/scala/quoted/StagingContext.scala b/library/src/scala/quoted/StagingContext.scala new file mode 100644 index 000000000000..d14d0690bd36 --- /dev/null +++ b/library/src/scala/quoted/StagingContext.scala @@ -0,0 +1,25 @@ +package scala.quoted + +import scala.tasty.Reflection + +import scala.annotation.{implicitAmbiguous, implicitNotFound} + +// TODO add @implicitAmbiguous("...") +// TODO add some fake default and give better error message in `Staging` compiler phase +@implicitNotFound("Could not find an implicit StagingContext.\nIf this is a method that returns an `Expr[T]` you can use `Staged[T]` instead.\n\nQuotedContex is provided inside of top level splices in `inline` macros or within a call to `Toolbox.run`.\n") +trait StagingContext extends scala.runtime.quoted.Unpickler { + def show[T](expr: Expr[T]): String + def show[T](tpe: Type[T]): String + + /** AST reflection API. Provides low level reflection capabilities on the definition of the TASTy trees. + * + * Waring: Using this API can break the static type safety of quotes and splices. + * Error will be thrown at reflection time. + */ + val reflection: Reflection +} + +object StagingContext { + /** Compiler `StagingContext` available in a top level `~` of an inline macro */ + def macroContext: StagingContext = throw new Exception("Not in inline macro.") +} diff --git a/library/src/scala/runtime/quoted/Unpickler.scala b/library/src/scala/runtime/quoted/Unpickler.scala index ac4466b35fa5..5ab30035c3de 100644 --- a/library/src/scala/runtime/quoted/Unpickler.scala +++ b/library/src/scala/runtime/quoted/Unpickler.scala @@ -1,10 +1,14 @@ package scala.runtime.quoted -import scala.quoted.Types.TastyType -import scala.quoted.Exprs.{LiftedExpr, TastyExpr} +import scala.quoted.Exprs.LiftedExpr import scala.quoted.{Expr, Type} /** Provides methods to unpickle `Expr` and `Type` trees. */ +trait Unpickler { + private[quoted] def unpickleExpr[T](repr: Unpickler.Pickled, args: Seq[Any]): Expr[T] + private[quoted] def unpickleType[T](repr: Unpickler.Pickled, args: Seq[Any]): Type[T] +} + object Unpickler { /** Representation of pickled trees. For now a List[String], @@ -15,15 +19,17 @@ object Unpickler { /** Unpickle `repr` which represents a pickled `Expr` tree, * replacing splice nodes with `args` */ - def unpickleExpr[T](repr: Pickled, args: Seq[Any]): Expr[T] = new TastyExpr[T](repr, args) + def unpickleExpr[T](repr: Pickled, args: Seq[Any], unpickler: Unpickler): Expr[T] = + unpickler.unpickleExpr(repr, args) /** Lift the `value` to an `Expr` tree. * Values can only be of type Boolean, Byte, Short, Char, Int, Long, Float, Double, Unit, String, Null or Class. */ - def liftedExpr[T](value: T): LiftedExpr[T] = new LiftedExpr[T](value) + def liftedExpr[T](value: T): Expr[T] = new LiftedExpr[T](value) /** Unpickle `repr` which represents a pickled `Type` tree, * replacing splice nodes with `args` */ - def unpickleType[T](repr: Pickled, args: Seq[Any]): Type[T] = new TastyType[T](repr, args) + def unpickleType[T](repr: Pickled, args: Seq[Any], unpickler: Unpickler): Type[T] = + unpickler.unpickleType(repr, args) } diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index eafa6e3c12c2..1bd623ecabe6 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -45,5 +45,6 @@ class Reflection(val kernel: Kernel) object Reflection { /** Compiler tasty context available in a top level ~ of an inline macro */ - def macroContext: Reflection = throw new Exception("Not in inline macro.") + @deprecated("use StagingContext.macroContext") + def macroContext: Reflection = throw new Exception("Not in inline macro.") // TODO remove when reference compiler is updated } diff --git a/tests/disabled/reflect/run/t4813.scala b/tests/disabled/reflect/run/t4813.scala index 1146bb16ec04..c8f88c6715b6 100644 --- a/tests/disabled/reflect/run/t4813.scala +++ b/tests/disabled/reflect/run/t4813.scala @@ -1,5 +1,5 @@ import collection.mutable._ -import reflect._ +import staging.reflection._ object Test extends dotty.runtime.LegacyApp { diff --git a/tests/disabled/run/i4803d/Macro_1.scala b/tests/disabled/run/i4803d/Macro_1.scala index 8070c3180721..abc79b7c4bfc 100644 --- a/tests/disabled/run/i4803d/Macro_1.scala +++ b/tests/disabled/run/i4803d/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ object PowerMacro { - def powerCode(x: Expr[Double], n: Long): Expr[Double] = + def powerCode(x: Expr[Double], n: Long): Staged[Double] = if (n == 0) '{1.0} else if (n % 2 == 0) '{ val y = $x * $x; ${powerCode('y, n / 2)} } else '{ $x * ${powerCode(x, n - 1)} } diff --git a/tests/neg-macros/inline-case-objects/Macro_1.scala b/tests/neg-macros/inline-case-objects/Macro_1.scala index 4b636d5d4ec4..a347c402cd44 100644 --- a/tests/neg-macros/inline-case-objects/Macro_1.scala +++ b/tests/neg-macros/inline-case-objects/Macro_1.scala @@ -3,7 +3,7 @@ import scala.quoted._ import scala.quoted.autolift._ object Macros { - def impl(foo: Any): Expr[String] = foo.getClass.getCanonicalName + def impl(foo: Any): Staged[String] = foo.getClass.getCanonicalName } class Bar { diff --git a/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala b/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala index 5e5e71140fed..542cf17f0fd1 100644 --- a/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala +++ b/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala @@ -6,29 +6,29 @@ object E { inline def eval[T](inline x: E[T]): T = ${ impl(x) } - def impl[T](x: E[T]): Expr[T] = x.lift + def impl[T](x: E[T]): Staged[T] = x.lift } trait E[T] { - def lift: Expr[T] + def lift: Staged[T] } case class I(n: Int) extends E[Int] { - def lift: Expr[Int] = n + def lift: Staged[Int] = n } case class Plus[T](x: E[T], y: E[T])(implicit op: Plus2[T]) extends E[T] { - def lift: Expr[T] = op(x.lift, y.lift) + def lift: Staged[T] = op(x.lift, y.lift) } trait Op2[T] { - def apply(x: Expr[T], y: Expr[T]): Expr[T] + def apply(x: Expr[T], y: Expr[T]): Staged[T] } trait Plus2[T] extends Op2[T] object Plus2 { implicit case object IPlus extends Plus2[Int] { - def apply(x: Expr[Int], y: Expr[Int]): Expr[Int] = '{$x + $y} + def apply(x: Expr[Int], y: Expr[Int]): Staged[Int] = '{$x + $y} } } diff --git a/tests/neg-macros/inline-option/Macro_1.scala b/tests/neg-macros/inline-option/Macro_1.scala index 525cfd71ab9d..983e7ccc6dcb 100644 --- a/tests/neg-macros/inline-option/Macro_1.scala +++ b/tests/neg-macros/inline-option/Macro_1.scala @@ -3,7 +3,7 @@ import scala.quoted._ import scala.quoted.autolift._ object Macro { - def impl(opt: Option[Int]): Expr[Int] = opt match { + def impl(opt: Option[Int]): Staged[Int] = opt match { case Some(i) => i case None => '{-1} } diff --git a/tests/neg-macros/inline-tuples-1/Macro_1.scala b/tests/neg-macros/inline-tuples-1/Macro_1.scala index ad2439520403..50263fffc950 100644 --- a/tests/neg-macros/inline-tuples-1/Macro_1.scala +++ b/tests/neg-macros/inline-tuples-1/Macro_1.scala @@ -3,26 +3,26 @@ import scala.quoted._ import scala.quoted.autolift._ object Macros { - def tup1(tup: Tuple1[Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup2(tup: Tuple2[Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup3(tup: Tuple3[Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup4(tup: Tuple4[Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup5(tup: Tuple5[Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup6(tup: Tuple6[Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup7(tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup8(tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup9(tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup10(tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup11(tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup12(tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup13(tup: Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup14(tup: Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup15(tup: Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup16(tup: Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup17(tup: Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup18(tup: Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup19(tup: Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup20(tup: Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup21(tup: Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup22(tup: Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup1(tup: Tuple1[Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup2(tup: Tuple2[Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup3(tup: Tuple3[Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup4(tup: Tuple4[Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup5(tup: Tuple5[Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup6(tup: Tuple6[Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup7(tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup8(tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup9(tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup10(tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup11(tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup12(tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup13(tup: Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup14(tup: Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup15(tup: Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup16(tup: Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup17(tup: Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup18(tup: Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup19(tup: Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup20(tup: Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup21(tup: Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup22(tup: Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum } diff --git a/tests/neg-macros/quote-error-2/Macro_1.scala b/tests/neg-macros/quote-error-2/Macro_1.scala index f6507f10e49c..0c13e73196fd 100644 --- a/tests/neg-macros/quote-error-2/Macro_1.scala +++ b/tests/neg-macros/quote-error-2/Macro_1.scala @@ -2,10 +2,10 @@ import quoted._ object Macro_1 { inline def foo(inline b: Boolean): Unit = ${ fooImpl(b) } - def fooImpl(b: Boolean): Expr[Unit] = + def fooImpl(b: Boolean): Staged[Unit] = '{println(${msg(b)})} - def msg(b: Boolean): Expr[String] = + def msg(b: Boolean): Staged[String] = if (b) '{"foo(true)"} else QuoteError("foo cannot be called with false") diff --git a/tests/neg-macros/quote-error/Macro_1.scala b/tests/neg-macros/quote-error/Macro_1.scala index 5713a4e3ec2e..4489ba5fd76a 100644 --- a/tests/neg-macros/quote-error/Macro_1.scala +++ b/tests/neg-macros/quote-error/Macro_1.scala @@ -2,7 +2,7 @@ import quoted._ object Macro_1 { inline def foo(inline b: Boolean): Unit = ${fooImpl(b)} - def fooImpl(b: Boolean): Expr[Unit] = + def fooImpl(b: Boolean): Staged[Unit] = if (b) '{println("foo(true)")} else QuoteError("foo cannot be called with false") } diff --git a/tests/neg-macros/quote-exception/Macro_1.scala b/tests/neg-macros/quote-exception/Macro_1.scala index 721b9d1d97cf..850bebb9606a 100644 --- a/tests/neg-macros/quote-exception/Macro_1.scala +++ b/tests/neg-macros/quote-exception/Macro_1.scala @@ -2,7 +2,7 @@ import quoted._ object Macro_1 { inline def foo(inline b: Boolean): Unit = ${fooImpl(b)} - def fooImpl(b: Boolean): Expr[Unit] = + def fooImpl(b: Boolean): Staged[Unit] = if (b) '{println("foo(true)")} else ??? } diff --git a/tests/neg-macros/quote-interpolator-core-old.scala b/tests/neg-macros/quote-interpolator-core-old.scala index ddb2e6dc09f4..c9eae2c43829 100644 --- a/tests/neg-macros/quote-interpolator-core-old.scala +++ b/tests/neg-macros/quote-interpolator-core-old.scala @@ -12,12 +12,12 @@ object FInterpolation { // ... } - private def liftSeq(args: Seq[Expr[Any]]): Expr[Seq[Any]] = args match { + private def liftSeq(args: Seq[Expr[Any]]): Staged[Seq[Any]] = args match { case x :: xs => '{ ($x) +: ${liftSeq(xs)} } case Nil => '{Seq(): Seq[Any]} } - def fInterpolation(sc: StringContext, args: Seq[Expr[Any]]): Expr[String] = { + def fInterpolation(sc: StringContext, args: Seq[Expr[Any]]): Staged[String] = { val str: Expr[String] = sc.parts.mkString("") val args1: Expr[Seq[Any]] = liftSeq(args) '{ $str.format($args1: _*) } diff --git a/tests/neg-macros/quote-macro-complex-arg-0.scala b/tests/neg-macros/quote-macro-complex-arg-0.scala index 90e202b21a31..d43d89a8ce53 100644 --- a/tests/neg-macros/quote-macro-complex-arg-0.scala +++ b/tests/neg-macros/quote-macro-complex-arg-0.scala @@ -2,5 +2,5 @@ import scala.quoted._ object Macros { inline def foo(inline i: Int, dummy: Int, j: Int): Int = ${ bar(i + 1, 'j) } // error: i + 1 is not a parameter or field reference - def bar(x: Int, y: Expr[Int]): Expr[Int] = '{ ${x.toExpr} + $y } + def bar(x: Int, y: Expr[Int]): Staged[Int] = '{ ${x.toExpr} + $y } } diff --git a/tests/neg-macros/splice-in-top-level-splice-1.scala b/tests/neg-macros/splice-in-top-level-splice-1.scala index 243cd43c5188..8555fff7ab52 100644 --- a/tests/neg-macros/splice-in-top-level-splice-1.scala +++ b/tests/neg-macros/splice-in-top-level-splice-1.scala @@ -3,6 +3,6 @@ import scala.quoted.autolift._ object Foo { inline def foo(): Int = ${bar(${x})} // error - def x: Expr[Int] = '{1} - def bar(i: Int): Expr[Int] = i + def x: Staged[Int] = '{1} + def bar(i: Int): Staged[Int] = i } diff --git a/tests/neg-macros/splice-in-top-level-splice-2.scala b/tests/neg-macros/splice-in-top-level-splice-2.scala index 58efc998f66a..87827161719b 100644 --- a/tests/neg-macros/splice-in-top-level-splice-2.scala +++ b/tests/neg-macros/splice-in-top-level-splice-2.scala @@ -2,5 +2,5 @@ import scala.quoted._ object Foo { inline def foo(): Int = ${$x} // error - def x: Expr[Expr[Int]] = '{ '{1} } + def x: Staged[Expr[Int]] = '{ '{1} } } diff --git a/tests/neg-macros/tasty-macro-assert-2/quoted_1.scala b/tests/neg-macros/tasty-macro-assert-2/quoted_1.scala index 0cd616eaf32c..a1cf27d58115 100644 --- a/tests/neg-macros/tasty-macro-assert-2/quoted_1.scala +++ b/tests/neg-macros/tasty-macro-assert-2/quoted_1.scala @@ -14,8 +14,8 @@ object Asserts { inline def macroAssert(cond: => Boolean): Unit = ${ impl('cond) } - def impl(cond: Expr[Boolean])(implicit reflect: Reflection): Expr[Unit] = { - import reflect._ + def impl(cond: Expr[Boolean])(implicit staging: StagingContext): Expr[Unit] = { + import staging.reflection._ val tree = cond.unseal diff --git a/tests/neg-with-compiler/quote-run-in-macro-1/quoted_1.scala b/tests/neg-with-compiler/quote-run-in-macro-1/quoted_1.scala index 27590f387487..da8a8a1cfe46 100644 --- a/tests/neg-with-compiler/quote-run-in-macro-1/quoted_1.scala +++ b/tests/neg-with-compiler/quote-run-in-macro-1/quoted_1.scala @@ -5,8 +5,9 @@ object Macros { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) inline def foo(i: => Int): Int = ${ fooImpl('i) } - def fooImpl(i: Expr[Int]): Expr[Int] = { - val y: Int = i.run + def fooImpl(i: Expr[Int]): Staged[Int] = { + val tb = Toolbox.make + val y: Int = tb.run(i) y } } diff --git a/tests/neg-with-compiler/quote-run-in-macro-2/quoted_1.scala b/tests/neg-with-compiler/quote-run-in-macro-2/quoted_1.scala index 1f1f38ec20a1..5608ae67919b 100644 --- a/tests/neg-with-compiler/quote-run-in-macro-2/quoted_1.scala +++ b/tests/neg-with-compiler/quote-run-in-macro-2/quoted_1.scala @@ -4,9 +4,10 @@ import scala.quoted.autolift._ object Macros { inline def foo(i: => Int): Int = ${ fooImpl('i) } - def fooImpl(i: Expr[Int]): Expr[Int] = { + def fooImpl(i: Expr[Int]): Staged[Int] = { + val tb = Toolbox.make implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val y: Int = i.run + val y: Int = tb.run(i) y } } diff --git a/tests/neg/quote-0.scala b/tests/neg/quote-0.scala index 5f4299d10682..2da8a65d84c0 100644 --- a/tests/neg/quote-0.scala +++ b/tests/neg/quote-0.scala @@ -2,6 +2,8 @@ import scala.quoted._ class Test { + implicit def dummy: StagingContext = ??? + val x: Int = 0 '{ '{x + 1} // error: wrong staging level diff --git a/tests/neg/quote-spliceNonStaged.scala b/tests/neg/quote-spliceNonStaged.scala index fe93e73a2bf2..0462cbd17b47 100644 --- a/tests/neg/quote-spliceNonStaged.scala +++ b/tests/neg/quote-spliceNonStaged.scala @@ -2,6 +2,6 @@ package quotes import scala.quoted._ object Quotes_1 { - def printHello: Expr[Unit] = '{ println("Hello") } + def printHello: Staged[Unit] = '{ println("Hello") } $printHello // error } diff --git a/tests/pos-macros/i3898/quoted_1.scala b/tests/pos-macros/i3898/quoted_1.scala index 8d2b3d2c5d87..5f3a57e7d339 100644 --- a/tests/pos-macros/i3898/quoted_1.scala +++ b/tests/pos-macros/i3898/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { inline def ff(args: Any*): String = ${impl('args)} - def impl(args: Expr[Seq[Any]]): Expr[String] = '{""} + def impl(args: Expr[Seq[Any]]): Staged[String] = '{""} } diff --git a/tests/pos-macros/i3898b/quoted_1.scala b/tests/pos-macros/i3898b/quoted_1.scala index fa05e2fc2f93..56f9642fa2e6 100644 --- a/tests/pos-macros/i3898b/quoted_1.scala +++ b/tests/pos-macros/i3898b/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { inline def ff(x: Int, inline y: Int): String = ${impl('x)} - def impl(x: Expr[Int]): Expr[String] = '{""} + def impl(x: Expr[Int]): Staged[String] = '{""} } diff --git a/tests/pos-macros/i3898c/quoted_1.scala b/tests/pos-macros/i3898c/quoted_1.scala index fa05e2fc2f93..56f9642fa2e6 100644 --- a/tests/pos-macros/i3898c/quoted_1.scala +++ b/tests/pos-macros/i3898c/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { inline def ff(x: Int, inline y: Int): String = ${impl('x)} - def impl(x: Expr[Int]): Expr[String] = '{""} + def impl(x: Expr[Int]): Staged[String] = '{""} } diff --git a/tests/pos-macros/i3898c/quoted_2.scala b/tests/pos-macros/i3898c/quoted_2.scala index c94794b2b4ac..0e2451a6fe4d 100644 --- a/tests/pos-macros/i3898c/quoted_2.scala +++ b/tests/pos-macros/i3898c/quoted_2.scala @@ -1,9 +1,14 @@ +import scala.quoted._ + object Test { def main(args: Array[String]): Unit = { - val a = '{ - def z: Int = 5 - Macro.ff(z, 5) + val tb = Toolbox.make + tb.run { + val a = '{ + def z: Int = 5 + Macro.ff(z, 5) + } + a.show.toExpr } - } } diff --git a/tests/pos-macros/i4023/Macro_1.scala b/tests/pos-macros/i4023/Macro_1.scala index 34551e3123fc..9b608facdab4 100644 --- a/tests/pos-macros/i4023/Macro_1.scala +++ b/tests/pos-macros/i4023/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { inline def ff[T: Type](x: T): T = ${ impl('x) } - def impl[T](x: Expr[T]): Expr[T] = x + def impl[T](x: Expr[T]): Staged[T] = x } diff --git a/tests/pos-macros/i4023b/Macro_1.scala b/tests/pos-macros/i4023b/Macro_1.scala index bad8763aeeb2..687063509913 100644 --- a/tests/pos-macros/i4023b/Macro_1.scala +++ b/tests/pos-macros/i4023b/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { inline def ff[T](implicit t: Type[T]): Int = ${ impl[T] } - def impl[T]: Expr[Int] = '{4} + def impl[T]: Staged[Int] = '{4} } diff --git a/tests/pos-macros/i4023c/Macro_1.scala b/tests/pos-macros/i4023c/Macro_1.scala index f21f8a9e9012..4e63a62698b3 100644 --- a/tests/pos-macros/i4023c/Macro_1.scala +++ b/tests/pos-macros/i4023c/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { inline def ff[T](x: T): T = ${ impl('x)('[T]) } - def impl[T](x: Expr[T])(implicit t: Type[T]): Expr[T] = '{ $x: $t } + def impl[T](x: Expr[T])(implicit t: Type[T]): Staged[T] = '{ $x: $t } } diff --git a/tests/pos-macros/i4734/Macro_1.scala b/tests/pos-macros/i4734/Macro_1.scala index 740b70a134e0..e29cbd957ce4 100644 --- a/tests/pos-macros/i4734/Macro_1.scala +++ b/tests/pos-macros/i4734/Macro_1.scala @@ -5,7 +5,7 @@ object Macros { inline def unrolledForeach(f: Int => Int): Int = ${unrolledForeachImpl('f)} - def unrolledForeachImpl(f: Expr[Int => Int]): Expr[Int] = '{ + def unrolledForeachImpl(f: Expr[Int => Int]): Staged[Int] = '{ val size: Int = 5 ($f)(3) } diff --git a/tests/pos-macros/power-macro/Macro_1.scala b/tests/pos-macros/power-macro/Macro_1.scala index 53179247dd66..07f320909be3 100644 --- a/tests/pos-macros/power-macro/Macro_1.scala +++ b/tests/pos-macros/power-macro/Macro_1.scala @@ -1,11 +1,11 @@ -import scala.quoted.Expr +import scala.quoted._ object PowerMacro { inline def power(inline n: Long, x: Double) = ${powerCode(n, 'x)} - def powerCode(n: Long, x: Expr[Double]): Expr[Double] = + def powerCode(n: Long, x: Expr[Double]): Staged[Double] = if (n == 0) '{1.0} else if (n % 2 == 0) '{ { val y = $x * $x; ${powerCode(n / 2, 'y)} } } else '{ $x * ${powerCode(n - 1, x)} } diff --git a/tests/pos-macros/quote-nested-object/Macro_1.scala b/tests/pos-macros/quote-nested-object/Macro_1.scala index 9296fbb44da5..4b7498ded8f9 100644 --- a/tests/pos-macros/quote-nested-object/Macro_1.scala +++ b/tests/pos-macros/quote-nested-object/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { inline def plus(inline n: Int, m: Int): Int = ${ plus(n, 'm) } - def plus(n: Int, m: Expr[Int]): Expr[Int] = + def plus(n: Int, m: Expr[Int]): Staged[Int] = if (n == 0) m else '{ ${n} + $m } @@ -17,7 +17,7 @@ object Macro { inline def plus(inline n: Int, m: Int): Int = ${ plus(n, 'm) } - def plus(n: Int, m: Expr[Int]): Expr[Int] = + def plus(n: Int, m: Expr[Int]): Staged[Int] = if (n == 0) m else '{ ${n} + $m } } diff --git a/tests/pos-special/fatal-warnings/tasty-parent-unapply.scala b/tests/pos-special/fatal-warnings/tasty-parent-unapply.scala index af86983884fe..cc593e8da760 100644 --- a/tests/pos-special/fatal-warnings/tasty-parent-unapply.scala +++ b/tests/pos-special/fatal-warnings/tasty-parent-unapply.scala @@ -1,12 +1,10 @@ import scala.quoted._ -import scala.tasty.Reflection - object Macros { - def impl(reflect: Reflection): Unit = { - import reflect._ + def impl(staging: StagingContext): Unit = { + import staging.reflection._ def foo(tree: Tree, term: Term, typeTree: TypeTree, parent: Tree) = { diff --git a/tests/pos-with-compiler/quote-0.scala b/tests/pos-with-compiler/quote-0.scala index c0d931d5ee3b..b74d0dfbfb19 100644 --- a/tests/pos-with-compiler/quote-0.scala +++ b/tests/pos-with-compiler/quote-0.scala @@ -7,7 +7,7 @@ object Macros { inline def assert(expr: => Boolean): Unit = ${ assertImpl('expr) } - def assertImpl(expr: Expr[Boolean]) = + def assertImpl(expr: Expr[Boolean]): Staged[Unit] = '{ if !($expr) then throw new AssertionError(s"failed assertion: ${${showExpr(expr)}}") } @@ -15,7 +15,7 @@ object Macros { inline def power(inline n: Int, x: Double) = ${ powerCode(n, 'x) } - def powerCode(n: Int, x: Expr[Double]): Expr[Double] = + def powerCode(n: Int, x: Expr[Double]): Staged[Double] = if (n == 0) '{1.0} else if (n == 1) x else if (n % 2 == 0) '{ { val y = $x * $x; ${ powerCode(n / 2, 'y) } } } @@ -24,21 +24,23 @@ object Macros { class Test { - val program = '{ - import Macros._ + val tb = Toolbox.make + tb.run { + val program = '{ + import Macros._ - val x = 1 - assert(x != 0) + val x = 1 + assert(x != 0) - ${ assertImpl('{x != 0}) } + ${ assertImpl('{x != 0}) } - val y = math.sqrt(2.0) + val y = math.sqrt(2.0) - power(3, y) + power(3, y) - ${ powerCode(3, '{math.sqrt(2.0)}) } - } + ${ powerCode(3, '{math.sqrt(2.0)}) } + } - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - program.run + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)program + } } diff --git a/tests/pos-with-compiler/quote-assert/quoted_1.scala b/tests/pos-with-compiler/quote-assert/quoted_1.scala index 3f7bc8c69109..3486e2f64530 100644 --- a/tests/pos-with-compiler/quote-assert/quoted_1.scala +++ b/tests/pos-with-compiler/quote-assert/quoted_1.scala @@ -1,6 +1,6 @@ import scala.quoted._ object Macros { - def assertImpl(expr: Expr[Boolean]) = + def assertImpl(expr: Expr[Boolean]): Staged[Unit] = '{ if !($expr) then throw new AssertionError(s"failed assertion: ${$expr}") } } diff --git a/tests/pos-with-compiler/quote-assert/quoted_2.scala b/tests/pos-with-compiler/quote-assert/quoted_2.scala index f1db5a7e9b2c..107ee3b163b4 100644 --- a/tests/pos-with-compiler/quote-assert/quoted_2.scala +++ b/tests/pos-with-compiler/quote-assert/quoted_2.scala @@ -7,14 +7,15 @@ object Test { inline def assert(expr: => Boolean): Unit = ${ assertImpl('expr) } + val tb = Toolbox.make + tb.run { + val program = '{ + val x = 1 + assert(x != 0) - val program = '{ - val x = 1 - assert(x != 0) + ${ assertImpl('{x != 0}) } + } - ${ assertImpl('{x != 0}) } + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)program } - - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - program.run } diff --git a/tests/pos/i3898c.check b/tests/pos/i3898c.check new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/pos/i4350.scala b/tests/pos/i4350.scala index 46616bbcff10..29af033e13e9 100644 --- a/tests/pos/i4350.scala +++ b/tests/pos/i4350.scala @@ -1,5 +1,5 @@ -import scala.quoted.Type +import scala.quoted._ class Foo[T: Type] { - '{null.asInstanceOf[T]} + def foo: Staged[T] = '{null.asInstanceOf[T]} } diff --git a/tests/pos/i4380a.scala b/tests/pos/i4380a.scala index be0a710ff55c..fe555e7658e5 100644 --- a/tests/pos/i4380a.scala +++ b/tests/pos/i4380a.scala @@ -3,7 +3,7 @@ import scala.quoted._ object Test { trait Producer[A] { self => - def step(k: (A => Expr[Unit])): Expr[Unit] + def step(k: (A => Expr[Unit])): Staged[Unit] } trait Foo[A] @@ -13,7 +13,7 @@ object Test { stream match { case Bar(producer, nestedf) => { new Producer[Expr[A]] { - def step(k: Expr[A] => Expr[Unit]): Expr[Unit] = '{ + def step(k: Expr[A] => Expr[Unit]): Staged[Unit] = '{ val adv: Unit => Unit = { _ => ${producer.step((el) => nestedf(el))} } } } diff --git a/tests/pos/i4380b.scala b/tests/pos/i4380b.scala index 864d02d21885..44889d49dd90 100644 --- a/tests/pos/i4380b.scala +++ b/tests/pos/i4380b.scala @@ -1,8 +1,8 @@ import scala.quoted._ object Test { - def step(k: (String => Expr[Unit])): Expr[Unit] = '{} - def meth(): Unit = '{ + def step(k: (String => Expr[Unit])): Staged[Unit] = '{} + def meth(implicit st: StagingContext): Unit = '{ (i: Int) => ${ step(el => '{} ) } } } diff --git a/tests/pos/i4396a.scala b/tests/pos/i4396a.scala index 294783b91eec..6c800a2c4d30 100644 --- a/tests/pos/i4396a.scala +++ b/tests/pos/i4396a.scala @@ -1,3 +1,6 @@ +import scala.quoted._ + class Test { - '{ Option(4) match { case Some(a) => a; case None => 1 }} + def f: Staged[Int] = + '{ Option(4) match { case Some(a) => a; case None => 1 }} } \ No newline at end of file diff --git a/tests/pos/i4396b.scala b/tests/pos/i4396b.scala index ec327cfa61c1..fe34a06b74c3 100644 --- a/tests/pos/i4396b.scala +++ b/tests/pos/i4396b.scala @@ -1,3 +1,5 @@ +import scala.quoted._ + class Test { - '{ case class Foo() } -} \ No newline at end of file + def f: Staged[Unit] = '{ case class Foo() } +} diff --git a/tests/pos/i4414.scala b/tests/pos/i4414.scala index 2a2999ff34b7..a9c82e261d53 100644 --- a/tests/pos/i4414.scala +++ b/tests/pos/i4414.scala @@ -2,7 +2,7 @@ import scala.quoted._ object Test { - def a[A: Type](): Unit = { + def a[A: Type]()(implicit st: StagingContext): Unit = { b[Expr[A]]() a[A]() } diff --git a/tests/pos/i4774a.scala b/tests/pos/i4774a.scala index d8ceda47f7e2..97c86c74f589 100644 --- a/tests/pos/i4774a.scala +++ b/tests/pos/i4774a.scala @@ -2,7 +2,7 @@ import scala.quoted._ object Test { - def loop[T](x: Expr[T])(implicit t: Type[T]): Expr[T] = '{ + def loop[T](x: Expr[T])(implicit t: Type[T]): Staged[T] = '{ val y: $t = $x ${loop('y)} } diff --git a/tests/pos/i4774c.scala b/tests/pos/i4774c.scala index a67e8abc444e..92d15095d98f 100644 --- a/tests/pos/i4774c.scala +++ b/tests/pos/i4774c.scala @@ -2,5 +2,5 @@ import scala.quoted._ object Test { - def loop[T](x: Expr[T])(implicit t: Type[T]): Expr[T] = '{ val y = $x; ${loop('y)} } + def loop[T](x: Expr[T])(implicit t: Type[T]): Staged[T] = '{ val y = $x; ${loop('y)} } } diff --git a/tests/pos/i4774d.scala b/tests/pos/i4774d.scala index 6ab3239b6625..ece6da5ae5ec 100644 --- a/tests/pos/i4774d.scala +++ b/tests/pos/i4774d.scala @@ -2,6 +2,6 @@ import scala.quoted._ object Test { - def loop[T](x: Expr[T])(implicit t: Type[T]): Expr[T] = + def loop[T](x: Expr[T])(implicit t: Type[T]): Staged[T] = '{ val y: T = $x; ${loop('y)} } } diff --git a/tests/pos/i4891.scala b/tests/pos/i4891.scala index cf2189093280..3a34f68c1cff 100644 --- a/tests/pos/i4891.scala +++ b/tests/pos/i4891.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Test { - def foo: Expr[Option[String]] = '{None} + def foo: Staged[Option[String]] = '{None} } diff --git a/tests/pos/quote-1.scala b/tests/pos/quote-1.scala index 5772b7d49c1e..5a76bfc5e720 100644 --- a/tests/pos/quote-1.scala +++ b/tests/pos/quote-1.scala @@ -2,13 +2,15 @@ import scala.quoted._ object Test { + implicit def dummy: StagingContext = ??? + def f[T](x: Expr[T])(implicit t: Type[T]) = '{ val y: $t = $x val z = $x } f('{2})('[Int]) - f('{ true })('[Boolean]) + f('{ true })('[Boolean]) def g(es: Expr[String], t: Type[String]) = f('{ ($es + "!") :: Nil })('[List[$t]]) diff --git a/tests/pos/quote-lift.scala b/tests/pos/quote-lift.scala index 7d3a00322a14..ddb0eec00b6f 100644 --- a/tests/pos/quote-lift.scala +++ b/tests/pos/quote-lift.scala @@ -2,6 +2,8 @@ import scala.quoted._ object Test { + implicit def dummy: StagingContext = ??? + '{ ${implicitly[Liftable[Int]].toExpr(1)} } { @@ -13,5 +15,4 @@ object Test { } - -} \ No newline at end of file +} diff --git a/tests/pos/quote-liftable.scala b/tests/pos/quote-liftable.scala index 8b031f208498..46debc8ac02c 100644 --- a/tests/pos/quote-liftable.scala +++ b/tests/pos/quote-liftable.scala @@ -3,7 +3,7 @@ import scala.quoted._ object Test { implicit def IntIsLiftable: Liftable[Int] = new { - def toExpr(n: Int): Expr[Int] = n match { + def toExpr(n: Int)(implicit st: StagingContext) = n match { case Int.MinValue => '{Int.MinValue} case _ if n < 0 => '{- ${toExpr(n)}} case 0 => '{0} @@ -13,17 +13,19 @@ object Test { } implicit def BooleanIsLiftable: Liftable[Boolean] = new { - implicit def toExpr(b: Boolean) = + def toExpr(b: Boolean)(implicit st: StagingContext) = if (b) '{true} else '{false} } implicit def ListIsLiftable[T: Liftable: Type]: Liftable[List[T]] = new { - def toExpr(xs: List[T]): Expr[List[T]] = xs match { + def toExpr(xs: List[T])(implicit st: StagingContext) = xs match { case x :: xs1 => '{ ${ implicitly[Liftable[T]].toExpr(x) } :: ${ toExpr(xs1) } } case Nil => '{Nil: List[T]} } } + implicit val dummy: StagingContext = ??? + true.toExpr 1.toExpr 'a'.toExpr diff --git a/tests/pos/quote-no-splices.scala b/tests/pos/quote-no-splices.scala index 7f67c60492ce..c93b8696c4d9 100644 --- a/tests/pos/quote-no-splices.scala +++ b/tests/pos/quote-no-splices.scala @@ -1,6 +1,7 @@ +import scala.quoted.StagingContext class Foo { def foo: Unit = { - val expr ='{ + def expr(implicit st: StagingContext) = '{ val a = 3 println("foo") 2 + a diff --git a/tests/pos/quote-this.scala b/tests/pos/quote-this.scala index b06e30b29b69..967c64396c29 100644 --- a/tests/pos/quote-this.scala +++ b/tests/pos/quote-this.scala @@ -1,19 +1,19 @@ import scala.quoted._ class Foo { - def a: Expr[Int] = '{1} - def b: Expr[Int] = '{ + def a: Staged[Int] = '{1} + def b: Staged[Int] = '{ ${ this.a } } - def d: Expr[Expr[Int]] = '{ '{1} } - def e: Expr[Expr[Int]] = '{ + def d: Staged[Expr[Int]] = '{ '{1} } + def e: Staged[Expr[Int]] = '{ '{${${this.d}}} } def foo[T](x: T): T = x - def f = '{ + def f: Staged[Int] = '{ ${ foo[this.type](this).a } } diff --git a/tests/pos/typetags.scala b/tests/pos/typetags.scala index 509ccb6087d0..902193d378cf 100644 --- a/tests/pos/typetags.scala +++ b/tests/pos/typetags.scala @@ -2,7 +2,7 @@ import scala.quoted._ object Test { - def f[T: Type] = { + def f[T: Type](implicit st: StagingContext) = { implicitly[Type[Int]] implicitly[Type[List[Int]]] implicitly[Type[T]] diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala b/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala index 016997e12c3e..4441b1afaca1 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala @@ -7,8 +7,8 @@ object Foo { inline def inspectBody(i: => Int): String = ${ inspectBodyImpl('i) } - def inspectBodyImpl(x: Expr[Int])(implicit reflect: Reflection): Expr[String] = { - import reflect._ + def inspectBodyImpl(x: Expr[Int])(implicit staging: StagingContext): Expr[String] = { + import staging.reflection._ def definitionString(tree: Tree): Expr[String] = tree.symbol match { case IsDefDefSymbol(sym) => sym.tree.showExtractors case IsValDefSymbol(sym) => sym.tree.showExtractors diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala b/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala index d32df868176f..4e41b2d1da39 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala @@ -7,8 +7,8 @@ object Foo { inline def inspectBody(i: => Int): String = ${ inspectBodyImpl('i) } - def inspectBodyImpl(x: Expr[Int])(implicit reflect: Reflection): Expr[String] = { - import reflect._ + def inspectBodyImpl(x: Expr[Int])(implicit staging: StagingContext): Expr[String] = { + import staging.reflection._ def definitionString(tree: Tree): Expr[String] = tree.symbol match { case IsDefDefSymbol(sym) => sym.tree.showExtractors case IsValDefSymbol(sym) => sym.tree.showExtractors diff --git a/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala b/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala index 7d61ab585773..67dd648d865f 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala @@ -8,8 +8,8 @@ object Macros { implicit inline def printOwners[T](x: => T): Unit = ${ impl('x) } - def impl[T](x: Expr[T])(implicit reflect: Reflection): Expr[Unit] = { - import reflect._ + def impl[T](x: Expr[T])(implicit staging: StagingContext): Expr[Unit] = { + import staging.reflection._ val buff = new StringBuilder @@ -24,6 +24,7 @@ object Macros { val output = new TreeTraverser { override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = { + ctx.owner.owner tree match { case IsDefinition(tree @ DefDef(name, _, _, _, _)) => buff.append(name) diff --git a/tests/run-custom-args/Yretain-trees/tasty-load-tree-1/quoted_1.scala b/tests/run-custom-args/Yretain-trees/tasty-load-tree-1/quoted_1.scala index fb6911f7e2f3..9845fb7c7388 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-load-tree-1/quoted_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-load-tree-1/quoted_1.scala @@ -7,8 +7,8 @@ object Foo { inline def inspectBody(i: => Int): String = ${ inspectBodyImpl('i) } - def inspectBodyImpl(x: Expr[Int])(implicit reflect: Reflection): Expr[String] = { - import reflect._ + def inspectBodyImpl(x: Expr[Int])(implicit staging: StagingContext): Expr[String] = { + import staging.reflection._ def definitionString(tree: Tree): Expr[String] = tree.symbol match { case IsClassDefSymbol(sym) => sym.tree.showExtractors.toExpr diff --git a/tests/run-custom-args/Yretain-trees/tasty-load-tree-2/quoted_1.scala b/tests/run-custom-args/Yretain-trees/tasty-load-tree-2/quoted_1.scala index 93e7277adcf6..ffd7297bb4f4 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-load-tree-2/quoted_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-load-tree-2/quoted_1.scala @@ -7,8 +7,8 @@ object Foo { inline def inspectBody(i: => Int): String = ${ inspectBodyImpl('i) } - def inspectBodyImpl(x: Expr[Int])(implicit reflect: Reflection): Expr[String] = { - import reflect._ + def inspectBodyImpl(x: Expr[Int])(implicit staging: StagingContext): Expr[String] = { + import staging.reflection._ def definitionString(tree: Tree): Expr[String] = tree.symbol match { case IsClassDefSymbol(sym) => sym.tree.showExtractors.toExpr diff --git a/tests/run-macros/gestalt-optional-staging/Macro_1.scala b/tests/run-macros/gestalt-optional-staging/Macro_1.scala index 005a85c95c31..755799a2e53f 100644 --- a/tests/run-macros/gestalt-optional-staging/Macro_1.scala +++ b/tests/run-macros/gestalt-optional-staging/Macro_1.scala @@ -17,12 +17,12 @@ final class Optional[+A >: Null](val value: A) extends AnyVal { object Optional { // FIXME fix issue #5097 and enable private - /*private*/ def getOrElseImpl[T >: Null : Type](opt: Expr[Optional[T]], alt: Expr[T]): Expr[T] = '{ + /*private*/ def getOrElseImpl[T >: Null : Type](opt: Expr[Optional[T]], alt: Expr[T]): Staged[T] = '{ if ($opt.isEmpty) $alt else $opt.value } // FIXME fix issue #5097 and enable private - /*private*/ def mapImpl[A >: Null : Type, B >: Null : Type](opt: Expr[Optional[A]], f: Expr[A => B]): Expr[Optional[B]] = '{ + /*private*/ def mapImpl[A >: Null : Type, B >: Null : Type](opt: Expr[Optional[A]], f: Expr[A => B]): Staged[Optional[B]] = '{ if ($opt.isEmpty) new Optional(null) else new Optional(${f('{$opt.value})}) } diff --git a/tests/run-macros/i4455/Macro_1.scala b/tests/run-macros/i4455/Macro_1.scala index 6ec8460328b1..4e463a7e8ad6 100644 --- a/tests/run-macros/i4455/Macro_1.scala +++ b/tests/run-macros/i4455/Macro_1.scala @@ -1,8 +1,9 @@ import scala.quoted._ + object Macros { inline def foo(inline i: Int): Int = ${ bar('i) } inline def foo2(inline i: Int): Int = ${ bar('{i + 1}) } - def bar(x: Expr[Int]): Expr[Int] = x + def bar(x: Expr[Int]): Staged[Int] = x } diff --git a/tests/run-macros/i4515/Macro_1.scala b/tests/run-macros/i4515/Macro_1.scala index b392bf410b57..d004d658624f 100644 --- a/tests/run-macros/i4515/Macro_1.scala +++ b/tests/run-macros/i4515/Macro_1.scala @@ -1,5 +1,6 @@ +import scala.quoted._ object Macro { inline def foo[X](x: X): Unit = ${fooImpl('x)} - def fooImpl[X: quoted.Type](x: quoted.Expr[X]): quoted.Expr[Unit] = '{} + def fooImpl[X: quoted.Type](x: Expr[X]): Staged[Unit] = '{} } diff --git a/tests/run-macros/i4515b/Macro_1.scala b/tests/run-macros/i4515b/Macro_1.scala index ed345bd69bb5..091bc9cc3656 100644 --- a/tests/run-macros/i4515b/Macro_1.scala +++ b/tests/run-macros/i4515b/Macro_1.scala @@ -1,6 +1,6 @@ -import scala.tasty.Reflection +import scala.quoted._ object Macro { inline def foo: Unit = ${ fooImpl } - def fooImpl(implicit reflect: Reflection): quoted.Expr[Unit] = '{} + def fooImpl(implicit staging: StagingContext): quoted.Expr[Unit] = '{} } diff --git a/tests/run-macros/i4734/Macro_1.scala b/tests/run-macros/i4734/Macro_1.scala index 48028ca34861..c8d7f22115cb 100644 --- a/tests/run-macros/i4734/Macro_1.scala +++ b/tests/run-macros/i4734/Macro_1.scala @@ -6,7 +6,7 @@ object Macros { inline def unrolledForeach(seq: IndexedSeq[Int], f: => Int => Unit, inline unrollSize: Int): Unit = // or f: Int => Unit ${ unrolledForeachImpl('seq, 'f, unrollSize) } - def unrolledForeachImpl(seq: Expr[IndexedSeq[Int]], f: Expr[Int => Unit], unrollSize: Int): Expr[Unit] = '{ + def unrolledForeachImpl(seq: Expr[IndexedSeq[Int]], f: Expr[Int => Unit], unrollSize: Int): Staged[Unit] = '{ val size = ($seq).length assert(size % (${unrollSize}) == 0) // for simplicity of the implementation var i = 0 @@ -24,7 +24,7 @@ object Macros { } class UnrolledRange(start: Int, end: Int) { - def foreach(f: Int => Expr[Unit]): Expr[Unit] = { + def foreach(f: Int => Expr[Unit]): Staged[Unit] = { @tailrec def loop(i: Int, acc: Expr[Unit]): Expr[Unit] = if (i >= 0) loop(i - 1, '{ ${f(i)}; $acc }) else acc diff --git a/tests/run-macros/i4735/Macro_1.scala b/tests/run-macros/i4735/Macro_1.scala index 094137c60dde..84a660157c9a 100644 --- a/tests/run-macros/i4735/Macro_1.scala +++ b/tests/run-macros/i4735/Macro_1.scala @@ -8,7 +8,8 @@ object Macro { inline def unrolledForeach(inline unrollSize: Int, seq: Array[Int], f: => Int => Unit): Unit = // or f: Int => Unit ${ unrolledForeachImpl(unrollSize, 'seq, 'f) } - private def unrolledForeachImpl(unrollSize: Int, seq: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ + // FIXME add private issue #5295 + /*private*/ def unrolledForeachImpl(unrollSize: Int, seq: Expr[Array[Int]], f: Expr[Int => Unit]): Staged[Unit] = '{ val size = ($seq).length assert(size % (${unrollSize}) == 0) // for simplicity of the implementation var i = 0 @@ -25,8 +26,9 @@ object Macro { } - private class UnrolledRange(start: Int, end: Int) { - def foreach(f: Int => Expr[Unit]): Expr[Unit] = { + // FIXME add private issue #5295 + /*private*/ class UnrolledRange(start: Int, end: Int) { + def foreach(f: Int => Expr[Unit]): Staged[Unit] = { @tailrec def loop(i: Int, acc: Expr[Unit]): Expr[Unit] = if (i >= 0) loop(i - 1, '{ ${f(i)}; $acc }) else acc diff --git a/tests/run-macros/i4803/Macro_1.scala b/tests/run-macros/i4803/Macro_1.scala index 9e1455107699..b92e2e0b8711 100644 --- a/tests/run-macros/i4803/Macro_1.scala +++ b/tests/run-macros/i4803/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ object PowerMacro { - def powerCode(x: Expr[Double], n: Long): Expr[Double] = + def powerCode(x: Expr[Double], n: Long): Staged[Double] = if (n == 0) '{1.0} else if (n % 2 == 0) '{ val y = $x * $x; ${ powerCode('y, n / 2) } } else '{ $x * ${ powerCode(x, n - 1) } } diff --git a/tests/run-macros/i4803b/Macro_1.scala b/tests/run-macros/i4803b/Macro_1.scala index 48eab25d259b..72cf5619136a 100644 --- a/tests/run-macros/i4803b/Macro_1.scala +++ b/tests/run-macros/i4803b/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ object PowerMacro { - def powerCode(x: Expr[Double], n: Long): Expr[Double] = + def powerCode(x: Expr[Double], n: Long): Staged[Double] = if (n == 0) '{1.0} else if (n % 2 == 0) '{ val y = $x * $x; ${ powerCode('y, n / 2) } } else '{ $x * ${ powerCode(x, n - 1) } } diff --git a/tests/run-macros/i4803c/Macro_1.scala b/tests/run-macros/i4803c/Macro_1.scala index 8070c3180721..abc79b7c4bfc 100644 --- a/tests/run-macros/i4803c/Macro_1.scala +++ b/tests/run-macros/i4803c/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ object PowerMacro { - def powerCode(x: Expr[Double], n: Long): Expr[Double] = + def powerCode(x: Expr[Double], n: Long): Staged[Double] = if (n == 0) '{1.0} else if (n % 2 == 0) '{ val y = $x * $x; ${powerCode('y, n / 2)} } else '{ $x * ${powerCode(x, n - 1)} } diff --git a/tests/run-macros/i4803e/Macro_1.scala b/tests/run-macros/i4803e/Macro_1.scala index 4ccfa8c0e0f4..eb3a7bf2ab5e 100644 --- a/tests/run-macros/i4803e/Macro_1.scala +++ b/tests/run-macros/i4803e/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ object PowerMacro { - def power2(x: Expr[Double]) = '{ + def power2(x: Expr[Double]): Staged[Double] = '{ inline def power(x: Double, n: Long): Double = if (n == 0) 1.0 else if (n % 2 == 0) { val y = x * x; power(y, n / 2) } diff --git a/tests/run-macros/i4803f/Macro_1.scala b/tests/run-macros/i4803f/Macro_1.scala index 25aee2bf00c7..9be4681277d7 100644 --- a/tests/run-macros/i4803f/Macro_1.scala +++ b/tests/run-macros/i4803f/Macro_1.scala @@ -1,12 +1,12 @@ import scala.quoted._ object PowerMacro { - def powerCode(x: Expr[Double], n: Long): Expr[Double] = + def powerCode(x: Expr[Double], n: Long): Staged[Double] = if (n == 0) '{1.0} else if (n % 2 == 0) '{ val y = $x * $x; ${powerCode('y, n / 2)} } else '{ $x * ${powerCode(x, n - 1)} } - def power2(x: Expr[Double]) = '{ + def power2(x: Expr[Double]): Staged[Double] = '{ inline def power(x: Double): Double = ${powerCode('x, 2)} power($x) } diff --git a/tests/run-macros/i4947e/Macro_1.scala b/tests/run-macros/i4947e/Macro_1.scala index 7e08adf6d076..22a463959370 100644 --- a/tests/run-macros/i4947e/Macro_1.scala +++ b/tests/run-macros/i4947e/Macro_1.scala @@ -4,7 +4,7 @@ object Macros { def printStack(tag: String): Unit = { println(tag + ": "+ new Exception().getStackTrace().apply(1)) } - def assertImpl(expr: Expr[Boolean]) = '{ + def assertImpl(expr: Expr[Boolean]): Staged[Unit] = '{ printStack("assertImpl") println($expr) } diff --git a/tests/run-macros/i4947f/Macro_1.scala b/tests/run-macros/i4947f/Macro_1.scala index acbf4f25f5a8..a6f721afce3d 100644 --- a/tests/run-macros/i4947f/Macro_1.scala +++ b/tests/run-macros/i4947f/Macro_1.scala @@ -4,7 +4,7 @@ object Macros { def printStack(tag: String): Unit = { println(tag + ": "+ new Exception().getStackTrace().apply(1)) } - def assertImpl(expr: Expr[Boolean]) = '{ + def assertImpl(expr: Expr[Boolean]): Staged[Unit] = '{ printStack("assertImpl") println($expr) } diff --git a/tests/run-macros/i5188a/Macro_1.scala b/tests/run-macros/i5188a/Macro_1.scala index 2aa1a9d4cf1c..09831029a6a1 100644 --- a/tests/run-macros/i5188a/Macro_1.scala +++ b/tests/run-macros/i5188a/Macro_1.scala @@ -3,5 +3,5 @@ import scala.quoted.autolift._ object Lib { inline def sum(inline args: Int*): Int = ${ impl(args: _*) } - def impl(args: Int*): Expr[Int] = args.sum + def impl(args: Int*): Staged[Int] = args.sum } diff --git a/tests/run-macros/i5533/Macro_1.scala b/tests/run-macros/i5533/Macro_1.scala index 9b74f3b5954a..ae7a49c03f7f 100644 --- a/tests/run-macros/i5533/Macro_1.scala +++ b/tests/run-macros/i5533/Macro_1.scala @@ -1,5 +1,4 @@ import scala.quoted._ -import scala.tasty._ object scalatest { @@ -8,8 +7,8 @@ object scalatest { inline def assert(condition: => Boolean): Unit = ${assertImpl('condition)} - def assertImpl(condition: Expr[Boolean])(implicit refl: Reflection): Expr[Unit] = { - import refl._ + def assertImpl(condition: Expr[Boolean])(implicit st: StagingContext): Expr[Unit] = { + import st.reflection._ val tree = condition.unseal diff --git a/tests/run-macros/inline-case-objects/Macro_1.scala b/tests/run-macros/inline-case-objects/Macro_1.scala index b48cd1c35294..9ae0be0e0944 100644 --- a/tests/run-macros/inline-case-objects/Macro_1.scala +++ b/tests/run-macros/inline-case-objects/Macro_1.scala @@ -3,7 +3,7 @@ import scala.quoted._ import scala.quoted.autolift._ object Macros { - def impl(foo: Any): Expr[String] = foo.getClass.getCanonicalName + def impl(foo: Any): Staged[String] = foo.getClass.getCanonicalName } case object Bar { diff --git a/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala b/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala index 7c90bbcaf338..07342c1e7d68 100644 --- a/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala +++ b/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala @@ -6,52 +6,52 @@ object E { inline def eval[T](inline x: E[T]): T = ${ impl(x) } - def impl[T](x: E[T]): Expr[T] = x.lift + def impl[T](x: E[T]): Staged[T] = x.lift } trait E[T] { - def lift: Expr[T] + def lift: Staged[T] } case class I(n: Int) extends E[Int] { - def lift: Expr[Int] = n + def lift: Staged[Int] = n } case class D(n: Double) extends E[Double] { - def lift: Expr[Double] = n + def lift: Staged[Double] = n } case class Plus[T](x: E[T], y: E[T])(implicit op: Plus2[T]) extends E[T] { - def lift: Expr[T] = op(x.lift, y.lift) + def lift: Staged[T] = op(x.lift, y.lift) } case class Times[T](x: E[T], y: E[T])(implicit op: Times2[T]) extends E[T] { - def lift: Expr[T] = op(x.lift, y.lift) + def lift: Staged[T] = op(x.lift, y.lift) } trait Op2[T] { - def apply(x: Expr[T], y: Expr[T]): Expr[T] + def apply(x: Expr[T], y: Expr[T]): Staged[T] } trait Plus2[T] extends Op2[T] object Plus2 { implicit case object IPlus extends Plus2[Int] { - def apply(x: Expr[Int], y: Expr[Int]): Expr[Int] = '{$x + $y} + def apply(x: Expr[Int], y: Expr[Int]): Staged[Int] = '{$x + $y} } implicit case object DPlus extends Plus2[Double] { - def apply(x: Expr[Double], y: Expr[Double]): Expr[Double] = '{$x + $y} + def apply(x: Expr[Double], y: Expr[Double]): Staged[Double] = '{$x + $y} } } trait Times2[T] extends Op2[T] object Times2 { implicit case object ITimes extends Times2[Int] { - def apply(x: Expr[Int], y: Expr[Int]): Expr[Int] = '{$x * $y} + def apply(x: Expr[Int], y: Expr[Int]): Staged[Int] = '{$x * $y} } implicit case object DTimes extends Times2[Double] { - def apply(x: Expr[Double], y: Expr[Double]): Expr[Double] = '{$x * $y} + def apply(x: Expr[Double], y: Expr[Double]): Staged[Double] = '{$x * $y} } } diff --git a/tests/run-macros/inline-option/Macro_1.scala b/tests/run-macros/inline-option/Macro_1.scala index 15fc19057981..dae05897c0d4 100644 --- a/tests/run-macros/inline-option/Macro_1.scala +++ b/tests/run-macros/inline-option/Macro_1.scala @@ -4,11 +4,11 @@ import scala.quoted.autolift._ object Macros { - def impl(opt: Option[Int]): Expr[Int] = opt match { + def impl(opt: Option[Int]): Staged[Int] = opt match { case Some(i) => i case None => '{-1} } - def impl2(opt: Option[Option[Int]]): Expr[Int] = impl(opt.flatten) + def impl2(opt: Option[Option[Int]]): Staged[Int] = impl(opt.flatten) } diff --git a/tests/run-macros/inline-tuples-1/Macro_1.scala b/tests/run-macros/inline-tuples-1/Macro_1.scala index ad2439520403..50263fffc950 100644 --- a/tests/run-macros/inline-tuples-1/Macro_1.scala +++ b/tests/run-macros/inline-tuples-1/Macro_1.scala @@ -3,26 +3,26 @@ import scala.quoted._ import scala.quoted.autolift._ object Macros { - def tup1(tup: Tuple1[Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup2(tup: Tuple2[Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup3(tup: Tuple3[Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup4(tup: Tuple4[Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup5(tup: Tuple5[Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup6(tup: Tuple6[Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup7(tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup8(tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup9(tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup10(tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup11(tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup12(tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup13(tup: Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup14(tup: Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup15(tup: Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup16(tup: Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup17(tup: Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup18(tup: Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup19(tup: Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup20(tup: Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup21(tup: Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup22(tup: Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup1(tup: Tuple1[Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup2(tup: Tuple2[Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup3(tup: Tuple3[Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup4(tup: Tuple4[Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup5(tup: Tuple5[Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup6(tup: Tuple6[Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup7(tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup8(tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup9(tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup10(tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup11(tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup12(tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup13(tup: Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup14(tup: Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup15(tup: Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup16(tup: Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup17(tup: Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup18(tup: Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup19(tup: Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup20(tup: Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup21(tup: Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup22(tup: Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Staged[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum } diff --git a/tests/run-macros/inline-tuples-2/Macro_1.scala b/tests/run-macros/inline-tuples-2/Macro_1.scala index 1beb6c6dd35f..7de3a927e46b 100644 --- a/tests/run-macros/inline-tuples-2/Macro_1.scala +++ b/tests/run-macros/inline-tuples-2/Macro_1.scala @@ -4,8 +4,8 @@ import scala.quoted.autolift._ object Macros { - def impl(tup: Tuple1[Int]): Expr[Int] = tup._1 + def impl(tup: Tuple1[Int]): Staged[Int] = tup._1 - def impl2(tup: Tuple1[Tuple1[Int]]): Expr[Int] = impl(tup._1) + def impl2(tup: Tuple1[Tuple1[Int]]): Staged[Int] = impl(tup._1) } diff --git a/tests/run-macros/inline-varargs-1/Macro_1.scala b/tests/run-macros/inline-varargs-1/Macro_1.scala index 511c66e31ddf..057d634b672e 100644 --- a/tests/run-macros/inline-varargs-1/Macro_1.scala +++ b/tests/run-macros/inline-varargs-1/Macro_1.scala @@ -3,5 +3,5 @@ import scala.quoted._ import scala.quoted.autolift._ object Macros { - def sum(nums: Int*): Expr[Int] = nums.sum + def sum(nums: Int*): Staged[Int] = nums.sum } diff --git a/tests/run-macros/quote-and-splice/Macros_1.scala b/tests/run-macros/quote-and-splice/Macros_1.scala index f74d33359bf4..876caf01532f 100644 --- a/tests/run-macros/quote-and-splice/Macros_1.scala +++ b/tests/run-macros/quote-and-splice/Macros_1.scala @@ -3,23 +3,23 @@ import scala.quoted._ object Macros { inline def macro1 = ${ macro1Impl } - def macro1Impl = '{3} + def macro1Impl: Staged[Int] = '{3} inline def macro2(inline p: Boolean) = ${ macro2Impl(p) } - def macro2Impl(p: Boolean) = if (p) '{3} else '{4} + def macro2Impl(p: Boolean): Staged[Int] = if (p) '{3} else '{4} inline def macro3(n: Int) = ${ macro3Impl('n) } - def macro3Impl(p: Expr[Int]) = '{ 2 + $p } + def macro3Impl(p: Expr[Int]): Staged[Int] = '{ 2 + $p } inline def macro4(i: Int)(j: Int) = ${ macro4Impl('i)('j) } - def macro4Impl(i: Expr[Int])(j: Expr[Int]) = '{ $i + $j } + def macro4Impl(i: Expr[Int])(j: Expr[Int]): Staged[Int] = '{ $i + $j } inline def macro5(i: Int, j: Int) = ${ macro5Impl(j = 'j, i = 'i) } - def macro5Impl(i: Expr[Int], j: Expr[Int]) = '{ $i + $j } + def macro5Impl(i: Expr[Int], j: Expr[Int]): Staged[Int] = '{ $i + $j } inline def power(inline n: Int, x: Double) = ${ powerCode(n, 'x) } - def powerCode(n: Int, x: Expr[Double]): Expr[Double] = + def powerCode(n: Int, x: Expr[Double]): Staged[Double] = if (n == 0) '{1.0} else if (n == 1) x else if (n % 2 == 0) '{ { val y = $x * $x; ${powerCode(n / 2, 'y)} } } diff --git a/tests/run-macros/quote-change-owner/Macro_1.scala b/tests/run-macros/quote-change-owner/Macro_1.scala index c388edf03f14..e00fe536ba16 100644 --- a/tests/run-macros/quote-change-owner/Macro_1.scala +++ b/tests/run-macros/quote-change-owner/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ object Macros { inline def assert2(expr: => Boolean): Unit = ${ assertImpl('expr) } - def assertImpl(expr: Expr[Boolean]) = '{ + def assertImpl(expr: Expr[Boolean]): Staged[Unit] = '{ def foo(): Unit = $expr foo() } diff --git a/tests/run-macros/quote-force/quoted_1.scala b/tests/run-macros/quote-force/quoted_1.scala index 605de9311f3a..ed1b698743a3 100644 --- a/tests/run-macros/quote-force/quoted_1.scala +++ b/tests/run-macros/quote-force/quoted_1.scala @@ -7,13 +7,15 @@ object Location { implicit inline def location: Location = ${impl} - def impl: Expr[Location] = { + def impl: Staged[Location] = { val list = List("a", "b", "c", "d", "e", "f") '{new Location(${list})} } - private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = { - case x :: xs => '{ ${x} :: ${xs} } - case Nil => '{ List.empty[T] } + private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = new Liftable[List[T]] { + def toExpr(x: List[T])(implicit st: StagingContext): Expr[List[T]] = x match { + case x :: xs => '{ ${x} :: ${xs} } + case Nil => '{ List.empty[T] } + } } } diff --git a/tests/run-macros/quote-indexed-map-by-name/quoted_1.scala b/tests/run-macros/quote-indexed-map-by-name/quoted_1.scala index 5696310081b5..a6658b04047e 100644 --- a/tests/run-macros/quote-indexed-map-by-name/quoted_1.scala +++ b/tests/run-macros/quote-indexed-map-by-name/quoted_1.scala @@ -7,7 +7,7 @@ object Index { implicit inline def succ[K, H, T](implicit prev: => Index[K, T]): Index[K, (H, T)] = ${succImpl('[K], '[H], '[T])} - def succImpl[K, H, T](implicit k: Type[K], h: Type[H], t: Type[T]): Expr[Index[K, (H, T)]] = { + def succImpl[K, H, T](implicit k: Type[K], h: Type[H], t: Type[T]): Staged[Index[K, (H, T)]] = { '{new Index(0)} } } \ No newline at end of file diff --git a/tests/run-macros/quote-sep-comp-2/Macro_1.scala b/tests/run-macros/quote-sep-comp-2/Macro_1.scala index eac46498d15f..cea91e4765e2 100644 --- a/tests/run-macros/quote-sep-comp-2/Macro_1.scala +++ b/tests/run-macros/quote-sep-comp-2/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macros { - def assertImpl(expr: Expr[Boolean]) = '{ println($expr) } + def assertImpl(expr: Expr[Boolean]): Staged[Unit] = '{ println($expr) } } diff --git a/tests/run-macros/quote-sep-comp/Macro_1.scala b/tests/run-macros/quote-sep-comp/Macro_1.scala index e13342ac0dc8..2a417c4f1aa8 100644 --- a/tests/run-macros/quote-sep-comp/Macro_1.scala +++ b/tests/run-macros/quote-sep-comp/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macros { inline def assert2(expr: => Boolean): Unit = ${ assertImpl('expr) } - def assertImpl(expr: Expr[Boolean]) = '{ println($expr) } + def assertImpl(expr: Expr[Boolean]): Staged[Unit] = '{ println($expr) } } diff --git a/tests/run-macros/quote-simple-macro/quoted_1.scala b/tests/run-macros/quote-simple-macro/quoted_1.scala index 272ef07a09ae..81520ce660cc 100644 --- a/tests/run-macros/quote-simple-macro/quoted_1.scala +++ b/tests/run-macros/quote-simple-macro/quoted_1.scala @@ -3,5 +3,5 @@ import scala.quoted.autolift._ object Macros { inline def foo(inline i: Int, dummy: Int, j: Int): Int = ${ bar(i, 'j) } - def bar(x: Int, y: Expr[Int]): Expr[Int] = '{ ${x} + $y } + def bar(x: Int, y: Expr[Int]): Staged[Int] = '{ ${x} + $y } } diff --git a/tests/run-macros/quote-unrolled-foreach/quoted_1.scala b/tests/run-macros/quote-unrolled-foreach/quoted_1.scala index 506f41ec79da..1985cb32568c 100644 --- a/tests/run-macros/quote-unrolled-foreach/quoted_1.scala +++ b/tests/run-macros/quote-unrolled-foreach/quoted_1.scala @@ -7,7 +7,8 @@ object Macro { inline def unrolledForeach(inline unrollSize: Int, seq: Array[Int])(f: => Int => Unit): Unit = // or f: Int => Unit ${unrolledForeachImpl(unrollSize, 'seq, 'f)} - private def unrolledForeachImpl(unrollSize: Int, seq: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ + // FIXME add private back + /*private*/ def unrolledForeachImpl(unrollSize: Int, seq: Expr[Array[Int]], f: Expr[Int => Unit]): Staged[Unit] = '{ val size = $seq.length assert(size % (${unrollSize}) == 0) // for simplicity of the implementation var i = 0 diff --git a/tests/run-macros/reflect-select-copy/assert_1.scala b/tests/run-macros/reflect-select-copy/assert_1.scala index 56a489edb7be..359ece4db758 100644 --- a/tests/run-macros/reflect-select-copy/assert_1.scala +++ b/tests/run-macros/reflect-select-copy/assert_1.scala @@ -5,8 +5,8 @@ object scalatest { inline def assert(condition: => Boolean): Unit = ${ assertImpl('condition, '{""}) } - def assertImpl(cond: Expr[Boolean], clue: Expr[Any])(implicit refl: Reflection): Expr[Unit] = { - import refl._ + def assertImpl(cond: Expr[Boolean], clue: Expr[Any])(implicit staCtx: StagingContext): Expr[Unit] = { + import staCtx.reflection._ cond.unseal.underlyingArgument match { case Apply(sel @ Select(lhs, op), rhs :: Nil) => diff --git a/tests/run-macros/tasty-custom-show/quoted_1.scala b/tests/run-macros/tasty-custom-show/quoted_1.scala index a0b25049478d..25e7c63d0db0 100644 --- a/tests/run-macros/tasty-custom-show/quoted_1.scala +++ b/tests/run-macros/tasty-custom-show/quoted_1.scala @@ -8,8 +8,8 @@ object Macros { implicit inline def printOwners[T](x: => T): Unit = ${ impl('x) } - def impl[T](x: Expr[T])(implicit reflect: Reflection): Expr[Unit] = { - import reflect._ + def impl[T](x: Expr[T])(implicit staging: StagingContext): Expr[Unit] = { + import staging.reflection._ val buff = new StringBuilder @@ -39,15 +39,15 @@ object Macros { '{print(${buff.result()})} } - def dummyShow(implicit reflect: Reflection): reflect.Printer = { - import reflect._ + def dummyShow(implicit staging: StagingContext): staging.reflection.Printer = { + import staging.reflection._ new Printer { def showTree(tree: Tree)(implicit ctx: Context): String = "Tree" def showPattern(pattern: Pattern)(implicit ctx: Context): String = "Pattern" def showTypeOrBounds(tpe: TypeOrBounds)(implicit ctx: Context): String = "TypeOrBounds" def showConstant(const: Constant)(implicit ctx: Context): String = "Constant" def showSymbol(symbol: Symbol)(implicit ctx: Context): String = "Symbol" - def showFlags(flags: Flags)(implicit ctx: reflect.Context): String = "Flags" + def showFlags(flags: Flags)(implicit ctx: Context): String = "Flags" } } diff --git a/tests/run-macros/tasty-eval/quoted_1.scala b/tests/run-macros/tasty-eval/quoted_1.scala index 2ba5f2424f35..29bbde12d09d 100644 --- a/tests/run-macros/tasty-eval/quoted_1.scala +++ b/tests/run-macros/tasty-eval/quoted_1.scala @@ -8,19 +8,19 @@ object Macros { implicit inline def foo(i: Int): String = ${ impl('i) } - def impl(i: Expr[Int])(implicit reflect: Reflection): Expr[String] = { + def impl(i: Expr[Int])(implicit staging: StagingContext): Expr[String] = { value(i).toString } - inline implicit def value[X](e: Expr[X])(implicit reflect: Reflection, ev: Valuable[X]): Option[X] = ev.value(e) + inline implicit def value[X](e: Expr[X])(implicit staging: StagingContext, ev: Valuable[X]): Option[X] = ev.value(e) trait Valuable[X] { - def value(e: Expr[X])(implicit reflect: Reflection): Option[X] + def value(e: Expr[X])(implicit staging: StagingContext): Option[X] } implicit def intIsEvalable: Valuable[Int] = new Valuable[Int] { - override def value(e: Expr[Int])(implicit reflect: Reflection): Option[Int] = { - import reflect._ + override def value(e: Expr[Int])(implicit staging: StagingContext): Option[Int] = { + import staging.reflection._ e.unseal.tpe match { case Type.SymRef(IsValDefSymbol(sym), pre) => diff --git a/tests/run-macros/tasty-getfile-implicit-fun-context/Macro_1.scala b/tests/run-macros/tasty-getfile-implicit-fun-context/Macro_1.scala index efd7289fc89e..e0834022eacf 100644 --- a/tests/run-macros/tasty-getfile-implicit-fun-context/Macro_1.scala +++ b/tests/run-macros/tasty-getfile-implicit-fun-context/Macro_1.scala @@ -5,17 +5,16 @@ import scala.tasty.Reflection object SourceFiles { - type Macro[X] = given Reflection => Expr[X] - def tastyContext(implicit ctx: Reflection): Reflection = ctx + type Macro[X] = given StagingContext => Expr[X] + def tastyContext(implicit ctx: StagingContext): StagingContext = ctx implicit inline def getThisFile: String = ${getThisFileImpl} def getThisFileImpl: Macro[String] = { - val reflect = tastyContext - import reflect._ + val staging = implicitly[StagingContext] + import staging.reflection._ rootContext.source.getFileName.toString } - } diff --git a/tests/run-macros/tasty-getfile/Macro_1.scala b/tests/run-macros/tasty-getfile/Macro_1.scala index d9ae5d0b790f..b2e9c2b49b40 100644 --- a/tests/run-macros/tasty-getfile/Macro_1.scala +++ b/tests/run-macros/tasty-getfile/Macro_1.scala @@ -8,8 +8,8 @@ object SourceFiles { implicit inline def getThisFile: String = ${getThisFileImpl} - private def getThisFileImpl(implicit reflect: Reflection): Expr[String] = { - import reflect._ + private def getThisFileImpl(implicit staging: StagingContext): Expr[String] = { + import staging.reflection._ rootContext.source.getFileName.toString } diff --git a/tests/run-macros/tasty-implicit-fun-context-2/Macro_1.scala b/tests/run-macros/tasty-implicit-fun-context-2/Macro_1.scala index 9d1713005148..3ad88674dda1 100644 --- a/tests/run-macros/tasty-implicit-fun-context-2/Macro_1.scala +++ b/tests/run-macros/tasty-implicit-fun-context-2/Macro_1.scala @@ -3,14 +3,14 @@ import scala.tasty.Reflection object Foo { - type Macro[X] = given Reflection => Expr[X] - type Tastier[X] = given Reflection => X + type Macro[X] = given StagingContext => Expr[X] + type Tastier[X] = given StagingContext => X implicit inline def foo: String = ${fooImpl} - def fooImpl(implicit reflect: Reflection): given Reflection => Tastier[given Reflection => Macro[String]] = { - '{"abc"} + def fooImpl(implicit staging: StagingContext): given StagingContext => Tastier[given StagingContext => Macro[String]] = { + '("abc") } } diff --git a/tests/run-macros/tasty-indexed-map/quoted_1.scala b/tests/run-macros/tasty-indexed-map/quoted_1.scala index 2e2b6a00517b..b4d1f73aa56d 100644 --- a/tests/run-macros/tasty-indexed-map/quoted_1.scala +++ b/tests/run-macros/tasty-indexed-map/quoted_1.scala @@ -27,8 +27,8 @@ object Index { implicit inline def succ[K, H, T](implicit prev: => Index[K, T]): Index[K, (H, T)] = ${succImpl[K, H, T]} - def succImpl[K, H, T](implicit reflect: Reflection, k: Type[K], h: Type[H], t: Type[T]): Expr[Index[K, (H, T)]] = { - import reflect._ + def succImpl[K, H, T](implicit staging: StagingContext, k: Type[K], h: Type[H], t: Type[T]): Expr[Index[K, (H, T)]] = { + import staging.reflection._ def name(tp: TypeOrBounds): String = tp match { case Type.ConstantType(Constant.String(str)) => str diff --git a/tests/run-macros/tasty-linenumber-2/quoted_1.scala b/tests/run-macros/tasty-linenumber-2/quoted_1.scala index 9ed4720466f9..fb4eb0c819af 100644 --- a/tests/run-macros/tasty-linenumber-2/quoted_1.scala +++ b/tests/run-macros/tasty-linenumber-2/quoted_1.scala @@ -11,8 +11,8 @@ object LineNumber { implicit inline def line: LineNumber = ${lineImpl} - def lineImpl(implicit reflect: Reflection): Expr[LineNumber] = { - import reflect._ + def lineImpl(implicit staging: StagingContext): Expr[LineNumber] = { + import staging.reflection._ '{new LineNumber(${rootPosition.startLine})} } diff --git a/tests/run-macros/tasty-linenumber/quoted_1.scala b/tests/run-macros/tasty-linenumber/quoted_1.scala index 67192075dd28..6d71e0e12357 100644 --- a/tests/run-macros/tasty-linenumber/quoted_1.scala +++ b/tests/run-macros/tasty-linenumber/quoted_1.scala @@ -12,8 +12,8 @@ object LineNumber { implicit inline def line[T >: Unit <: Unit]: LineNumber = ${lineImpl('[T])} - def lineImpl(x: Type[Unit])(implicit reflect: Reflection): Expr[LineNumber] = { - import reflect._ + def lineImpl(x: Type[Unit])(implicit staging: StagingContext): Expr[LineNumber] = { + import staging.reflection._ '{new LineNumber(${rootPosition.startLine})} } diff --git a/tests/run-macros/tasty-location/quoted_1.scala b/tests/run-macros/tasty-location/quoted_1.scala index bd4a7138fcc3..d9d84f5078ab 100644 --- a/tests/run-macros/tasty-location/quoted_1.scala +++ b/tests/run-macros/tasty-location/quoted_1.scala @@ -9,8 +9,8 @@ object Location { implicit inline def location: Location = ${impl} - def impl(implicit reflect: Reflection): Expr[Location] = { - import reflect._ + def impl(implicit staging: StagingContext): Expr[Location] = { + import staging.reflection._ def listOwnerNames(sym: Symbol, acc: List[String]): List[String] = if (sym == definitions.RootClass || sym == definitions.EmptyPackageClass) acc @@ -20,8 +20,10 @@ object Location { '{new Location(${list})} } - private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = { - case x :: xs => '{ ${x} :: ${xs} } - case Nil => '{ List.empty[T] } + private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = new Liftable[List[T]] { + override def toExpr(x: List[T])(implicit st: StagingContext): Expr[List[T]] = x match { + case x :: xs => '{ ${x} :: ${xs} } + case Nil => '{ List.empty[T] } + } } } diff --git a/tests/run-macros/tasty-macro-assert/quoted_1.scala b/tests/run-macros/tasty-macro-assert/quoted_1.scala index e81cc01473da..d263aaab4ad8 100644 --- a/tests/run-macros/tasty-macro-assert/quoted_1.scala +++ b/tests/run-macros/tasty-macro-assert/quoted_1.scala @@ -14,8 +14,8 @@ object Asserts { inline def macroAssert(cond: => Boolean): Unit = ${impl('cond)} - def impl(cond: Expr[Boolean])(implicit reflect: Reflection): Expr[Unit] = { - import reflect._ + def impl(cond: Expr[Boolean])(implicit staging: StagingContext): Expr[Unit] = { + import staging.reflection._ val tree = cond.unseal diff --git a/tests/run-macros/tasty-positioned/quoted_1.scala b/tests/run-macros/tasty-positioned/quoted_1.scala index 5e1473f8c93c..a3287124c42f 100644 --- a/tests/run-macros/tasty-positioned/quoted_1.scala +++ b/tests/run-macros/tasty-positioned/quoted_1.scala @@ -12,8 +12,8 @@ object Positioned { implicit inline def apply[T](x: => T): Positioned[T] = ${impl('x)} - def impl[T](x: Expr[T])(implicit ev: Type[T], reflect: Reflection): Expr[Positioned[T]] = { - import reflect.{Position => _, _} + def impl[T](x: Expr[T])(implicit ev: Type[T], staging: StagingContext): Expr[Positioned[T]] = { + import staging.reflection.{Position => _, _} val pos = rootPosition val path = pos.sourceFile.jpath.toString diff --git a/tests/run-macros/tasty-seal-method/quoted_1.scala b/tests/run-macros/tasty-seal-method/quoted_1.scala index 2713d4979f6f..ac161ca54b33 100644 --- a/tests/run-macros/tasty-seal-method/quoted_1.scala +++ b/tests/run-macros/tasty-seal-method/quoted_1.scala @@ -1,15 +1,13 @@ import scala.quoted._ -import scala.tasty._ - object Asserts { inline def zeroLastArgs(x: => Int): Int = ${ zeroLastArgsImpl('x) } /** Replaces last argument list by 0s */ - def zeroLastArgsImpl(x: Expr[Int])(implicit reflect: Reflection): Expr[Int] = { - import reflect._ + def zeroLastArgsImpl(x: Expr[Int])(implicit st: StagingContext): Expr[Int] = { + import st.reflection._ // For simplicity assumes that all parameters are Int and parameter lists have no more than 3 elements x.unseal.underlyingArgument match { case Apply(fn, args) => @@ -30,8 +28,8 @@ object Asserts { ${ zeroAllArgsImpl('x) } /** Replaces all argument list by 0s */ - def zeroAllArgsImpl(x: Expr[Int])(implicit reflect: Reflection): Expr[Int] = { - import reflect._ + def zeroAllArgsImpl(x: Expr[Int])(implicit st: StagingContext): Expr[Int] = { + import st.reflection._ // For simplicity assumes that all parameters are Int and parameter lists have no more than 3 elements def rec(term: Term): Term = term match { case Apply(fn, args) => diff --git a/tests/run-macros/tasty-subtyping/quoted_1.scala b/tests/run-macros/tasty-subtyping/quoted_1.scala index b9cbed0696fb..dfd0cda8d4e8 100644 --- a/tests/run-macros/tasty-subtyping/quoted_1.scala +++ b/tests/run-macros/tasty-subtyping/quoted_1.scala @@ -11,14 +11,14 @@ object Macros { inline def isSubTypeOf[T, U]: Boolean = ${isSubTypeOfImpl('[T], '[U])} - def isTypeEqualImpl[T, U](t: Type[T], u: Type[U])(implicit reflect: Reflection): Expr[Boolean] = { - import reflect._ + def isTypeEqualImpl[T, U](t: Type[T], u: Type[U])(implicit staging: StagingContext): Expr[Boolean] = { + import staging.reflection._ val isTypeEqual = t.unseal.tpe =:= u.unseal.tpe isTypeEqual } - def isSubTypeOfImpl[T, U](t: Type[T], u: Type[U])(implicit reflect: Reflection): Expr[Boolean] = { - import reflect._ + def isSubTypeOfImpl[T, U](t: Type[T], u: Type[U])(implicit staging: StagingContext): Expr[Boolean] = { + import staging.reflection._ val isTypeEqual = t.unseal.tpe <:< u.unseal.tpe isTypeEqual } diff --git a/tests/run-macros/tasty-tree-map/quoted_1.scala b/tests/run-macros/tasty-tree-map/quoted_1.scala index d8cceb031073..575b57d24b0a 100644 --- a/tests/run-macros/tasty-tree-map/quoted_1.scala +++ b/tests/run-macros/tasty-tree-map/quoted_1.scala @@ -5,8 +5,8 @@ object Macros { implicit inline def identityMaped[T](x: => T): T = ${ impl('x) } - def impl[T: Type](x: Expr[T])(implicit reflection: Reflection): Expr[T] = { - import reflection._ + def impl[T: Type](x: Expr[T])(implicit st: StagingContext): Expr[T] = { + import st.reflection._ val identityMap = new TreeMap { } val transformed = identityMap.transformTerm(x.unseal).seal.cast[T] transformed diff --git a/tests/run-macros/xml-interpolation-3/XmlQuote_1.scala b/tests/run-macros/xml-interpolation-3/XmlQuote_1.scala index af16eb4204ba..660461d29f35 100644 --- a/tests/run-macros/xml-interpolation-3/XmlQuote_1.scala +++ b/tests/run-macros/xml-interpolation-3/XmlQuote_1.scala @@ -1,6 +1,5 @@ import scala.quoted._ import scala.quoted.autolift._ -import scala.tasty.Reflection import scala.language.implicitConversions @@ -13,7 +12,7 @@ object XmlQuote { ${XmlQuote.impl(ctx, 'args)} } - def impl(receiver: StringContext, args: Expr[Seq[Any]]): Expr[Xml] = { + def impl(receiver: StringContext, args: Expr[Seq[Any]]): Staged[Xml] = { val string = receiver.parts.mkString("??") '{new Xml(${string}, $args.toList)} } diff --git a/tests/run-with-compiler-custom-args/staged-streams_1.scala b/tests/run-with-compiler-custom-args/staged-streams_1.scala index 5e0ebc8c4931..3c1ed9db3c97 100644 --- a/tests/run-with-compiler-custom-args/staged-streams_1.scala +++ b/tests/run-with-compiler-custom-args/staged-streams_1.scala @@ -1,26 +1,23 @@ import scala.quoted._ import scala.quoted.autolift._ -/** - * Port of the strymonas library as described in O. Kiselyov et al., Stream fusion, to completeness (POPL 2017) - */ - -object Test { +/** Port of the strymonas library as described in O. Kiselyov et al., Stream fusion, to completeness (POPL 2017) */ +class Strymonas(implicit staging: StagingContext) { // TODO: remove as it exists in Quoted Lib sealed trait Var[T] { - def get: Expr[T] - def update(x: Expr[T]): Expr[Unit] + def get: Staged[T] + def update(x: Expr[T]): Staged[Unit] } object Var { - def apply[T: Type, U: Type](init: Expr[T])(body: Var[T] => Expr[U]): Expr[U] = '{ + def apply[T: Type, U: Type](init: Expr[T])(body: Var[T] => Expr[U]): Staged[U] = '{ var x = $init ${ body( new Var[T] { - def get: Expr[T] = 'x - def update(e: Expr[T]): Expr[Unit] = '{ x = $e } + def get: Staged[T] = 'x + def update(e: Expr[T]): Staged[Unit] = '{ x = $e } } ) } @@ -625,78 +622,83 @@ object Test { Stream(Linear(prod)) } } +} - def test1() = Stream +object Test { + + def test1(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 2, 3)}) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test2() = Stream + def test2(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 2, 3)}) .map((a: Expr[Int]) => '{ $a * 2 }) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test3() = Stream + def test3(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 2, 3)}) - .flatMap((d: Expr[Int]) => Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d * $dp })) + .flatMap((d: Expr[Int]) => strymonas.Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d * $dp })) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test4() = Stream + def test4(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 2, 3)}) .filter((d: Expr[Int]) => '{ $d % 2 == 0 }) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test5() = Stream + def test5(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 2, 3)}) .take('{2}) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test6() = Stream + def test6(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 1, 1)}) - .flatMap((d: Expr[Int]) => Stream.of('{Array(1, 2, 3)}).take('{2})) + .flatMap((d: Expr[Int]) => strymonas.Stream.of('{Array(1, 2, 3)}).take('{2})) .take('{5}) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test7() = Stream + def test7(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 2, 3)}) - .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), Stream.of('{Array(1, 2, 3)})) + .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), strymonas.Stream.of('{Array(1, 2, 3)})) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test8() = Stream + def test8(strymonas: Strymonas): Staged[Int] = strymonas.Stream .of('{Array(1, 2, 3)}) - .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), Stream.of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp }))) + .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), strymonas.Stream.of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => strymonas.Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp }))) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test9() = Stream - .of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp })) - .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), Stream.of('{Array(1, 2, 3)}) ) + def test9(strymonas: Strymonas): Staged[Int] = strymonas.Stream + .of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => strymonas.Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp })) + .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), strymonas.Stream.of('{Array(1, 2, 3)}) ) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) - def test10() = Stream - .of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp })) - .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), Stream.of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp })) ) + def test10(strymonas: Strymonas): Staged[Int] = strymonas.Stream + .of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => strymonas.Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp })) + .zip(((a : Expr[Int]) => (b : Expr[Int]) => '{ $a + $b }), strymonas.Stream.of('{Array(1, 2, 3)}).flatMap((d: Expr[Int]) => strymonas.Stream.of('{Array(1, 2, 3)}).map((dp: Expr[Int]) => '{ $d + $dp })) ) .fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b })) def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(test1().run) + val tb = scala.quoted.Toolbox.make + import tb.run + + println(run(test1(new Strymonas))) println - println(test2().run) + println(run(test2(new Strymonas))) println - println(test3().run) + println(run(test3(new Strymonas))) println - println(test4().run) + println(run(test4(new Strymonas))) println - println(test5().run) + println(run(test5(new Strymonas))) println - println(test6().run) + println(run(test6(new Strymonas))) println - println(test7().run) + println(run(test7(new Strymonas))) println - println(test8().run) + println(run(test8(new Strymonas))) println - println(test9().run) + println(run(test9(new Strymonas))) println - println(test10().run) + println(run(test10(new Strymonas))) } } diff --git a/tests/run-with-compiler/i3823-b.scala b/tests/run-with-compiler/i3823-b.scala index 958ef94e1b56..949454a9ffc3 100644 --- a/tests/run-with-compiler/i3823-b.scala +++ b/tests/run-with-compiler/i3823-b.scala @@ -1,10 +1,11 @@ import scala.quoted._ object Test { + val tb = Toolbox.make def main(args: Array[String]): Unit = { - def f[T](x: Expr[T])(implicit t: Type[T]) = '{ + def f[T](x: Expr[T])(implicit t: Type[T]): Staged[Unit] = '{ val z: $t = $x } - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(f('{2})(Type.IntTag).show) + val tb = Toolbox.make + println(tb.show(f('(2))(Type.IntTag))) } -} \ No newline at end of file +} diff --git a/tests/run-with-compiler/i3823-c.scala b/tests/run-with-compiler/i3823-c.scala index 3efe37610519..ea198e78b0d4 100644 --- a/tests/run-with-compiler/i3823-c.scala +++ b/tests/run-with-compiler/i3823-c.scala @@ -1,11 +1,10 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - def f[T](x: Expr[T])(implicit t: Type[T]) = '{ + def f[T](x: Expr[T])(implicit t: Type[T]): Staged[Unit] = '{ val z = $x } - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(f('{2})(Type.IntTag).show) + val tb = Toolbox.make + println(tb.show(f('(2))(Type.IntTag))) } } - diff --git a/tests/run-with-compiler/i3823.scala b/tests/run-with-compiler/i3823.scala index 3e207e307d42..7fcbce619734 100644 --- a/tests/run-with-compiler/i3823.scala +++ b/tests/run-with-compiler/i3823.scala @@ -1,10 +1,11 @@ import scala.quoted._ + object Test { + val tb = Toolbox.make def main(args: Array[String]): Unit = { - def f[T: Type](x: Expr[T])(t: Type[T]) = '{ - val z: $t = $x + def f[T: Type](x: Expr[T])(t: Type[T]): Staged[Unit] = '{ + val z: t.unary_~ = ~x } - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(f('{2})('[Int]).show) + println(tb.show(f('(2))('[Int]))) } } \ No newline at end of file diff --git a/tests/run-with-compiler/i3847-b.scala b/tests/run-with-compiler/i3847-b.scala index 3c76fb547c15..d3580345a94e 100644 --- a/tests/run-with-compiler/i3847-b.scala +++ b/tests/run-with-compiler/i3847-b.scala @@ -4,7 +4,7 @@ import scala.reflect.ClassTag object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T]): Liftable[Array[List[T]]] = { new Liftable[Array[List[T]]] { - def toExpr(arr: Array[List[T]]): Expr[Array[List[T]]] = '{ + def toExpr(arr: Array[List[T]])(implicit st: StagingContext): Expr[Array[List[T]]] = '{ new Array[List[$t]](${arr.length.toExpr}) // TODO add elements } @@ -16,8 +16,9 @@ object Test { def main(args: Array[String]): Unit = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) import Arrays._ - implicit val ct: Expr[ClassTag[Int]] = '{ClassTag.Int} - val arr: Expr[Array[List[Int]]] = Array[List[Int]](List(1, 2, 3)).toExpr - println(arr.show) + implicit val ct: Staged[ClassTag[Int]] = '{ClassTag.Int} + val arr: Staged[Array[List[Int]]] = Array[List[Int]](List(1, 2, 3)).toExpr + val tb = Toolbox.make + println(tb.show(arr)) } -} \ No newline at end of file +} diff --git a/tests/run-with-compiler/i3847.scala b/tests/run-with-compiler/i3847.scala index a8b071cc7bdb..18901b69e53b 100644 --- a/tests/run-with-compiler/i3847.scala +++ b/tests/run-with-compiler/i3847.scala @@ -4,7 +4,7 @@ import scala.reflect.ClassTag object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = { new Liftable[Array[T]] { - def toExpr(arr: Array[T]): Expr[Array[T]] = '{ + def toExpr(arr: Array[T])(implicit st: StagingContext): Expr[Array[T]] = '{ new Array[$t](${arr.length.toExpr})($ct) // TODO add elements } @@ -16,8 +16,9 @@ object Test { def main(args: Array[String]): Unit = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(this.getClass.getClassLoader) import Arrays._ - implicit val ct: Expr[ClassTag[Int]] = '{ClassTag.Int} - val arr: Expr[Array[Int]] = Array[Int](1, 2, 3).toExpr - println(arr.show) + implicit def ct: Staged[ClassTag[Int]] = '{ClassTag.Int} + def arr: Staged[Array[Int]] = Array[Int](1, 2, 3).toExpr + val tb = Toolbox.make + println(tb.show(arr)) } } \ No newline at end of file diff --git a/tests/run-with-compiler/i3876-b.scala b/tests/run-with-compiler/i3876-b.scala index b4eda5c9c3a4..89b63743695c 100644 --- a/tests/run-with-compiler/i3876-b.scala +++ b/tests/run-with-compiler/i3876-b.scala @@ -1,15 +1,16 @@ import scala.quoted._ + object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) - val x: Expr[Int] = '{3} + def x: Staged[Int] = '{3} - val f2: Expr[Int => Int] = '{ + def f2: Staged[Int => Int] = '{ def f(x: Int): Int = x + x f } - println(f2(x).run) - println(f2(x).show) + println(tb.run(f2(implicitly)(x))) + println(tb.show(f2(implicitly)(x))) } } diff --git a/tests/run-with-compiler/i3876-c.scala b/tests/run-with-compiler/i3876-c.scala index 1f8cef379856..55ffe0c2d4b2 100644 --- a/tests/run-with-compiler/i3876-c.scala +++ b/tests/run-with-compiler/i3876-c.scala @@ -1,15 +1,16 @@ import scala.quoted._ + object Test { def main(args: Array[String]): Unit = { - implicit def toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) - val x: Expr[Int] = '{3} + def x: Staged[Int] = '{3} - val f3: Expr[Int => Int] = '{ + def f3: Staged[Int => Int] = '{ val f: (x: Int) => Int = x => x + x f } - println(f3(x).run) - println(f3(x).show) // TODO improve printer + println(tb.run(f3(implicitly)(x))) + println(tb.show(f3(implicitly)(x))) // TODO improve printer } } diff --git a/tests/run-with-compiler/i3876-d.scala b/tests/run-with-compiler/i3876-d.scala index 24075b701f3f..5bf4bea7ab42 100644 --- a/tests/run-with-compiler/i3876-d.scala +++ b/tests/run-with-compiler/i3876-d.scala @@ -1,15 +1,16 @@ import scala.quoted._ + object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) - val x: Expr[Int] = '{3} + def x: Staged[Int] = '{3} - val f4: Expr[Int => Int] = '{ + def f4: Staged[Int => Int] = '{ inlineLambda } - println(f4(x).run) - println(f4(x).show) + println(tb.run(f4(implicitly)(x))) + println(tb.show(f4(implicitly)(x))) } inline def inlineLambda <: Int => Int = x => x + x diff --git a/tests/run-with-compiler/i3876.scala b/tests/run-with-compiler/i3876.scala index 418bdee7d3f2..14402f0385a6 100644 --- a/tests/run-with-compiler/i3876.scala +++ b/tests/run-with-compiler/i3876.scala @@ -1,12 +1,13 @@ import scala.quoted._ + object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) - val x: Expr[Int] = '{3} + def x: Staged[Int] = '{3} - val f: Expr[Int => Int] = '{ (x: Int) => x + x } - println(f(x).run) - println(f(x).show) + def f: Staged[Int => Int] = '{ (x: Int) => x + x } + println(tb.run(f(implicitly)(x))) + println(tb.show(f(implicitly)(x))) } } diff --git a/tests/run-with-compiler/i3946.scala b/tests/run-with-compiler/i3946.scala index 84c31b7b6789..730ee9481aca 100644 --- a/tests/run-with-compiler/i3946.scala +++ b/tests/run-with-compiler/i3946.scala @@ -1,9 +1,9 @@ import scala.quoted._ + object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val u: Expr[Unit] = '{} - println(u.show) - println(u.run) + val tb = Toolbox.make + println(tb.show('{})) + println(tb.run('{})) } } diff --git a/tests/run-with-compiler/i3947.scala b/tests/run-with-compiler/i3947.scala index 5ec35a804fe1..82df3949b6b6 100644 --- a/tests/run-with-compiler/i3947.scala +++ b/tests/run-with-compiler/i3947.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } // classOf[Object] diff --git a/tests/run-with-compiler/i3947b.scala b/tests/run-with-compiler/i3947b.scala index b623b8f9fc16..92a96fa3d1eb 100644 --- a/tests/run-with-compiler/i3947b.scala +++ b/tests/run-with-compiler/i3947b.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } // primitives diff --git a/tests/run-with-compiler/i3947b2.scala b/tests/run-with-compiler/i3947b2.scala index b10a46d97301..e2c03b5901e5 100644 --- a/tests/run-with-compiler/i3947b2.scala +++ b/tests/run-with-compiler/i3947b2.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } // primitives diff --git a/tests/run-with-compiler/i3947b3.scala b/tests/run-with-compiler/i3947b3.scala index 15d33d9ae4d2..f5d16b2e81af 100644 --- a/tests/run-with-compiler/i3947b3.scala +++ b/tests/run-with-compiler/i3947b3.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } // primitives diff --git a/tests/run-with-compiler/i3947c.scala b/tests/run-with-compiler/i3947c.scala index 1642692145bf..a99390c1e119 100644 --- a/tests/run-with-compiler/i3947c.scala +++ b/tests/run-with-compiler/i3947c.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } test(classOf[Null]) diff --git a/tests/run-with-compiler/i3947d.scala b/tests/run-with-compiler/i3947d.scala index 11baf2773417..ad4ec238a766 100644 --- a/tests/run-with-compiler/i3947d.scala +++ b/tests/run-with-compiler/i3947d.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } test(classOf[Foo]) diff --git a/tests/run-with-compiler/i3947d2.scala b/tests/run-with-compiler/i3947d2.scala index 2969ded0e436..a009ac0cadae 100644 --- a/tests/run-with-compiler/i3947d2.scala +++ b/tests/run-with-compiler/i3947d2.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } test(classOf[foo.Foo]) diff --git a/tests/run-with-compiler/i3947e.scala b/tests/run-with-compiler/i3947e.scala index b0d0706cca30..1fd6dc732c0d 100644 --- a/tests/run-with-compiler/i3947e.scala +++ b/tests/run-with-compiler/i3947e.scala @@ -4,14 +4,14 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } // class Object diff --git a/tests/run-with-compiler/i3947f.scala b/tests/run-with-compiler/i3947f.scala index d74159272676..8dbc0b5e5b84 100644 --- a/tests/run-with-compiler/i3947f.scala +++ b/tests/run-with-compiler/i3947f.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.run(name.show.toExpr)) + println(tb.run(name)) } // class Array[Object] diff --git a/tests/run-with-compiler/i3947g.scala b/tests/run-with-compiler/i3947g.scala index 6d9e1ec0524c..a87058e776e6 100644 --- a/tests/run-with-compiler/i3947g.scala +++ b/tests/run-with-compiler/i3947g.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } // primitive arrays diff --git a/tests/run-with-compiler/i3947i.scala b/tests/run-with-compiler/i3947i.scala index 6f3241ae6be0..e8f3a78eab5b 100644 --- a/tests/run-with-compiler/i3947i.scala +++ b/tests/run-with-compiler/i3947i.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } // primitive arrays diff --git a/tests/run-with-compiler/i3947j.scala b/tests/run-with-compiler/i3947j.scala index 2d14db5bf052..5e593db9a8b9 100644 --- a/tests/run-with-compiler/i3947j.scala +++ b/tests/run-with-compiler/i3947j.scala @@ -4,13 +4,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def test[T: Type](clazz: java.lang.Class[T]): Unit = { - val lclazz = clazz.toExpr - val name = '{ ($lclazz).getCanonicalName } + def lclazz: Staged[Class[T]] = clazz.toExpr + def name: Staged[String] = '{ ($lclazz).getCanonicalName } println() - println(name.show) - println(name.run) + println(tb.show(name)) + println(tb.run(name)) } test(classOf[Array[Array[Int]]]) diff --git a/tests/run-with-compiler/i4044a.scala b/tests/run-with-compiler/i4044a.scala index 30886ca3dfc7..5ab35c9cb1ca 100644 --- a/tests/run-with-compiler/i4044a.scala +++ b/tests/run-with-compiler/i4044a.scala @@ -1,17 +1,20 @@ import scala.quoted._ class Foo { - def foo: Unit = { + def foo: Staged[Any] = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) val e: Expr[Int] = '{3} val q = '{ ${ '{ $e } } } - println(q.show) + q } } object Test { def main(args: Array[String]): Unit = { - val f = new Foo - f.foo + val tb = Toolbox.make + println(tb.show { + val f = new Foo + f.foo + }) } } diff --git a/tests/run-with-compiler/i4044b.scala b/tests/run-with-compiler/i4044b.scala index b70f9882cee1..78b7879adab0 100644 --- a/tests/run-with-compiler/i4044b.scala +++ b/tests/run-with-compiler/i4044b.scala @@ -1,17 +1,17 @@ import scala.quoted._ sealed abstract class VarRef[T] { - def update(expr: Expr[T]): Expr[Unit] - def expr: Expr[T] + def update(expr: Expr[T]): Staged[Unit] + def expr: Staged[T] } object VarRef { - def apply[T: Type, U: Type](init: Expr[T])(body: VarRef[T] => Expr[U]): Expr[U] = '{ + def apply[T: Type, U: Type](init: Expr[T])(body: VarRef[T] => Expr[U]): Staged[U] = '{ var x = $init ${body( new VarRef { - def update(e: Expr[T]): Expr[Unit] = '{ x = $e } - def expr: Expr[T] = 'x + def update(e: Expr[T]): Staged[Unit] = '{ x = $e } + def expr: Staged[T] = 'x } )} } @@ -21,7 +21,7 @@ object VarRef { object Test { def main(args: Array[String]): Unit = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = VarRef('{4})(varRef => '{ ${varRef.update('{3})}; ${varRef.expr} }) - println(q.show) + val tb = Toolbox.make + println(tb.show(VarRef('{4})(varRef => '{ ${varRef.update('{3})}; ${varRef.expr} }))) } } diff --git a/tests/run-with-compiler/i4044c.scala b/tests/run-with-compiler/i4044c.scala index 558ec2d1b045..0e72da743173 100644 --- a/tests/run-with-compiler/i4044c.scala +++ b/tests/run-with-compiler/i4044c.scala @@ -2,9 +2,9 @@ import scala.quoted._ class Foo { def foo: Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make val q = '{ ${ '{ ${ '{ 5 } } } } } - println(q.show) + println(tb.show(q)) } } diff --git a/tests/run-with-compiler/i4044d.scala b/tests/run-with-compiler/i4044d.scala index 512448e49f8d..9b274548fec5 100644 --- a/tests/run-with-compiler/i4044d.scala +++ b/tests/run-with-compiler/i4044d.scala @@ -2,9 +2,8 @@ import scala.quoted._ class Foo { def foo: Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val a: Expr[Int] = '{3} - val q: Expr[Int] = '{ + def a: Staged[Int] = '{3} + def q: Staged[Int] = '{ val b = 3 ${ println("evaluating inner quote") @@ -13,7 +12,8 @@ class Foo { } } } - println(q.show) + val tb = Toolbox.make + println(tb.show(q)) } } diff --git a/tests/run-with-compiler/i4044e.scala b/tests/run-with-compiler/i4044e.scala index bef7315f5e81..3eea83f5ca93 100644 --- a/tests/run-with-compiler/i4044e.scala +++ b/tests/run-with-compiler/i4044e.scala @@ -1,19 +1,22 @@ import scala.quoted._ class Foo { - def foo: Unit = { + def foo: Staged[Unit] = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) val e: Expr[Int] = '{3} val f: Expr[Int] = '{5} val t: Type[Int] = '[Int] val q = '{ ${ '{ ($e + $f).asInstanceOf[$t] } } } - println(q.show) + '{ println(~q.show.toExpr) } } } object Test { def main(args: Array[String]): Unit = { - val f = new Foo - f.foo + val tb = Toolbox.make + tb.run { + val f = new Foo + f.foo + } } } diff --git a/tests/run-with-compiler/i4044f.scala b/tests/run-with-compiler/i4044f.scala index bad5c8859a3b..1b3d51f36b68 100644 --- a/tests/run-with-compiler/i4044f.scala +++ b/tests/run-with-compiler/i4044f.scala @@ -2,11 +2,10 @@ import scala.quoted._ class Foo { def foo: Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val e: Expr[Int] = '{3} - val f: Expr[Int] = '{5} - def foo(x: Expr[Int], y: Expr[Int]): Expr[Int] = '{ $x + $y } - val q = '{ + def e: Staged[Int] = '{3} + def f: Staged[Int] = '{5} + def foo(x: Expr[Int], y: Expr[Int]): Staged[Int] = '{ $x + $y } + def q: Staged[Int] = '{ val e1 = $e val f1 = $f ${ @@ -14,7 +13,8 @@ class Foo { foo('{e1 + $u}, '{f1}) } } - println(q.show) + val tb = Toolbox.make + println(tb.show(q)) } } diff --git a/tests/run-with-compiler/i4350.scala b/tests/run-with-compiler/i4350.scala index c1be9e8570dd..a8d227ccc98a 100644 --- a/tests/run-with-compiler/i4350.scala +++ b/tests/run-with-compiler/i4350.scala @@ -1,14 +1,14 @@ -import scala.quoted.Type +import scala.quoted._ class Foo[T: Type] { - def q = '{(null: Any).asInstanceOf[T]} + def q: Staged[T] = '{(null: Any).asInstanceOf[T]} } object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println((new Foo[Object]).q.show) - println((new Foo[String]).q.show) + val tb = Toolbox.make(getClass.getClassLoader) + println(tb.run(new Foo[Object]().q.show.toExpr)) + println(tb.run(new Foo[String]().q.show.toExpr)) } } diff --git a/tests/run-with-compiler/i4591.scala b/tests/run-with-compiler/i4591.scala index c862e316c96f..37c7f7193bb3 100644 --- a/tests/run-with-compiler/i4591.scala +++ b/tests/run-with-compiler/i4591.scala @@ -2,14 +2,14 @@ import scala.quoted._ object Test { - def foo[T: Type](init: Expr[T]): Expr[Unit] = '{ + def foo[T: Type](init: Expr[T]): Staged[Unit] = '{ var x = $init println(x) } def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - foo('{Option(9)}).run + val tb = Toolbox.make + tb.run(foo('{Option(9)})) } } diff --git a/tests/run-with-compiler/i5144.scala b/tests/run-with-compiler/i5144.scala index 6f124d2402f9..9c554ab4cddf 100644 --- a/tests/run-with-compiler/i5144.scala +++ b/tests/run-with-compiler/i5144.scala @@ -1,16 +1,18 @@ import scala.quoted._ object Test { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def eval1(ff: Expr[Int => Int]): Expr[Int] = '{$ff(42)} + val tb = Toolbox.make(getClass.getClassLoader) + def eval1(ff: Expr[Int => Int]): Staged[Int] = '{$ff(42)} - def peval1(): Expr[Unit] = '{ + def peval1(): Staged[Unit] = '{ def f(x: Int): Int = ${eval1('f)} } def main(args: Array[String]): Unit = { - val p = peval1() - println(p.show) + println(tb.show { + val p = peval1() + p + }) } } \ No newline at end of file diff --git a/tests/run-with-compiler/i5144b.scala b/tests/run-with-compiler/i5144b.scala index ebbc72e5780e..97b151168a8e 100644 --- a/tests/run-with-compiler/i5144b.scala +++ b/tests/run-with-compiler/i5144b.scala @@ -1,16 +1,18 @@ import scala.quoted._ object Test { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def eval1(ff: Expr[Int => Int]): Expr[Int] = ff('{42}) + val tb = Toolbox.make(getClass.getClassLoader) + def eval1(ff: Expr[Int => Int]): Staged[Int] = ff('{42}) - def peval1(): Expr[Unit] = '{ + def peval1(): Staged[Unit] = '{ def f(x: Int): Int = ${eval1('f)} } def main(args: Array[String]): Unit = { - val p = peval1() - println(p.show) + println(tb.show { + val p = peval1() + p + }) } } \ No newline at end of file diff --git a/tests/run-with-compiler/i5152.scala b/tests/run-with-compiler/i5152.scala index be9532ed2c43..cc945f3d3445 100644 --- a/tests/run-with-compiler/i5152.scala +++ b/tests/run-with-compiler/i5152.scala @@ -1,16 +1,15 @@ import scala.quoted._ object Test { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def eval1(ff: Expr[Int => Int]): Expr[Int => Int] = '{identity} + val tb = Toolbox.make(getClass.getClassLoader) + def eval1(ff: Expr[Int => Int]): Staged[Int => Int] = '{identity} - def peval1(): Expr[Unit] = '{ + def peval1(): Staged[Unit] = '{ lazy val f: Int => Int = ${eval1('{(y: Int) => f(y)})} } def main(args: Array[String]): Unit = { - val p = peval1() - println(p.show) + println(tb.show(peval1())) } } \ No newline at end of file diff --git a/tests/run-with-compiler/i5161.check b/tests/run-with-compiler/i5161.check new file mode 100644 index 000000000000..27c72498d7f1 --- /dev/null +++ b/tests/run-with-compiler/i5161.check @@ -0,0 +1,7 @@ +run : Some(2) +show : scala.Tuple2.apply[scala.Option[scala.Int], scala.Option[scala.Int]](scala.Some.apply[scala.Int](1), scala.Some.apply[scala.Int](1)) match { + case scala.Tuple2(scala.Some(x), scala.Some(y)) => + scala.Some.apply[scala.Int](x.+(y)) + case _ => + scala.None +} diff --git a/tests/run-with-compiler/i5161.scala b/tests/run-with-compiler/i5161.scala new file mode 100644 index 000000000000..4ee5dcb67758 --- /dev/null +++ b/tests/run-with-compiler/i5161.scala @@ -0,0 +1,30 @@ +import scala.quoted._ + +object Test { + val toolbox = scala.quoted.Toolbox.make + enum Exp { + case Int2(x: Int) + case Add(e1: Exp, e2: Exp) + } + import Exp._ + + def evalTest(e: Exp): Staged[Option[Int]] = e match { + case Int2(x) => '(Some(~x.toExpr)) + case Add(e1, e2) => + '{ + (~evalTest(e1), ~evalTest(e2)) match { + case (Some(x), Some(y)) => Some(x+y) + case _ => None + } + } + case null => '(None) + } + + + def main(args: Array[String]): Unit = { + val test = Add(Int2(1), Int2(1)) + def res: Staged[Option[Int]] = evalTest(test) + println("run : " + toolbox.run(res)) + println("show : " + toolbox.show(res)) + } +} diff --git a/tests/run-with-compiler/i5161b.check b/tests/run-with-compiler/i5161b.check new file mode 100644 index 000000000000..a93920fde48e --- /dev/null +++ b/tests/run-with-compiler/i5161b.check @@ -0,0 +1,10 @@ +show0 : { + val x: scala.Option[scala.Int] = scala.Option.apply[scala.Int](3) + if (x.isInstanceOf[scala.Some[_ >: scala.Nothing <: scala.Any]]) scala.Option.apply[scala.Int](1) else scala.None +} +run1 : Some(1) +run2 : Some(1) +show3 : { + val x: scala.Option[scala.Int] = scala.Option.apply[scala.Int](3) + if (x.isInstanceOf[scala.Some[_ >: scala.Nothing <: scala.Any]]) scala.Option.apply[scala.Int](1) else scala.None +} diff --git a/tests/run-with-compiler/i5161b.scala b/tests/run-with-compiler/i5161b.scala new file mode 100644 index 000000000000..efd0c999e9c9 --- /dev/null +++ b/tests/run-with-compiler/i5161b.scala @@ -0,0 +1,18 @@ +import scala.quoted._ + +object Test { + val toolbox: Toolbox = Toolbox.make + + def main(args: Array[String]): Unit = { + def res: Staged[Any] = '{ + val x: Option[Int] = Option(3) + if (x.isInstanceOf[Some[_]]) Option(1) + else None + } + println("show0 : " + toolbox.show(res)) + println("run1 : " + toolbox.run(res)) + println("run2 : " + toolbox.run(res)) + println("show3 : " + toolbox.show(res)) + } +} + diff --git a/tests/run-with-compiler/i5247.scala b/tests/run-with-compiler/i5247.scala index 1fb8793d6822..72fa7ddc4767 100644 --- a/tests/run-with-compiler/i5247.scala +++ b/tests/run-with-compiler/i5247.scala @@ -1,15 +1,15 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(foo[Object].show) - println(bar[Object].show) + val tb = Toolbox.make(getClass.getClassLoader) + println(tb.show(foo[Object])) + println(tb.show(bar[Object])) } - def foo[H : Type]: Expr[H] = { + def foo[H : Type]: Staged[H] = { val t = '[H] '{ null.asInstanceOf[$t] } } - def bar[H : Type]: Expr[List[H]] = { + def bar[H : Type]: Staged[List[H]] = { val t = '[List[H]] '{ null.asInstanceOf[$t] } } diff --git a/tests/run-with-compiler/i5376.check b/tests/run-with-compiler/i5376.check new file mode 100644 index 000000000000..07047a63c26f --- /dev/null +++ b/tests/run-with-compiler/i5376.check @@ -0,0 +1 @@ +1.+(1) diff --git a/tests/run-with-compiler/i5376.scala b/tests/run-with-compiler/i5376.scala new file mode 100644 index 000000000000..178a98673823 --- /dev/null +++ b/tests/run-with-compiler/i5376.scala @@ -0,0 +1,12 @@ +import scala.quoted._ +object Test { + val tb = Toolbox.make + def main(args: Array[String]): Unit = { + tb.run { + var e = '(1) + e = '(~e + 1) + val res = e.show + '(println(~res.toExpr)) + } + } +} diff --git a/tests/run-with-compiler/quote-ackermann-1.scala b/tests/run-with-compiler/quote-ackermann-1.scala index 3e9b4c281d01..352220dcc413 100644 --- a/tests/run-with-compiler/quote-ackermann-1.scala +++ b/tests/run-with-compiler/quote-ackermann-1.scala @@ -3,18 +3,18 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val ack3 = ackermann(3).run + val tb = Toolbox.make + val ack3 = tb.run(ackermann(3)) println(ack3(1)) println(ack3(2)) println(ack3(3)) println(ack3(4)) } - def ackermann(m: Int): Expr[Int => Int] = { + def ackermann(m: Int): Staged[Int => Int] = { if (m == 0) '{ n => n + 1 } else '{ n => - def `ackermann(m-1)`(n: Int): Int = ${ackermann(m - 1)('n)} // Expr[Int => Int] applied to Expr[Int] + def `ackermann(m-1)`(n: Int): Int = ${ val ack = ackermann(m - 1); ack('n) } // Expr[Int => Int] applied to Expr[Int] def `ackermann(m)`(n: Int): Int = if (n == 0) `ackermann(m-1)`(1) else `ackermann(m-1)`(`ackermann(m)`(n - 1)) `ackermann(m)`(n) diff --git a/tests/run-with-compiler/quote-fun-app-1.scala b/tests/run-with-compiler/quote-fun-app-1.scala index d99b03cc578a..e84fc4c01894 100644 --- a/tests/run-with-compiler/quote-fun-app-1.scala +++ b/tests/run-with-compiler/quote-fun-app-1.scala @@ -3,14 +3,14 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val f = f1.run + val tb = Toolbox.make + val f = tb.run(f1) println(f(42)) println(f(43)) } - def f1: Expr[Int => Int] = '{ n => ${f2('n)} } - def f2: Expr[Int => Int] = '{ n => ${f3('n)} } - def f3: Expr[Int => Int] = '{ n => ${f4('n)} } - def f4: Expr[Int => Int] = '{ n => n } + def f1(implicit st: StagingContext): Expr[Int => Int] = '{ n => ${f2(implicitly)('n)} } + def f2(implicit st: StagingContext): Expr[Int => Int] = '{ n => ${f3(implicitly)('n)} } + def f3(implicit st: StagingContext): Expr[Int => Int] = '{ n => ${f4(implicitly)('n)} } + def f4(implicit st: StagingContext): Expr[Int => Int] = '{ n => n } } diff --git a/tests/run-with-compiler/quote-function-applied-to.scala b/tests/run-with-compiler/quote-function-applied-to.scala index daa9b8f308ee..9ab4b2893378 100644 --- a/tests/run-with-compiler/quote-function-applied-to.scala +++ b/tests/run-with-compiler/quote-function-applied-to.scala @@ -2,30 +2,30 @@ import quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(('{ () => x(0) }).apply().show) - println(('{ (x1: Int) => x1 }).apply('{x(1)}).show) - println(('{ (x1: Int, x2: Int) => x1 + x2 }).apply('{x(1)}, '{x(2)}).show) - println(('{ (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 }).apply('{x(1)}, '{x(2)}, '{x(3)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int) => x1 + x2 + x3 + x4 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => x1 + x2 + x3 + x4 + x5 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int) => x1 + x2 + x3 + x4 + x5 + x6 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}, '{x(20)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}, '{x(20)}, '{x(21)}).show) - println(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}, '{x(20)}, '{x(21)}, '{x(22)}).show) + val tb = scala.quoted.Toolbox.make + println(tb.show(('{ () => x(0) }).apply())) + println(tb.show(('{ (x1: Int) => x1 }).apply('{x(1)}))) + println(tb.show(('{ (x1: Int, x2: Int) => x1 + x2 }).apply('{x(1)}, '{x(2)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int) => x1 + x2 + x3 }).apply('{x(1)}, '{x(2)}, '{x(3)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int) => x1 + x2 + x3 + x4 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => x1 + x2 + x3 + x4 + x5 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int) => x1 + x2 + x3 + x4 + x5 + x6 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}, '{x(20)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}, '{x(20)}, '{x(21)}))) + println(tb.show(('{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 }).apply('{x(1)}, '{x(2)}, '{x(3)}, '{x(4)}, '{x(5)}, '{x(6)}, '{x(7)}, '{x(8)}, '{x(9)}, '{x(10)}, '{x(11)}, '{x(12)}, '{x(13)}, '{x(14)}, '{x(15)}, '{x(16)}, '{x(17)}, '{x(18)}, '{x(19)}, '{x(20)}, '{x(21)}, '{x(22)}))) } def x(i: Int): Int = i diff --git a/tests/run-with-compiler/quote-lambda.check b/tests/run-with-compiler/quote-lambda.check new file mode 100644 index 000000000000..43870c18cd8b --- /dev/null +++ b/tests/run-with-compiler/quote-lambda.check @@ -0,0 +1 @@ +((x: scala.Int) => x) diff --git a/tests/run-with-compiler/quote-lambda.scala b/tests/run-with-compiler/quote-lambda.scala index c904c3676a61..ca8489f9d079 100644 --- a/tests/run-with-compiler/quote-lambda.scala +++ b/tests/run-with-compiler/quote-lambda.scala @@ -2,6 +2,7 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - '{ (x: Int) => ${'x} } + val tb = Toolbox.make + println(tb.show('{ (x: Int) => ${'x} })) } } diff --git a/tests/run-with-compiler/quote-lib.scala b/tests/run-with-compiler/quote-lib.scala index 0db100f12028..59bbd4d4007e 100644 --- a/tests/run-with-compiler/quote-lib.scala +++ b/tests/run-with-compiler/quote-lib.scala @@ -11,29 +11,31 @@ import liftable.Exprs._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) val liftedUnit: Expr[Unit] = '{} - letVal('{1})(a => '{ $a + 1 }).show - letLazyVal('{1})(a => '{ $a + 1 }).show - letDef('{1})(a => '{ $a + 1 }).show + def liftedUnit: Staged[Unit] = '() - liftedWhile('{true})('{ println(1) }).show - liftedDoWhile('{ println(1) })('{true}).show + tb.show(letVal('(1))(a => '{ $a + 1 })) + tb.show(letLazyVal('(1))(a => '{ $a + 1 })) + tb.show(letDef('(1))(a => '{ $a + 1 })) - val t1: Expr[Tuple1[Int]] = Tuple1(4) - val t2: Expr[(Int, Int)] = (2, 3) - val t3: Expr[(Int, Int, Int)] = (2, 3, 4) - val t4: Expr[(Int, Int, Int, Int)] = (2, 3, 4, 5) + tb.show(liftedWhile('(true))('{ println(1) })) + tb.show(liftedDoWhile('{ println(1) })('(true))) + + def t1: Staged[Tuple1[Int]] = Tuple1(4).toExpr + def t2: Staged[(Int, Int)] = (2, 3).toExpr + def t3: Staged[(Int, Int, Int)] = (2, 3, 4).toExpr + def t4: Staged[(Int, Int, Int, Int)] = (2, 3, 4, 5).toExpr val list: List[Int] = List(1, 2, 3) - val liftedList: Expr[List[Int]] = list + def liftedList: Staged[List[Int]] = list - liftedList.foldLeft[Int](0)('{ (acc: Int, x: Int) => acc + x }).show - liftedList.foreach('{ (x: Int) => println(x) }).show + tb.show(liftedList.foldLeft[Int](0)('{ (acc: Int, x: Int) => acc + x })) + tb.show(liftedList.foreach('{ (x: Int) => println(x) })) - list.unrolledFoldLeft[Int](0)('{ (acc: Int, x: Int) => acc + x }).show - list.unrolledForeach('{ (x: Int) => println(x) }).show + tb.show(list.unrolledFoldLeft[Int](0)('{ (acc: Int, x: Int) => acc + x })) + tb.show(list.unrolledForeach('{ (x: Int) => println(x) })) println("quote lib ok") } @@ -46,52 +48,52 @@ package liftable { object Exprs { implicit class LiftExprOps[T](x: T) extends AnyVal { - def toExpr(implicit liftable: Liftable[T]): Expr[T] = + def toExpr(implicit liftable: Liftable[T], st: StagingContext): Expr[T] = liftable.toExpr(x) } } object Units { implicit def UnitIsLiftable: Liftable[Unit] = new Liftable[Unit] { - def toExpr(x: Unit): Expr[Unit] = '{} + override def toExpr(x: Unit)(implicit st: StagingContext): Expr[Unit] = '{} } } object Lets { - def letVal[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T]): Expr[U] = + def letVal[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T]): Staged[U] = '{ val letVal: $t = $expr; ${ body('letVal) } } - def letLazyVal[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T]): Expr[U] = + def letLazyVal[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T]): Staged[U] = '{ lazy val letLazyVal: $t = $expr; ${ body('letLazyVal) } } - def letDef[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T]): Expr[U] = + def letDef[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T]): Staged[U] = '{ def letDef: $t = $expr; ${ body('letDef) } } } object Loops { - def liftedWhile(cond: Expr[Boolean])(body: Expr[Unit]): Expr[Unit] = '{ while ($cond) $body } - def liftedDoWhile(body: Expr[Unit])(cond: Expr[Boolean]): Expr[Unit] = '{ do $body while ($cond) } + def liftedWhile(cond: Expr[Boolean])(body: Expr[Unit]): Staged[Unit] = '{ while ($cond) $body } + def liftedDoWhile(body: Expr[Unit])(cond: Expr[Boolean]): Staged[Unit] = '{ do $body while ($cond) } } object Tuples { implicit def Tuple1IsLiftable[T1: Liftable](implicit t1: Type[T1]): Liftable[Tuple1[T1]] = new Liftable[Tuple1[T1]] { - def toExpr(x: Tuple1[T1]): Expr[Tuple1[T1]] = + def toExpr(x: Tuple1[T1])(implicit st: StagingContext): Expr[Tuple1[T1]] = '{ Tuple1[$t1](${ x._1}) } } implicit def Tuple2IsLiftable[T1: Liftable, T2: Liftable](implicit t1: Type[T1], t2: Type[T2]): Liftable[(T1, T2)] = new Liftable[(T1, T2)] { - def toExpr(x: (T1, T2)): Expr[(T1, T2)] = + def toExpr(x: (T1, T2))(implicit st: StagingContext): Expr[(T1, T2)] = '{ Tuple2[$t1, $t2](${x._1}, ${x._2}) } } implicit def Tuple3IsLiftable[T1: Liftable, T2: Liftable, T3: Liftable](implicit t1: Type[T1], t2: Type[T2], t3: Type[T3]): Liftable[(T1, T2, T3)] = new Liftable[(T1, T2, T3)] { - def toExpr(x: (T1, T2, T3)): Expr[(T1, T2, T3)] = + def toExpr(x: (T1, T2, T3))(implicit st: StagingContext): Expr[(T1, T2, T3)] = '{ Tuple3[$t1, $t2, $t3](${x._1}, ${x._2}, ${x._3}) } } implicit def Tuple4IsLiftable[T1: Liftable, T2: Liftable, T3: Liftable, T4: Liftable](implicit t1: Type[T1], t2: Type[T2], t3: Type[T3], t4: Type[T4]): Liftable[(T1, T2, T3, T4)] = new Liftable[(T1, T2, T3, T4)] { - def toExpr(x: (T1, T2, T3, T4)): Expr[(T1, T2, T3, T4)] = + def toExpr(x: (T1, T2, T3, T4))(implicit st: StagingContext): Expr[(T1, T2, T3, T4)] = '{ Tuple4[$t1, $t2, $t3, $t4](${x._1}, ${x._2}, ${x._3}, ${x._4}) } } @@ -102,25 +104,25 @@ package liftable { object Lists { implicit def ListIsLiftable[T: Liftable](implicit t: Type[T]): Liftable[List[T]] = new Liftable[List[T]] { - def toExpr(x: List[T]): Expr[List[T]] = x match { + def toExpr(x: List[T])(implicit st: StagingContext): Expr[List[T]] = x match { case x :: xs => '{ (${xs}).::[$t](${x}) } case Nil => '{ Nil: List[$t] } } } implicit class LiftedOps[T: Liftable](list: Expr[List[T]])(implicit t: Type[T]) { - def foldLeft[U](acc: Expr[U])(f: Expr[(U, T) => U])(implicit u: Type[U]): Expr[U] = + def foldLeft[U](acc: Expr[U])(f: Expr[(U, T) => U])(implicit u: Type[U]): Staged[U] = '{ ($list).foldLeft[$u]($acc)($f) } - def foreach(f: Expr[T => Unit]): Expr[Unit] = + def foreach(f: Expr[T => Unit]): Staged[Unit] = '{ ($list).foreach($f) } } implicit class UnrolledOps[T: Liftable](list: List[T])(implicit t: Type[T]) { - def unrolledFoldLeft[U](acc: Expr[U])(f: Expr[(U, T) => U])(implicit u: Type[U]): Expr[U] = list match { + def unrolledFoldLeft[U](acc: Expr[U])(f: Expr[(U, T) => U])(implicit u: Type[U]): Staged[U] = list match { case x :: xs => xs.unrolledFoldLeft('{ ($f).apply($acc, ${x}) })(f) case Nil => acc } - def unrolledForeach(f: Expr[T => Unit]): Expr[Unit] = list match { + def unrolledForeach(f: Expr[T => Unit]): Staged[Unit] = list match { case x :: xs => '{ ($f).apply(${x}); ${ xs.unrolledForeach(f) } } case Nil => '{} } @@ -128,7 +130,7 @@ package liftable { object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = new Liftable[Array[T]] { - def toExpr(arr: Array[T]): Expr[Array[T]] = '{ new Array[$t](${arr.length})($ct) } + def toExpr(arr: Array[T])(implicit st: StagingContext): Expr[Array[T]] = '{ new Array[$t](${arr.length})($ct) } } } diff --git a/tests/run-with-compiler/quote-nested-1.scala b/tests/run-with-compiler/quote-nested-1.scala index 78b4c52e7508..a71262d7717e 100644 --- a/tests/run-with-compiler/quote-nested-1.scala +++ b/tests/run-with-compiler/quote-nested-1.scala @@ -2,8 +2,7 @@ import quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = '{ '{3} } - println(q.show) + val tb = Toolbox.make + println(tb.show('{ '(3) })) } } diff --git a/tests/run-with-compiler/quote-nested-2.scala b/tests/run-with-compiler/quote-nested-2.scala index 6d5eca0029fd..1f045f94bb5f 100644 --- a/tests/run-with-compiler/quote-nested-2.scala +++ b/tests/run-with-compiler/quote-nested-2.scala @@ -4,11 +4,10 @@ object Test { def main(args: Array[String]): Unit = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = '{ + val tb = Toolbox.make + println(tb.show( '{ val a = '{4} '{${a}} - } - - println(q.show) + })) } } diff --git a/tests/run-with-compiler/quote-nested-3.scala b/tests/run-with-compiler/quote-nested-3.scala index 827ce44d5cd2..4a2921ca180b 100644 --- a/tests/run-with-compiler/quote-nested-3.scala +++ b/tests/run-with-compiler/quote-nested-3.scala @@ -2,18 +2,19 @@ import quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) +implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = '{ - type T = String - val x = "foo" - ${ - val y = 'x - '{ val z: T = $y } + val tb = Toolbox.make + println(tb.show { + '{ + type T = String + val x = "foo" + ${ + val y = 'x + '{ val z: T = $y } + } + x } - x - } - - println(q.show) + }) } } diff --git a/tests/run-with-compiler/quote-nested-4.scala b/tests/run-with-compiler/quote-nested-4.scala index 850095f2ace3..6a7064410a0c 100644 --- a/tests/run-with-compiler/quote-nested-4.scala +++ b/tests/run-with-compiler/quote-nested-4.scala @@ -1,14 +1,14 @@ -import quoted._ +import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - - val q = '{ - val t = '[String] - t - } - - println(q.show) + val tb = Toolbox.make + println(tb.show { + val q = '{ + val t = '[String] + t + } + q + }) } } diff --git a/tests/run-with-compiler/quote-nested-5.scala b/tests/run-with-compiler/quote-nested-5.scala index 3ba3f6a43bd1..b0d1c6164a4d 100644 --- a/tests/run-with-compiler/quote-nested-5.scala +++ b/tests/run-with-compiler/quote-nested-5.scala @@ -4,14 +4,14 @@ object Test { def main(args: Array[String]): Unit = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = '{ - val a = '{4} - ${'{ - '{${a}} - }} - - } - - println(q.show) + val tb = Toolbox.make + println(tb.show { + '{ + val a = '{4} + ${'{ + '{${a}} + }} + } + }) } } diff --git a/tests/run-with-compiler/quote-owners-2.scala b/tests/run-with-compiler/quote-owners-2.scala index 0b19e8a32b3f..cf728368f494 100644 --- a/tests/run-with-compiler/quote-owners-2.scala +++ b/tests/run-with-compiler/quote-owners-2.scala @@ -3,13 +3,13 @@ import quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = f(g(Type.IntTag)) - println(q.run) - println(q.show) + val tb = Toolbox.make + def q: Staged[Int] = f(g(Type.IntTag)) + println(tb.run(q)) + println(tb.show(q)) } - def f(t: Type[List[Int]]): Expr[Int] = '{ + def f(t: Type[List[Int]]): Staged[Int] = '{ def ff: Int = { val a: $t = { type T = $t @@ -21,5 +21,5 @@ object Test { ff } - def g[T](a: Type[T]): Type[List[T]] = '[List[$a]] + def g[T](a: Type[T])(implicit st: StagingContext): Type[List[T]] = '[List[$a]] } diff --git a/tests/run-with-compiler/quote-owners.scala b/tests/run-with-compiler/quote-owners.scala index 9a6f4bbd7d6d..836f121e7aed 100644 --- a/tests/run-with-compiler/quote-owners.scala +++ b/tests/run-with-compiler/quote-owners.scala @@ -2,20 +2,20 @@ import quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = f - println(q.run) - println(q.show) + val tb = Toolbox.make + def q: Staged[Int] = f + println(tb.run(q)) + println(tb.show(q)) } - def f: Expr[Int] = '{ + def f: Staged[Int] = '{ def ff: Int = { $g } ff } - def g: Expr[Int] = '{ + def g: Staged[Int] = '{ val a = 9 a + 0 } diff --git a/tests/run-with-compiler/quote-run-2.check b/tests/run-with-compiler/quote-run-2.check index 0821d5fb001e..7e9019bb7aa9 100644 --- a/tests/run-with-compiler/quote-run-2.check +++ b/tests/run-with-compiler/quote-run-2.check @@ -11,11 +11,11 @@ { val y: scala.Double = 5.0.*(5.0) y.*({ - val y$2: scala.Double = y.*(y) - y$2.*({ - val y$3: scala.Double = y$2.*(y$2) - val y$4: scala.Double = y$3.*(y$3) - y$4 + val y: scala.Double = y.*(y) + y.*({ + val y: scala.Double = y.*(y) + val y: scala.Double = y.*(y) + y }) }) } diff --git a/tests/run-with-compiler/quote-run-2.scala b/tests/run-with-compiler/quote-run-2.scala index 25e527baaafb..ef98fc6fd241 100644 --- a/tests/run-with-compiler/quote-run-2.scala +++ b/tests/run-with-compiler/quote-run-2.scala @@ -3,17 +3,17 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def powerCode(n: Int, x: Expr[Double]): Expr[Double] = - if (n == 0) '{1.0} + val tb = Toolbox.make + def powerCode(n: Int, x: Expr[Double]): Staged[Double] = + if (n == 0) '(1.0) else if (n == 1) x else if (n % 2 == 0) '{ { val y = $x * $x; ${powerCode(n / 2, 'y)} } } else '{ $x * ${powerCode(n - 1, x)} } - println(powerCode(0, '{5}).show) - println(powerCode(1, '{5}).show) - println(powerCode(2, '{5}).show) - println(powerCode(3, '{5}).show) - println(powerCode(22, '{5}).show) + println(tb.run(powerCode(0, '{5}).show.toExpr)) + println(tb.run(powerCode(1, '{5}).show.toExpr)) + println(tb.run(powerCode(2, '{5}).show.toExpr)) + println(tb.run(powerCode(3, '{5}).show.toExpr)) + println(tb.run(powerCode(22, '{5}).show.toExpr)) // FIXME prin unique names } } diff --git a/tests/run-with-compiler/quote-run-3.check b/tests/run-with-compiler/quote-run-3.check new file mode 100644 index 000000000000..297073879944 --- /dev/null +++ b/tests/run-with-compiler/quote-run-3.check @@ -0,0 +1,7 @@ +start +start in expr +splice: Expr(4) +end in expr +foo +res: 9 +end diff --git a/tests/run-with-compiler/quote-run-3.scala b/tests/run-with-compiler/quote-run-3.scala new file mode 100644 index 000000000000..5e74262a63cc --- /dev/null +++ b/tests/run-with-compiler/quote-run-3.scala @@ -0,0 +1,27 @@ + +import scala.quoted._ + +object Test { + def main(args: Array[String]): Unit = { + val tb = Toolbox.make + + def expr(a: Expr[Int]): Staged[Int] = '{ + val b = 3 + println("foo") + 2 + b + ~{ + println("splice: " + a) + a + } + } + println("start") + val res = tb.run { + println("start in expr") + val e = expr('(4)) + println("end in expr") + e + } + println("res: " + res) + println("end") + + } +} diff --git a/tests/run-with-compiler/quote-run-b.scala b/tests/run-with-compiler/quote-run-b.scala index 71ba388be3cd..f9b4375561cf 100644 --- a/tests/run-with-compiler/quote-run-b.scala +++ b/tests/run-with-compiler/quote-run-b.scala @@ -3,13 +3,13 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val lambdaExpr = '{ + val tb: Toolbox = Toolbox.make(getClass.getClassLoader) + def lambdaExpr: Staged[Int => Unit] = '{ (x: Int) => println("lambda(" + x + ")") } println() - val lambda = lambdaExpr.run + val lambda = tb.run(lambdaExpr) lambda(4) lambda(5) } diff --git a/tests/run-with-compiler/quote-run-c.scala b/tests/run-with-compiler/quote-run-c.scala index ddb6df723e8c..489b2447d85a 100644 --- a/tests/run-with-compiler/quote-run-c.scala +++ b/tests/run-with-compiler/quote-run-c.scala @@ -3,22 +3,24 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val classExpr = '{ + val tb: Toolbox = Toolbox.make + import tb.run + + val classExpr: Staged[Any] = '{ class A { override def toString: String = "Foo" } new A } - val classExpr2 = '{ + val classExpr2: Staged[Any] = '{ class A { override def toString: String = "Bar" } new A } - println(classExpr.run) - println(classExpr.run.getClass == classExpr.run.getClass) - println(classExpr2.run) - println(classExpr2.run.getClass) + println(run(classExpr)) + println(run(classExpr).getClass == run(classExpr).getClass) + println(run(classExpr2)) + println(run(classExpr2).getClass) } } diff --git a/tests/run-with-compiler/quote-run-constants.scala b/tests/run-with-compiler/quote-run-constants.scala index 837fb8834499..52cc1d7bef66 100644 --- a/tests/run-with-compiler/quote-run-constants.scala +++ b/tests/run-with-compiler/quote-run-constants.scala @@ -1,43 +1,40 @@ - -import scala.quoted.autolift._ - import scala.quoted._ +import scala.quoted.autolift._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def run[T](expr: Expr[T]): Unit = println(expr.run) - def show[T](expr: Expr[T]): Unit = println(expr.show) + val tb = Toolbox.make + import tb._ - run(true) - run('a') - run('\n') - run('"') - run('\'') - run('\\') - run(1) - run(2) - run(3L) - run(4.0f) - run(5.0d) - run("xyz") + println(run(true)) + println(run('a')) + println(run('\n')) + println(run('"')) + println(run('\'')) + println(run('\\')) + println(run(1)) + println(run(2)) + println(run(3L)) + println(run(4.0f)) + println(run(5.0d)) + println(run("xyz")) println("======") - show(true) - show('a') - show('\n') - show('"') - show('\'') - show('\\') - show(1) - show(2) - show(3L) - show(4.0f) - show(5.0d) - show("xyz") - show("\n\\\"'") - show("""abc - xyz""") + println(show(true)) + println(show('a')) + println(show('\n')) + println(show('"')) + println(show('\'')) + println(show('\\')) + println(show(1)) + println(show(2)) + println(show(3L)) + println(show(4.0f)) + println(show(5.0d)) + println(show("xyz")) + println(show("\n\\\"'")) + println(show("""abc + xyz""")) } } diff --git a/tests/run-with-compiler/quote-run-large.scala b/tests/run-with-compiler/quote-run-large.scala index a9772aeb6b62..67600a9ef2c6 100644 --- a/tests/run-with-compiler/quote-run-large.scala +++ b/tests/run-with-compiler/quote-run-large.scala @@ -1,9 +1,9 @@ -import scala.quoted.Exprs.TastyExpr +import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - val a = '{ // ' + def a: Staged[Any] = '{ // ' class Foo(x: Int) { override def toString(): String = s"Foo($x)" def foo1: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x @@ -60,9 +60,7 @@ object Test { new Foo(5) } - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - - assert(a.asInstanceOf[TastyExpr[_]].tasty.size > 1, "Test should be testing a quote with TastyExpr encoded in more than one string") - a.show // Force unpiclking of the expression + val tb = Toolbox.make + tb.show(a) // Force unpiclking of the expression } } \ No newline at end of file diff --git a/tests/run-with-compiler/quote-run-many.scala b/tests/run-with-compiler/quote-run-many.scala index 2a4644f523df..7a0c5d8c328c 100644 --- a/tests/run-with-compiler/quote-run-many.scala +++ b/tests/run-with-compiler/quote-run-many.scala @@ -3,12 +3,12 @@ import scala.quoted.autolift._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def expr(i: Int) = '{ + val tb = Toolbox.make(getClass.getClassLoader) + def expr(i: Int): Staged[Int] = '{ val a = 3 + ${i} 2 + a } for (i <- 0 to 200) - expr(i).run + tb.run(expr(i)) } } diff --git a/tests/run-with-compiler/quote-run-staged-interpreter.scala b/tests/run-with-compiler/quote-run-staged-interpreter.scala index 57f6fe6d128c..4485a3542031 100644 --- a/tests/run-with-compiler/quote-run-staged-interpreter.scala +++ b/tests/run-with-compiler/quote-run-staged-interpreter.scala @@ -11,7 +11,7 @@ enum Exp { object Test { import Exp._ - def compile(e: Exp, env: Map[String, Expr[Int]], keepLets: Boolean): Expr[Int] = { + def compile(e: Exp, env: Map[String, Expr[Int]], keepLets: Boolean): Staged[Int] = { def compileImpl(e: Exp, env: Map[String, Expr[Int]]): Expr[Int] = e match { case Num(n) => n case Plus(e1, e2) => '{${compileImpl(e1, env)} + ${compileImpl(e2, env)}} @@ -27,30 +27,31 @@ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make + import tb._ + val exp = Plus(Plus(Num(2), Var("x")), Num(4)) val letExp = Let("x", Num(3), exp) - val res1 = '{ (x: Int) => ${compile(exp, Map("x" -> 'x), false)} } - + val res1: Staged[Int => Int] = '{ (x: Int) => ${compile(exp, Map("x" -> 'x), false)} } - println(res1.show) + println(show(res1)) - val fn = res1.run + val fn = run(res1) println(fn(0)) println(fn(2)) println(fn(3)) println("---") - val res2 = compile(letExp, Map(), false) - println(res2.show) - println(res2.run) + def res2: Staged[Int] = compile(letExp, Map(), false) + println(show(res2)) + println(run(res2)) println("---") - val res3 = compile(letExp, Map(), true) - println(res3.show) - println(res3.run) + val res3: Staged[Int] = compile(letExp, Map(), true) + println(show(res3)) + println(run(res3)) } } diff --git a/tests/run-with-compiler/quote-run-with-settings.scala b/tests/run-with-compiler/quote-run-with-settings.scala index 5e73f65dfafd..20c0a93adcec 100644 --- a/tests/run-with-compiler/quote-run-with-settings.scala +++ b/tests/run-with-compiler/quote-run-with-settings.scala @@ -5,14 +5,15 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val expr = '{ + val tb = Toolbox.make(getClass.getClassLoader) + + def expr: Staged[Int] = '{ val a = 3 println("foo") 2 + a } - println(expr.show) - println(expr.run) + println(tb.show(expr)) + println(tb.run(expr)) println() val outDir = Paths.get("out/out-quoted-1") @@ -23,7 +24,7 @@ object Test { { implicit val settings = Toolbox.Settings.make(outDir = Some(outDir.toString)) implicit val toolbox2: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(expr.run) + println(toolbox2.run(expr)) assert(Files.exists(classFile)) } } diff --git a/tests/run-with-compiler/quote-run.scala b/tests/run-with-compiler/quote-run.scala index b7d38de71b11..d88023784372 100644 --- a/tests/run-with-compiler/quote-run.scala +++ b/tests/run-with-compiler/quote-run.scala @@ -2,14 +2,14 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val expr = '{ + val tb = Toolbox.make(getClass.getClassLoader) + def expr: Staged[Int] = '{ val a = 3 println("foo") 2 + a } - println(expr.run) - println(expr.run) - println(expr.show) + println(tb.run(expr)) + println(tb.run(expr)) + println(tb.show(expr)) } } diff --git a/tests/run-with-compiler/quote-show-blocks.scala b/tests/run-with-compiler/quote-show-blocks.scala index c5fb45d1ce3a..98ff36dd9fb2 100644 --- a/tests/run-with-compiler/quote-show-blocks.scala +++ b/tests/run-with-compiler/quote-show-blocks.scala @@ -3,19 +3,19 @@ import scala.quoted.autolift._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def a(n: Int, x: Expr[Unit]): Expr[Unit] = + val tb = Toolbox.make(getClass.getClassLoader) + def a(n: Int, x: Expr[Unit]): Staged[Unit] = if (n == 0) x else a(n - 1, '{ println(${n}); $x }) - println(a(5, '{}).show) + println(tb.show(a(5, '{}))) - def b(n: Int, x: Expr[Unit]): Expr[Unit] = + def b(n: Int, x: Expr[Unit]): Staged[Unit] = if (n == 0) x else b(n - 1, '{ $x; println(${n}) }) - println(b(5, '{}).show) + println(tb.show(b(5, '{}))) } } diff --git a/tests/run-with-compiler/quote-two-captured-ref.scala b/tests/run-with-compiler/quote-two-captured-ref.scala index 79dea2f4482f..2f0b53c01ab3 100644 --- a/tests/run-with-compiler/quote-two-captured-ref.scala +++ b/tests/run-with-compiler/quote-two-captured-ref.scala @@ -2,8 +2,8 @@ import quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - val q = '{ + val tb = Toolbox.make(getClass.getClassLoader) + println(tb.show('{ val x = 1 println(${ println(1) @@ -11,8 +11,6 @@ object Test { val b = 'x '{ $a + $b } }) - } - - println(q.show) + })) } } diff --git a/tests/run-with-compiler/quote-type-tags.scala b/tests/run-with-compiler/quote-type-tags.scala index 36534c041b03..25a02ed9690f 100644 --- a/tests/run-with-compiler/quote-type-tags.scala +++ b/tests/run-with-compiler/quote-type-tags.scala @@ -2,20 +2,23 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def asof[T: Type, U](x: Expr[T], t: Type[U]): Expr[U] = '{$x.asInstanceOf[$t]} - println(asof('{}, '[Unit]).show) - println(asof('{true}, '[Boolean]).show) - println(asof('{0.toByte}, '[Byte]).show) - println(asof('{ 'a' }, '[Char]).show) - println(asof('{1.toShort}, '[Short]).show) - println(asof('{2}, '[Int]).show) - println(asof('{3L}, '[Long]).show) - println(asof('{4f}, '[Float]).show) - println(asof('{5d}, '[Double]).show) + def asof[T, U](x: Expr[T], t: Type[U]): Staged[U] = + '{$x.asInstanceOf[$t]} + + println(tb.show(asof('{}, '[Unit]))) + println(tb.show(asof('{true}, '[Boolean]))) + println(tb.show(asof('{0.toByte}, '[Byte]))) + println(tb.show(asof('{ 'a' }, '[Char]))) + println(tb.show(asof('{1.toShort}, '[Short]))) + println(tb.show(asof('{2}, '[Int]))) + println(tb.show(asof('{3L}, '[Long]))) + println(tb.show(asof('{4f}, '[Float]))) + println(tb.show(asof('{5d}, '[Double]))) - println(asof('{5d}, '[Boolean]).show) // Will clearly fail at runtime but the code can be generated + println(tb.show(asof('{5d}, '[Boolean]))) // Will clearly fail at runtime but the code can be generated } } diff --git a/tests/run-with-compiler/quote-unrolled-foreach.scala b/tests/run-with-compiler/quote-unrolled-foreach.scala index 89cee178f3cd..b0d9ff5d9c65 100644 --- a/tests/run-with-compiler/quote-unrolled-foreach.scala +++ b/tests/run-with-compiler/quote-unrolled-foreach.scala @@ -3,47 +3,40 @@ import scala.quoted._ import scala.quoted.autolift._ object Test { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = { - val code1 = '{ (arr: Array[Int], f: Int => Unit) => ${ foreach1('arr, 'f) } } - println(code1.show) + println(tb.show('{ (arr: Array[Int], f: Int => Unit) => ${ foreach1('arr, 'f) } })) println() - val code1Tpe = '{ (arr: Array[String], f: String => Unit) => ${ foreach1Tpe1('arr, 'f) } } - println(code1Tpe.show) + println(tb.show('{ (arr: Array[String], f: String => Unit) => ${ foreach1Tpe1('arr, 'f) } })) println() - val code1Tpe2 = '{ (arr: Array[String], f: String => Unit) => ${ foreach1Tpe1('arr, 'f) } } - println(code1Tpe2.show) + println(tb.show('{ (arr: Array[String], f: String => Unit) => ${ foreach1Tpe1('arr, 'f) } })) println() - val code2 = '{ (arr: Array[Int]) => ${ foreach1('arr, '{i => System.out.println(i)}) } } - println(code2.show) + println(tb.show('{ (arr: Array[Int]) => ${ foreach1('arr, '{i => System.out.println(i)}) } })) println() - val code3 = '{ (arr: Array[Int], f: Int => Unit) => ${ foreach3('arr, 'f) } } - println(code3.show) + println(tb.show('{ (arr: Array[Int], f: Int => Unit) => ${ foreach3('arr, 'f) } })) println() - val code4 = '{ (arr: Array[Int], f: Int => Unit) => ${ foreach4('arr, 'f, 4) } } - println(code4.show) + println(tb.show('{ (arr: Array[Int], f: Int => Unit) => ${foreach4('(arr), '(f), 4)} })) println() val liftedArray: Expr[Array[Int]] = Array(1, 2, 3, 4) - println(liftedArray.show) + println(tb.show(liftedArray)) println() - - def printAll(arr: Array[Int]) = '{ + def printAll(arr: Array[Int]): Staged[Unit] = '{ val arr1 = ${ arr } ${ foreach1('arr1, '{x => println(x)}) } } - println(printAll(Array(1, 3, 4, 5)).show) + println(tb.show(printAll(Array(1, 3, 4, 5)))) } - def foreach1(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ + def foreach1(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Staged[Unit] = '{ val size = ($arrRef).length var i = 0 while (i < size) { @@ -53,7 +46,7 @@ object Test { } } - def foreach1Tpe1[T](arrRef: Expr[Array[T]], f: Expr[T => Unit])(implicit t: Type[T]): Expr[Unit] = '{ + def foreach1Tpe1[T](arrRef: Expr[Array[T]], f: Expr[T => Unit])(implicit t: Type[T]): Staged[Unit] = '{ val size = ($arrRef).length var i = 0 while (i < size) { @@ -63,7 +56,7 @@ object Test { } } - def foreach1Tpe2[T: Type](arrRef: Expr[Array[T]], f: Expr[T => Unit]): Expr[Unit] = '{ + def foreach1Tpe2[T: Type](arrRef: Expr[Array[T]], f: Expr[T => Unit]): Staged[Unit] = '{ val size = ($arrRef).length var i = 0 while (i < size) { @@ -73,7 +66,7 @@ object Test { } } - def foreach2(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ + def foreach2(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Staged[Unit] = '{ val size = ($arrRef).length var i = 0 while (i < size) { @@ -83,7 +76,7 @@ object Test { } } - def foreach3(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ + def foreach3(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Staged[Unit] = '{ val size = ($arrRef).length var i = 0 if (size % 3 != 0) throw new Exception("...")// for simplicity of the implementation @@ -95,7 +88,7 @@ object Test { } } - def foreach3_2(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ + def foreach3_2(arrRef: Expr[Array[Int]], f: Expr[Int => Unit]): Staged[Unit] = '{ val size = ($arrRef).length var i = 0 if (size % 3 != 0) throw new Exception("...")// for simplicity of the implementation @@ -107,7 +100,7 @@ object Test { } } - def foreach4(arrRef: Expr[Array[Int]], f: Expr[Int => Unit], unrollSize: Int): Expr[Unit] = '{ + def foreach4(arrRef: Expr[Array[Int]], f: Expr[Int => Unit], unrollSize: Int): Staged[Unit] = '{ val size = ($arrRef).length var i = 0 if (size % ${unrollSize} != 0) throw new Exception("...") // for simplicity of the implementation @@ -118,14 +111,14 @@ object Test { } implicit object ArrayIntIsLiftable extends Liftable[Array[Int]] { - override def toExpr(x: Array[Int]): Expr[Array[Int]] = '{ + override def toExpr(x: Array[Int])(implicit st: StagingContext): Expr[Array[Int]] = '{ val array = new Array[Int](${x.length}) ${ foreachInRange(0, x.length)(i => '{ array(${i}) = ${x(i)}}) } array } } - def foreachInRange(start: Int, end: Int)(f: Int => Expr[Unit]): Expr[Unit] = { + def foreachInRange(start: Int, end: Int)(f: Int => Expr[Unit]): Staged[Unit] = { @tailrec def unroll(i: Int, acc: Expr[Unit]): Expr[Unit] = if (i < end) unroll(i + 1, '{ $acc; ${f(i)} }) else acc if (start < end) unroll(start + 1, f(start)) else '{} diff --git a/tests/run-with-compiler/quote-var.scala b/tests/run-with-compiler/quote-var.scala index 02a79410cfb8..a8675a5539ea 100644 --- a/tests/run-with-compiler/quote-var.scala +++ b/tests/run-with-compiler/quote-var.scala @@ -3,18 +3,18 @@ import scala.quoted._ object Test { sealed trait Var { - def get: Expr[String] - def update(x: Expr[String]): Expr[Unit] + def get: Staged[String] + def update(x: Expr[String]): Staged[Unit] } object Var { - def apply(init: Expr[String])(body: Var => Expr[String]): Expr[String] = '{ + def apply(init: Expr[String])(body: Var => Expr[String]): Staged[String] = '{ var x = $init ${ body( new Var { - def get: Expr[String] = 'x - def update(e: Expr[String]): Expr[Unit] = '{ x = $e } + def get: Staged[String] = 'x + def update(e: Expr[String]): Staged[Unit] = '{ x = $e } } ) } @@ -22,7 +22,7 @@ object Test { } - def test1(): Expr[String] = Var('{"abc"}) { x => + def test1(): Staged[String] = Var('{"abc"}) { x => '{ ${ x.update('{"xyz"}) } ${ x.get } @@ -30,8 +30,8 @@ object Test { } def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - println(test1().run) + val tb: Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + println(tb.run(test1())) } } diff --git a/tests/run-with-compiler/shonan-hmm-simple.scala b/tests/run-with-compiler/shonan-hmm-simple.scala index 3b5a0373159a..1b22b3b581eb 100644 --- a/tests/run-with-compiler/shonan-hmm-simple.scala +++ b/tests/run-with-compiler/shonan-hmm-simple.scala @@ -17,7 +17,7 @@ class RingInt extends Ring[Int] { val mul = (x, y) => x * y } -class RingIntExpr extends Ring[Expr[Int]] { +class RingIntExpr(implicit st: StagingContext) extends Ring[Expr[Int]] { val zero = '{0} val one = '{1} val add = (x, y) => '{$x + $y} @@ -36,14 +36,14 @@ class RingComplex[U](u: Ring[U]) extends Ring[Complex[U]] { sealed trait PV[T] { def expr(implicit l: Liftable[T]): Expr[T] } -case class Sta[T](x: T) extends PV[T] { +case class Sta[T](x: T)(implicit st: StagingContext) extends PV[T] { def expr(implicit l: Liftable[T]): Expr[T] = x } case class Dyn[T](x: Expr[T]) extends PV[T] { def expr(implicit l: Liftable[T]): Expr[T] = x } -class RingPV[U: Liftable](u: Ring[U], eu: Ring[Expr[U]]) extends Ring[PV[U]] { +class RingPV[U: Liftable](u: Ring[U], eu: Ring[Expr[U]])(implicit st: StagingContext) extends Ring[PV[U]] { val zero: PV[U] = Sta(u.zero) val one: PV[U] = Sta(u.one) val add = (x: PV[U], y: PV[U]) => (x, y) match { @@ -72,7 +72,7 @@ case class Complex[T](re: T, im: T) object Complex { implicit def isLiftable[T: Type: Liftable]: Liftable[Complex[T]] = new Liftable[Complex[T]] { - def toExpr(comp: Complex[T]): Expr[Complex[T]] = '{Complex(${comp.re}, ${comp.im})} + def toExpr(comp: Complex[T])(implicit st: StagingContext): Expr[Complex[T]] = '{Complex(${comp.re}, ${comp.im})} } } @@ -98,7 +98,7 @@ class StaticVecOps[T] extends VecOps[Int, T] { } } -class ExprVecOps[T: Type] extends VecOps[Expr[Int], Expr[T]] { +class ExprVecOps[T: Type](implicit st: StagingContext) extends VecOps[Expr[Int], Expr[T]] { val reduce: ((Expr[T], Expr[T]) => Expr[T], Expr[T], Vec[Expr[Int], Expr[T]]) => Expr[T] = (plus, zero, vec) => '{ var sum = $zero var i = 0 @@ -116,7 +116,7 @@ class Blas1[Idx, T](r: Ring[T], ops: VecOps[Idx, T]) { object Test { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = { val arr1 = Array(0, 1, 2, 4, 8) val arr2 = Array(1, 0, 1, 0, 1) @@ -141,17 +141,17 @@ object Test { println(res2) println() - val blasStaticIntExpr = new Blas1(new RingIntExpr, new StaticVecOps) - val resCode1 = blasStaticIntExpr.dot( + def blasStaticIntExpr(implicit st: StagingContext) = new Blas1(new RingIntExpr, new StaticVecOps) + def resCode1: Staged[Int] = blasStaticIntExpr.dot( vec1.map(_.toExpr), vec2.map(_.toExpr) ) - println(resCode1.show) - println(resCode1.run) + println(tb.show(resCode1)) + println(tb.run(resCode1)) println() - val blasExprIntExpr = new Blas1(new RingIntExpr, new ExprVecOps) - val resCode2: Expr[(Array[Int], Array[Int]) => Int] = '{ + def blasExprIntExpr(implicit st: StagingContext) = new Blas1(new RingIntExpr, new ExprVecOps) + def resCode2: Staged[(Array[Int], Array[Int]) => Int] = '{ (arr1, arr2) => if (arr1.length != arr2.length) throw new Exception("...") ${ @@ -161,21 +161,21 @@ object Test { ) } } - println(resCode2.show) - println(resCode2.run.apply(arr1, arr2)) + println(tb.show(resCode2)) + println(tb.run(resCode2).apply(arr1, arr2)) println() - val blasStaticIntPVExpr = new Blas1(new RingPV[Int](new RingInt, new RingIntExpr), new StaticVecOps) - val resCode3 = blasStaticIntPVExpr.dot( + def blasStaticIntPVExpr(implicit st: StagingContext) = new Blas1(new RingPV[Int](new RingInt, new RingIntExpr), new StaticVecOps) + def resCode3: Staged[Int] = blasStaticIntPVExpr.dot( vec1.map(i => Dyn(i)), vec2.map(i => Sta(i)) ).expr - println(resCode3.show) - println(resCode3.run) + println(tb.show(resCode3)) + println(tb.run(resCode3)) println() - val blasExprIntPVExpr = new Blas1(new RingPV[Int](new RingInt, new RingIntExpr), new StaticVecOps) - val resCode4: Expr[Array[Int] => Int] = '{ + def blasExprIntPVExpr(implicit st: StagingContext) = new Blas1(new RingPV[Int](new RingInt, new RingIntExpr), new StaticVecOps) + def resCode4: Staged[Array[Int] => Int] = '{ arr => if (arr.length != ${vec2.size}) throw new Exception("...") ${ @@ -186,13 +186,13 @@ object Test { } } - println(resCode4.show) - println(resCode4.run.apply(arr1)) + println(tb.show(resCode4)) + println(tb.run(resCode4).apply(arr1)) println() import Complex.isLiftable - val blasExprComplexPVInt = new Blas1[Int, Complex[PV[Int]]](new RingComplex(new RingPV[Int](new RingInt, new RingIntExpr)), new StaticVecOps) - val resCode5: Expr[Array[Complex[Int]] => Complex[Int]] = '{ + def blasExprComplexPVInt(implicit st: StagingContext) = new Blas1[Int, Complex[PV[Int]]](new RingComplex(new RingPV[Int](new RingInt, new RingIntExpr)), new StaticVecOps) + def resCode5: Staged[Array[Complex[Int]] => Complex[Int]] = '{ arr => if (arr.length != ${cmpxVec2.size}) throw new Exception("...") ${ @@ -203,17 +203,17 @@ object Test { '{Complex(${cpx.re.expr}, ${cpx.im.expr})} } } - println(resCode5.show) - println(resCode5.run.apply(cmpxArr1)) + println(tb.show(resCode5)) + println(tb.run(resCode5).apply(cmpxArr1)) println() - val RingPVInt = new RingPV[Int](new RingInt, new RingIntExpr) + def RingPVInt(implicit st: StagingContext) = new RingPV[Int](new RingInt, new RingIntExpr) // Staged loop of dot product on vectors of Int or Expr[Int] - val dotIntOptExpr = new Blas1(RingPVInt, new StaticVecOps).dot + def dotIntOptExpr(implicit st: StagingContext) = new Blas1(RingPVInt, new StaticVecOps).dot // will generate the code '{ ((arr: scala.Array[scala.Int]) => arr.apply(1).+(arr.apply(3))) } - val staticVec = Vec[Int, PV[Int]](5, i => Sta((i % 2))) - val code = '{(arr: Array[Int]) => ${dotIntOptExpr(Vec(5, i => Dyn('{arr(${i})})), staticVec).expr} } - println(code.show) + def staticVec(implicit st: StagingContext) = Vec[Int, PV[Int]](5, i => Sta((i % 2))) + def code: Staged[Array[Int] => Int] = '{(arr: Array[Int]) => ${dotIntOptExpr(implicitly)(Vec(5, i => Dyn('{arr(${i})})), staticVec).expr} } + println(tb.show(code)) println() } diff --git a/tests/run-with-compiler/shonan-hmm.check b/tests/run-with-compiler/shonan-hmm.check index f39b702f17ce..d2c7eb5ec5d3 100644 --- a/tests/run-with-compiler/shonan-hmm.check +++ b/tests/run-with-compiler/shonan-hmm.check @@ -20,10 +20,10 @@ List(25, 30, 20, 43, 44) while (i.<(n)) { vout.update(i, { var sum: scala.Int = 0 - var i$2: scala.Int = 0 - while (i$2.<(m)) { - sum = sum.+(v.apply(i$2).*(a.apply(i).apply(i$2))) - i$2 = i$2.+(1) + var i: scala.Int = 0 + while (i.<(m)) { + sum = sum.+(v.apply(i).*(a.apply(i).apply(i))) + i = i.+(1) } (sum: scala.Int) @@ -48,49 +48,49 @@ List(25, 30, 20, 43, 44) val arr: scala.Array[scala.Array[scala.Int]] = { val array: scala.Array[scala.Array[scala.Int]] = dotty.runtime.Arrays.newGenericArray[scala.Array[scala.Int]](5)(scala.reflect.ClassTag.apply[scala.Array[scala.Int]](scala.Predef.classOf[scala.Array[scala.Int]])) array.update(0, { - val array$2: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$2.update(0, 5) - array$2.update(1, 0) - array$2.update(2, 0) - array$2.update(3, 5) - array$2.update(4, 0) - array$2 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 5) + array.update(1, 0) + array.update(2, 0) + array.update(3, 5) + array.update(4, 0) + array }) array.update(1, { - val array$3: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$3.update(0, 0) - array$3.update(1, 0) - array$3.update(2, 10) - array$3.update(3, 0) - array$3.update(4, 0) - array$3 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 10) + array.update(3, 0) + array.update(4, 0) + array }) array.update(2, { - val array$4: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$4.update(0, 0) - array$4.update(1, 10) - array$4.update(2, 0) - array$4.update(3, 0) - array$4.update(4, 0) - array$4 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 10) + array.update(2, 0) + array.update(3, 0) + array.update(4, 0) + array }) array.update(3, { - val array$5: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$5.update(0, 0) - array$5.update(1, 0) - array$5.update(2, 2) - array$5.update(3, 3) - array$5.update(4, 5) - array$5 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 2) + array.update(3, 3) + array.update(4, 5) + array }) array.update(4, { - val array$6: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$6.update(0, 0) - array$6.update(1, 0) - array$6.update(2, 3) - array$6.update(3, 0) - array$6.update(4, 7) - array$6 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 3) + array.update(3, 0) + array.update(4, 7) + array }) array } @@ -111,49 +111,49 @@ List(25, 30, 20, 43, 44) val arr: scala.Array[scala.Array[scala.Int]] = { val array: scala.Array[scala.Array[scala.Int]] = dotty.runtime.Arrays.newGenericArray[scala.Array[scala.Int]](5)(scala.reflect.ClassTag.apply[scala.Array[scala.Int]](scala.Predef.classOf[scala.Array[scala.Int]])) array.update(0, { - val array$2: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$2.update(0, 5) - array$2.update(1, 0) - array$2.update(2, 0) - array$2.update(3, 5) - array$2.update(4, 0) - array$2 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 5) + array.update(1, 0) + array.update(2, 0) + array.update(3, 5) + array.update(4, 0) + array }) array.update(1, { - val array$3: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$3.update(0, 0) - array$3.update(1, 0) - array$3.update(2, 10) - array$3.update(3, 0) - array$3.update(4, 0) - array$3 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 10) + array.update(3, 0) + array.update(4, 0) + array }) array.update(2, { - val array$4: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$4.update(0, 0) - array$4.update(1, 10) - array$4.update(2, 0) - array$4.update(3, 0) - array$4.update(4, 0) - array$4 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 10) + array.update(2, 0) + array.update(3, 0) + array.update(4, 0) + array }) array.update(3, { - val array$5: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$5.update(0, 0) - array$5.update(1, 0) - array$5.update(2, 2) - array$5.update(3, 3) - array$5.update(4, 5) - array$5 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 2) + array.update(3, 3) + array.update(4, 5) + array }) array.update(4, { - val array$6: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$6.update(0, 0) - array$6.update(1, 0) - array$6.update(2, 3) - array$6.update(3, 0) - array$6.update(4, 7) - array$6 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 3) + array.update(3, 0) + array.update(4, 7) + array }) array } @@ -174,49 +174,49 @@ List(25, 30, 20, 43, 44) val arr: scala.Array[scala.Array[scala.Int]] = { val array: scala.Array[scala.Array[scala.Int]] = dotty.runtime.Arrays.newGenericArray[scala.Array[scala.Int]](5)(scala.reflect.ClassTag.apply[scala.Array[scala.Int]](scala.Predef.classOf[scala.Array[scala.Int]])) array.update(0, { - val array$2: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$2.update(0, 5) - array$2.update(1, 0) - array$2.update(2, 0) - array$2.update(3, 5) - array$2.update(4, 0) - array$2 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 5) + array.update(1, 0) + array.update(2, 0) + array.update(3, 5) + array.update(4, 0) + array }) array.update(1, { - val array$3: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$3.update(0, 0) - array$3.update(1, 0) - array$3.update(2, 10) - array$3.update(3, 0) - array$3.update(4, 0) - array$3 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 10) + array.update(3, 0) + array.update(4, 0) + array }) array.update(2, { - val array$4: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$4.update(0, 0) - array$4.update(1, 10) - array$4.update(2, 0) - array$4.update(3, 0) - array$4.update(4, 0) - array$4 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 10) + array.update(2, 0) + array.update(3, 0) + array.update(4, 0) + array }) array.update(3, { - val array$5: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$5.update(0, 0) - array$5.update(1, 0) - array$5.update(2, 2) - array$5.update(3, 3) - array$5.update(4, 5) - array$5 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 2) + array.update(3, 3) + array.update(4, 5) + array }) array.update(4, { - val array$6: scala.Array[scala.Int] = new scala.Array[scala.Int](5) - array$6.update(0, 0) - array$6.update(1, 0) - array$6.update(2, 3) - array$6.update(3, 0) - array$6.update(4, 7) - array$6 + val array: scala.Array[scala.Int] = new scala.Array[scala.Int](5) + array.update(0, 0) + array.update(1, 0) + array.update(2, 3) + array.update(3, 0) + array.update(4, 7) + array }) array } @@ -299,4 +299,4 @@ List(25, 30, 20, 43, 44) }) vout.update(4, v.apply(2).*(3).+(v.apply(4).*(7))) }) -} +} \ No newline at end of file diff --git a/tests/run-with-compiler/shonan-hmm/Complex.scala b/tests/run-with-compiler/shonan-hmm/Complex.scala index b73e0bbfade0..fe009cc789ab 100644 --- a/tests/run-with-compiler/shonan-hmm/Complex.scala +++ b/tests/run-with-compiler/shonan-hmm/Complex.scala @@ -5,11 +5,10 @@ case class Complex[T](re: T, im: T) object Complex { implicit def complexIsLiftable[T: Type: Liftable]: Liftable[Complex[T]] = new Liftable { - def toExpr(c: Complex[T]): Expr[Complex[T]] = '{ Complex(${c.re.toExpr}, ${c.im.toExpr}) } + def toExpr(c: Complex[T])(implicit st: StagingContext): Expr[Complex[T]] = '{ Complex(${c.re.toExpr}, ${c.im.toExpr}) } } - def of_complex_expr(x: Expr[Complex[Int]]): Complex[Expr[Int]] = Complex('{$x.re}, '{$x.im}) - def of_expr_complex(x: Complex[Expr[Int]]): Expr[Complex[Int]] = '{Complex(${x.re}, ${x.im})} + def of_complex_expr(x: Expr[Complex[Int]])(implicit st: StagingContext): Complex[Expr[Int]] = Complex('{$x.re}, '{$x.im}) + def of_expr_complex(x: Complex[Expr[Int]]): Staged[Complex[Int]] = '{Complex(${x.re}, ${x.im})} - -} \ No newline at end of file +} diff --git a/tests/run-with-compiler/shonan-hmm/Lifters.scala b/tests/run-with-compiler/shonan-hmm/Lifters.scala index 56d8eb0a4e93..1a308fdf969c 100644 --- a/tests/run-with-compiler/shonan-hmm/Lifters.scala +++ b/tests/run-with-compiler/shonan-hmm/Lifters.scala @@ -6,21 +6,26 @@ import scala.quoted._ import scala.quoted.autolift._ object Lifters { - implicit def LiftedClassTag[T: Type](implicit ct: ClassTag[T]): Expr[ClassTag[T]] = { - '{ ClassTag(${ct.runtimeClass })} + + implicit def ClassTagIsLiftable[T : Type](implicit ct: ClassTag[T]): Liftable[ClassTag[T]] = new Liftable[ClassTag[T]] { + override def toExpr(ct: ClassTag[T])(implicit st: StagingContext): Expr[ClassTag[T]] = '{ ClassTag(${ct.runtimeClass })} } - implicit def ArrayIsLiftable[T : Type: ClassTag](implicit l: Liftable[T]): Liftable[Array[T]] = arr => '{ - val array = new Array[T](${arr.length})(${implicitly[Expr[ClassTag[T]]]}) - ${initArray(arr, 'array)} + implicit def ArrayIsLiftable[T : Type: ClassTag](implicit l: Liftable[T]): Liftable[Array[T]] = new Liftable[Array[T]] { + override def toExpr(arr: Array[T])(implicit st: StagingContext): Expr[Array[T]] = '{ + val array = new Array[T](${arr.length})(${implicitly[Expr[ClassTag[T]]]}) + ${initArray(arr, 'array)} + } } - implicit def IntArrayIsLiftable: Liftable[Array[Int]] = arr => '{ - val array = new Array[Int](${arr.length}) - ${initArray(arr, 'array)} + implicit def IntArrayIsLiftable: Liftable[Array[Int]] = new Liftable[Array[Int]] { + override def toExpr(arr: Array[Int])(implicit st: StagingContext): Expr[Array[Int]] = '{ + val array = new Array[Int](${arr.length}) + ${initArray(arr, 'array)} + } } - private def initArray[T : Liftable : Type](arr: Array[T], array: Expr[Array[T]]): Expr[Array[T]] = { + private def initArray[T : Liftable : Type](arr: Array[T], array: Expr[Array[T]])(implicit st: StagingContext): Expr[Array[T]] = { UnrolledExpr.block( arr.zipWithIndex.map { case (x, i) => '{ $array(${i}) = ${x} } diff --git a/tests/run-with-compiler/shonan-hmm/MVmult.scala b/tests/run-with-compiler/shonan-hmm/MVmult.scala index 72d35144acf0..1695da85b703 100644 --- a/tests/run-with-compiler/shonan-hmm/MVmult.scala +++ b/tests/run-with-compiler/shonan-hmm/MVmult.scala @@ -18,11 +18,11 @@ object MVmult { val a_ = Vec (n, i => Vec(m, j => a(i)(j))) val v_ = Vec (n, i => v(i)) - val MV = new MVmult[Int, Int, Unit](RingInt, new StaticVecR(RingInt)) + val MV = new MVmult[Int, Int, Unit](new RingInt, new StaticVecR(new RingInt)) MV.mvmult(vout_, a_, v_) } - def mvmult_c: Expr[(Array[Int], Array[Array[Int]], Array[Int]) => Unit] = '{ + def mvmult_c: Staged[(Array[Int], Array[Array[Int]], Array[Int]) => Unit] = '{ (vout, a, v) => { val n = vout.length val m = v.length @@ -31,14 +31,14 @@ object MVmult { val a_ = Vec('n, (i: Expr[Int]) => Vec('m, (j: Expr[Int]) => '{ a($i)($j) } )) val v_ = Vec('m, (i: Expr[Int]) => '{v($i)}) - val MV = new MVmult[Expr[Int], Expr[Int], Expr[Unit]](RingIntExpr, new VecRDyn) + val MV = new MVmult[Expr[Int], Expr[Int], Expr[Unit]](new RingIntExpr, new VecRDyn) MV.mvmult(vout_, a_, v_) } } } - def mvmult_mc(n: Int, m: Int): Expr[(Array[Int], Array[Array[Int]], Array[Int]) => Unit] = { - val MV = new MVmult[Int, Expr[Int], Expr[Unit]](RingIntExpr, new VecRStaDim(RingIntExpr)) + def mvmult_mc(n: Int, m: Int): Staged[(Array[Int], Array[Array[Int]], Array[Int]) => Unit] = { + val MV = new MVmult[Int, Expr[Int], Expr[Unit]](new RingIntExpr, new VecRStaDim(new RingIntExpr)) '{ (vout, a, v) => { if (${n} != vout.length) throw new IndexOutOfBoundsException(${n.toString}) @@ -54,7 +54,7 @@ object MVmult { } } - def mvmult_ac(a: Array[Array[Int]]): Expr[(Array[Int], Array[Int]) => Unit] = { + def mvmult_ac(a: Array[Array[Int]]): Staged[(Array[Int], Array[Int]) => Unit] = { import Lifters._ '{ val arr = ${a} @@ -65,7 +65,7 @@ object MVmult { } } - def mvmult_opt(a: Array[Array[Int]]): Expr[(Array[Int], Array[Int]) => Unit] = { + def mvmult_opt(a: Array[Array[Int]]): Staged[(Array[Int], Array[Int]) => Unit] = { import Lifters._ '{ val arr = ${a} @@ -76,7 +76,7 @@ object MVmult { } } - def mvmult_roll(a: Array[Array[Int]]): Expr[(Array[Int], Array[Int]) => Unit] = { + def mvmult_roll(a: Array[Array[Int]]): Staged[(Array[Int], Array[Int]) => Unit] = { import Lifters._ '{ val arr = ${a} @@ -87,19 +87,19 @@ object MVmult { } } - def mvmult_let1(a: Array[Array[Int]]): Expr[(Array[Int], Array[Int]) => Unit] = { + def mvmult_let1(a: Array[Array[Int]]): Staged[(Array[Int], Array[Int]) => Unit] = { val (n, m, a2) = amatCopy(a, copy_row1) mvmult_abs0(new RingIntOPExpr, new VecRStaOptDynInt(new RingIntPExpr))(n, m, a2) } - def mvmult_let(a: Array[Array[Int]]): Expr[(Array[Int], Array[Int]) => Unit] = { + def mvmult_let(a: Array[Array[Int]]): Staged[(Array[Int], Array[Int]) => Unit] = { initRows(a) { rows => val (n, m, a2) = amat2(a, rows) mvmult_abs0(new RingIntOPExpr, new VecRStaOptDynInt(new RingIntPExpr))(n, m, a2) } } - def initRows[T: Type](a: Array[Array[Int]])(cont: Array[Expr[Array[Int]]] => Expr[T]): Expr[T] = { + def initRows[T: Type](a: Array[Array[Int]])(cont: Array[Expr[Array[Int]]] => Expr[T]): Staged[T] = { import Lifters._ def loop(i: Int, acc: List[Expr[Array[Int]]]): Expr[T] = { if (i >= a.length) cont(acc.toArray.reverse) @@ -114,7 +114,7 @@ object MVmult { loop(0, Nil) } - def amat1(a: Array[Array[Int]], aa: Expr[Array[Array[Int]]]): (Int, Int, Vec[PV[Int], Vec[PV[Int], PV[Int]]]) = { + def amat1(a: Array[Array[Int]], aa: Expr[Array[Array[Int]]])(implicit st: StagingContext): (Int, Int, Vec[PV[Int], Vec[PV[Int], PV[Int]]]) = { val n = a.length val m = a(0).length val vec: Vec[PV[Int], Vec[PV[Int], PV[Int]]] = Vec(Sta(n), i => Vec(Sta(m), j => (i, j) match { @@ -125,7 +125,7 @@ object MVmult { (n, m, vec) } - def amat2(a: Array[Array[Int]], refs: Array[Expr[Array[Int]]]): (Int, Int, Vec[PV[Int], Vec[PV[Int], PV[Int]]]) = { + def amat2(a: Array[Array[Int]], refs: Array[Expr[Array[Int]]])(implicit st: StagingContext): (Int, Int, Vec[PV[Int], Vec[PV[Int], PV[Int]]]) = { val n = a.length val m = a(0).length val vec: Vec[PV[Int], Vec[PV[Int], PV[Int]]] = Vec(Sta(n), i => Vec(Sta(m), j => (i, j) match { @@ -135,7 +135,7 @@ object MVmult { (n, m, vec) } - def amatCopy(a: Array[Array[Int]], copyRow: Array[Int] => (Expr[Int] => Expr[Int])): (Int, Int, Vec[PV[Int], Vec[PV[Int], PV[Int]]]) = { + def amatCopy(a: Array[Array[Int]], copyRow: Array[Int] => (Expr[Int] => Expr[Int]))(implicit st: StagingContext): (Int, Int, Vec[PV[Int], Vec[PV[Int], PV[Int]]]) = { val n = a.length val m = a(0).length val vec: Vec[PV[Int], Vec[PV[Int], PV[Int]]] = Vec(Sta(n), i => Vec(Sta(m), j => (i, j) match { @@ -148,19 +148,19 @@ object MVmult { (n, m, vec) } - def copy_row1: Array[Int] => (Expr[Int] => Expr[Int]) = v => { + def copy_row1(implicit st: StagingContext): Array[Int] => (Expr[Int] => Expr[Int]) = v => { import Lifters._ val arr = v i => '{ ($arr).apply($i) } } - def copy_row_let: Array[Int] => (Expr[Int] => Expr[Int]) = v => { + def copy_row_let(implicit st: StagingContext): Array[Int] => (Expr[Int] => Expr[Int]) = v => { import Lifters._ val arr: Expr[Array[Int]] = ??? // FIXME used genlet v i => '{ ($arr).apply($i) } } - private def mvmult_abs0(ring: Ring[PV[Int]], vecOp: VecROp[PV[Int], PV[Int], Expr[Unit]])(n: Int, m: Int, a: Vec[PV[Int], Vec[PV[Int], PV[Int]]]): Expr[(Array[Int], Array[Int]) => Unit] = { + private def mvmult_abs0(ring: Ring[PV[Int]], vecOp: VecROp[PV[Int], PV[Int], Expr[Unit]])(n: Int, m: Int, a: Vec[PV[Int], Vec[PV[Int], PV[Int]]]): Staged[(Array[Int], Array[Int]) => Unit] = { '{ (vout, v) => { if (${n} != vout.length) throw new IndexOutOfBoundsException(${n.toString}) diff --git a/tests/run-with-compiler/shonan-hmm/PV.scala b/tests/run-with-compiler/shonan-hmm/PV.scala index d33cb7a45333..8ed9e5835633 100644 --- a/tests/run-with-compiler/shonan-hmm/PV.scala +++ b/tests/run-with-compiler/shonan-hmm/PV.scala @@ -8,9 +8,9 @@ case class Sta[T](x: T) extends PV[T] case class Dyn[T](x: Expr[T]) extends PV[T] object Dyns { - def dyn[T: Liftable](pv: PV[T]): Expr[T] = pv match { + def dyn[T: Liftable](pv: PV[T]): Staged[T] = pv match { case Sta(x) => x.toExpr case Dyn(x) => x } - val dyni: PV[Int] => Expr[Int] = dyn[Int] + val dyni: PV[Int] => Staged[Int] = dyn[Int] } diff --git a/tests/run-with-compiler/shonan-hmm/Ring.scala b/tests/run-with-compiler/shonan-hmm/Ring.scala index 3763017d8424..3c48b98c85d9 100644 --- a/tests/run-with-compiler/shonan-hmm/Ring.scala +++ b/tests/run-with-compiler/shonan-hmm/Ring.scala @@ -15,7 +15,7 @@ trait Ring[T] { } } -object RingInt extends Ring[Int] { +class RingInt extends Ring[Int] { val zero = 0 val one = 0 val add = (x, y) => x + y @@ -24,7 +24,7 @@ object RingInt extends Ring[Int] { override def toString(): String = "RingInt" } -object RingIntExpr extends Ring[Expr[Int]] { +class RingIntExpr(implicit st: StagingContext) extends Ring[Expr[Int]] { val zero = '{0} val one = '{1} val add = (x, y) => '{$x + $y} @@ -43,7 +43,7 @@ case class RingComplex[U](u: Ring[U]) extends Ring[Complex[U]] { override def toString(): String = s"RingComplex($u)" } -case class RingPV[U: Liftable](staRing: Ring[U], dynRing: Ring[Expr[U]]) extends Ring[PV[U]] { +case class RingPV[U: Liftable](staRing: Ring[U], dynRing: Ring[Expr[U]])(implicit st: StagingContext) extends Ring[PV[U]] { type T = PV[U] val dyn = Dyns.dyn[U] @@ -66,9 +66,9 @@ case class RingPV[U: Liftable](staRing: Ring[U], dynRing: Ring[Expr[U]]) extends } } -class RingIntPExpr extends RingPV(RingInt, RingIntExpr) +class RingIntPExpr(implicit st: StagingContext) extends RingPV(new RingInt, new RingIntExpr) -class RingIntOPExpr extends RingIntPExpr { +class RingIntOPExpr(implicit st: StagingContext) extends RingIntPExpr { override def add = (x: PV[Int], y: PV[Int]) => (x, y) match { case (Sta(0), y) => y case (x, Sta(0)) => x diff --git a/tests/run-with-compiler/shonan-hmm/Test.scala b/tests/run-with-compiler/shonan-hmm/Test.scala index 44849c6e3abd..168158519c78 100644 --- a/tests/run-with-compiler/shonan-hmm/Test.scala +++ b/tests/run-with-compiler/shonan-hmm/Test.scala @@ -5,21 +5,22 @@ import scala.quoted._ object Test { def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + val tb = Toolbox.make { - val intComplex = new RingComplex(RingInt) + val intComplex = new RingComplex(new RingInt) import intComplex._ println(Complex(1, 2) * Complex(4, 2)) } - { - val intExprComplex = new RingComplex(RingIntExpr) + tb.run { + val intExprComplex = new RingComplex(new RingIntExpr) import intExprComplex._ val res = Complex('{1}, '{2}) * Complex('{4}, '{2}) println(s"Complex(${res.re.show}, ${res.im.show})") + '() } // { @@ -33,10 +34,12 @@ object Test { val arr1 = Array(Complex(1, 0), Complex(0, 4), Complex(2, 2)) val arr2 = Array(Complex(2, 0), Complex(1, 1), Complex(1, 2)) val out = Array(Complex(0, 0), Complex(0, 0), Complex(0, 0)) - Vmults.vmult(out, arr1, arr2) - println(out.toList) + tb.run { + Vmults.vmult(out, arr1, arr2) + '(println(~out.toList.toString.toExpr)) + } - println(Vmults.vmultCA.show) + println(tb.show(Vmults.vmultCA)) val a = Array( Array( 5, 0, 0, 5, 0), @@ -54,37 +57,37 @@ object Test { println() println() - println(MVmult.mvmult_c.show) + println(tb.show(MVmult.mvmult_c)) println() println() println() - println(MVmult.mvmult_mc(3, 2).show) + println(tb.show(MVmult.mvmult_mc(3, 2))) println() println() println() - println(MVmult.mvmult_ac(a).show) + println(tb.show(MVmult.mvmult_ac(a))) println() println() println() - println(MVmult.mvmult_opt(a).show) + println(tb.show(MVmult.mvmult_opt(a))) println() println() println() - println(MVmult.mvmult_roll(a).show) + println(tb.show(MVmult.mvmult_roll(a))) println() println() println() - println(MVmult.mvmult_let1(a).show) + println(tb.show(MVmult.mvmult_let1(a))) println() println() println() - println(MVmult.mvmult_let(a).show) + println(tb.show(MVmult.mvmult_let(a))) } } diff --git a/tests/run-with-compiler/shonan-hmm/UnrolledExpr.scala b/tests/run-with-compiler/shonan-hmm/UnrolledExpr.scala index 56ab8a676740..8e23e31811ed 100644 --- a/tests/run-with-compiler/shonan-hmm/UnrolledExpr.scala +++ b/tests/run-with-compiler/shonan-hmm/UnrolledExpr.scala @@ -8,7 +8,7 @@ object UnrolledExpr { } // TODO support blocks in the compiler to avoid creating trees of blocks? - def block[T: Type](stats: Iterable[Expr[_]], expr: Expr[T]): Expr[T] = { + def block[T: Type](stats: Iterable[Expr[_]], expr: Expr[T]): Staged[T] = { def rec(stats: List[Expr[_]]): Expr[T] = stats match { case x :: xs => '{ $x; ${rec(xs)} } case Nil => expr @@ -21,10 +21,10 @@ object UnrolledExpr { class UnrolledExpr[T: Liftable, It <: Iterable[T]](xs: It) { import UnrolledExpr._ - def foreach[U](f: T => Expr[U]): Expr[Unit] = block(xs.map(f), '{}) + def foreach[U](f: T => Expr[U]): Staged[Unit] = block(xs.map(f), '{}) def withFilter(f: T => Boolean): UnrolledExpr[T, Iterable[T]] = new UnrolledExpr(xs.filter(f)) - def foldLeft[U](acc: Expr[U])(f: (Expr[U], T) => Expr[U]): Expr[U] = + def foldLeft[U](acc: Expr[U])(f: (Expr[U], T) => Expr[U]): Staged[U] = xs.foldLeft(acc)((acc, x) => f(acc, x)) } diff --git a/tests/run-with-compiler/shonan-hmm/VecOp.scala b/tests/run-with-compiler/shonan-hmm/VecOp.scala index d4764b9f4487..963e62908a8c 100644 --- a/tests/run-with-compiler/shonan-hmm/VecOp.scala +++ b/tests/run-with-compiler/shonan-hmm/VecOp.scala @@ -12,7 +12,7 @@ class VecSta extends VecOp[Int, Unit] { override def toString(): String = s"StaticVec" } -class VecDyn extends VecOp[Expr[Int], Expr[Unit]] { +class VecDyn(implicit st: StagingContext) extends VecOp[Expr[Int], Expr[Unit]] { def iter: Vec[Expr[Int], Expr[Unit]] => Expr[Unit] = arr => '{ var i = 0 while (i < ${arr.size}) { diff --git a/tests/run-with-compiler/shonan-hmm/VecROp.scala b/tests/run-with-compiler/shonan-hmm/VecROp.scala index 2be017b6385e..bb76654bae54 100644 --- a/tests/run-with-compiler/shonan-hmm/VecROp.scala +++ b/tests/run-with-compiler/shonan-hmm/VecROp.scala @@ -17,7 +17,7 @@ class StaticVecR[T](r: Ring[T]) extends VecSta with VecROp[Int, T, Unit] { override def toString(): String = s"StaticVecR($r)" } -class VecRDyn[T: Type] extends VecDyn with VecROp[Expr[Int], Expr[T], Expr[Unit]] { +class VecRDyn[T: Type](implicit st: StagingContext) extends VecDyn with VecROp[Expr[Int], Expr[T], Expr[Unit]] { def reduce: ((Expr[T], Expr[T]) => Expr[T], Expr[T], Vec[Expr[Int], Expr[T]]) => Expr[T] = { (plus, zero, vec) => '{ var sum = $zero @@ -32,7 +32,7 @@ class VecRDyn[T: Type] extends VecDyn with VecROp[Expr[Int], Expr[T], Expr[Unit] override def toString(): String = s"VecRDyn" } -class VecRStaDim[T: Type](r: Ring[T]) extends VecROp[Int, T, Expr[Unit]] { +class VecRStaDim[T: Type](r: Ring[T])(implicit st: StagingContext) extends VecROp[Int, T, Expr[Unit]] { val M = new StaticVecR[T](r) def reduce: ((T, T) => T, T, Vec[Int, T]) => T = M.reduce val seq: (Expr[Unit], Expr[Unit]) => Expr[Unit] = (e1, e2) => '{ $e1; $e2 } @@ -46,7 +46,7 @@ class VecRStaDim[T: Type](r: Ring[T]) extends VecROp[Int, T, Expr[Unit]] { override def toString(): String = s"VecRStaDim($r)" } -class VecRStaDyn[T : Type : Liftable](r: Ring[PV[T]]) extends VecROp[PV[Int], PV[T], Expr[Unit]] { +class VecRStaDyn[T : Type : Liftable](r: Ring[PV[T]])(implicit st: StagingContext) extends VecROp[PV[Int], PV[T], Expr[Unit]] { val VSta: VecROp[Int, PV[T], Expr[Unit]] = new VecRStaDim(r) val VDyn = new VecRDyn val dyn = Dyns.dyn[T] @@ -74,7 +74,7 @@ object VecRStaOptDynInt { val threshold = 3 } -class VecRStaOptDynInt(r: Ring[PV[Int]]) extends VecRStaDyn(r) { +class VecRStaOptDynInt(r: Ring[PV[Int]])(implicit st: StagingContext) extends VecRStaDyn(r) { val M: VecROp[PV[Int], PV[Int], Expr[Unit]] = new VecRStaDyn(r) override def reduce: ((PV[Int], PV[Int]) => PV[Int], PV[Int], Vec[PV[Int], PV[Int]]) => PV[Int] = (plus, zero, vec) => vec match { diff --git a/tests/run-with-compiler/shonan-hmm/Vmults.scala b/tests/run-with-compiler/shonan-hmm/Vmults.scala index 14837e8b3da9..227543c0c14f 100644 --- a/tests/run-with-compiler/shonan-hmm/Vmults.scala +++ b/tests/run-with-compiler/shonan-hmm/Vmults.scala @@ -8,18 +8,18 @@ class Vmult[Idx, T, Unt](tring: Ring[T], vec: VecOp[Idx, Unt]) { } object Vmults { - def vmult(vout: Array[Complex[Int]], v1: Array[Complex[Int]], v2: Array[Complex[Int]]): Unit = { + def vmult(vout: Array[Complex[Int]], v1: Array[Complex[Int]], v2: Array[Complex[Int]])(implicit staging: StagingContext): Unit = { val n = vout.length val vout_ = OVec(n, (i, v: Complex[Int]) => vout(i) = v) val v1_ = Vec (n, i => v1(i)) val v2_ = Vec (n, i => v2(i)) - val V = new Vmult[Int, Complex[Int], Unit](RingComplex(RingInt), new VecSta) + val V = new Vmult[Int, Complex[Int], Unit](RingComplex(new RingInt), new VecSta) V.vmult(vout_, v1_, v2_) } - def vmultCA: Expr[(Array[Complex[Int]], Array[Complex[Int]], Array[Complex[Int]]) => Unit] = '{ + def vmultCA(implicit staging: StagingContext): Expr[(Array[Complex[Int]], Array[Complex[Int]], Array[Complex[Int]]) => Unit] = '{ (vout, v1, v2) => { val n = vout.length ${ @@ -27,7 +27,7 @@ object Vmults { val v1_ = Vec ('n, i => Complex.of_complex_expr('{v1($i)})) val v2_ = Vec ('n, i => Complex.of_complex_expr('{v2($i)})) - val V = new Vmult[Expr[Int], Complex[Expr[Int]], Expr[Unit]](RingComplex(RingIntExpr), new VecDyn) + val V = new Vmult[Expr[Int], Complex[Expr[Int]], Expr[Unit]](RingComplex(new RingIntExpr), new VecDyn) V.vmult(vout_, v1_, v2_) } } diff --git a/tests/run-with-compiler/tasty-extractors-constants-2/quoted_1.scala b/tests/run-with-compiler/tasty-extractors-constants-2/quoted_1.scala index f494558779f2..031306d5a7d9 100644 --- a/tests/run-with-compiler/tasty-extractors-constants-2/quoted_1.scala +++ b/tests/run-with-compiler/tasty-extractors-constants-2/quoted_1.scala @@ -6,28 +6,31 @@ import scala.tasty.util._ object Macros { + val tb = Toolbox.make + import tb.run + inline def testMacro: Unit = ${impl} - def impl(implicit reflect: Reflection): Expr[Unit] = { + def impl(implicit staging: StagingContext): Expr[Unit] = { implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) // 2 is a lifted constant val show1 = power(2, 3.0).show - val run1 = power(2, 3.0).run + val run1 = run(power(2, 3.0)) // n is a lifted constant val n = 2 val show2 = power(n, 4.0).show - val run2 = power(n, 4.0).run + val run2 = run(power(n, 4.0)) // n is a constant in a quote val show3 = power('{2}, 5.0).show - val run3 = power('{2}, 5.0).run + val run3 = run(power('{2}, 5.0)) // n2 is clearly not a constant // FIXME // val n2 = '{ println("foo"); 2 } -// val show4 = (power(n2, 6.0).show) -// val run4 = (power(n2, 6.0).run) +// val show4 = show(power(n2, 6.0)) +// val run4 = run(power(n2, 6.0)) '{ println(${show1}) @@ -44,7 +47,7 @@ object Macros { } } - def power(n: Expr[Int], x: Expr[Double])(implicit reflect: Reflection): Expr[Double] = { + def power(n: Expr[Int], x: Expr[Double])(implicit staging: StagingContext): Expr[Double] = { import quoted.matching.Const n match { case Const(n1) => powerCode(n1, x) @@ -52,7 +55,7 @@ object Macros { } } - def powerCode(n: Int, x: Expr[Double]): Expr[Double] = + def powerCode(n: Int, x: Expr[Double]): Staged[Double] = if (n == 0) '{1.0} else if (n == 1) x else if (n % 2 == 0) '{ { val y = $x * $x; ${powerCode(n / 2, 'y)} } }