diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 5725d554b815..a566f90cf38d 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -111,16 +111,14 @@ object Splicer { } protected def interpretStaticMethodCall(fn: Tree, args: => List[Object])(implicit env: Env): Object = { - if (fn.symbol == defn.NoneModuleRef.termSymbol) { - // TODO generalize - None - } else { - val (clazz, instance) = loadModule(fn.symbol.owner) - val method = getMethod(clazz, fn.symbol.name, paramsSig(fn.symbol)) - stopIfRuntimeException(method.invoke(instance, args: _*)) - } + val instance = loadModule(fn.symbol.owner) + val method = getMethod(instance.getClass, fn.symbol.name, paramsSig(fn.symbol)) + stopIfRuntimeException(method.invoke(instance, args: _*)) } + protected def interpretModuleAccess(fn: Tree)(implicit env: Env): Object = + loadModule(fn.symbol.moduleClass) + protected def interpretNew(fn: RefTree, args: => List[Result])(implicit env: Env): Object = { val clazz = loadClass(fn.symbol.owner.fullName) val constr = clazz.getConstructor(paramsSig(fn.symbol): _*) @@ -130,16 +128,15 @@ object Splicer { protected def unexpectedTree(tree: Tree)(implicit env: Env): Object = throw new StopInterpretation("Unexpected tree could not be interpreted: " + tree, tree.pos) - private def loadModule(sym: Symbol): (Class[_], Object) = { + private def loadModule(sym: Symbol): Object = { if (sym.owner.is(Package)) { // is top level object val moduleClass = loadClass(sym.fullName) - val moduleInstance = moduleClass.getField(MODULE_INSTANCE_FIELD).get(null) - (moduleClass, moduleInstance) + moduleClass.getField(MODULE_INSTANCE_FIELD).get(null) } else { // nested object in an object val clazz = loadClass(sym.fullNameSeparated(FlatName)) - (clazz, clazz.getConstructor().newInstance().asInstanceOf[Object]) + clazz.getConstructor().newInstance().asInstanceOf[Object] } } @@ -147,7 +144,7 @@ object Splicer { try classLoader.loadClass(name.toString) catch { case _: ClassNotFoundException => - val msg = s"Could not find macro class $name in classpath$extraMsg" + val msg = s"Could not find class $name in classpath$extraMsg" throw new StopInterpretation(msg, pos) } } @@ -156,7 +153,7 @@ object Splicer { try clazz.getMethod(name.toString, paramClasses: _*) catch { case _: NoSuchMethodException => - val msg = em"Could not find macro method ${clazz.getCanonicalName}.$name with parameters ($paramClasses%, %)$extraMsg" + val msg = em"Could not find method ${clazz.getCanonicalName}.$name with parameters ($paramClasses%, %)$extraMsg" throw new StopInterpretation(msg, pos) } } @@ -257,7 +254,8 @@ object Splicer { protected def interpretVarargs(args: List[Boolean])(implicit env: Env): Boolean = args.forall(identity) protected def interpretTastyContext()(implicit env: Env): Boolean = true protected def interpretStaticMethodCall(fn: tpd.Tree, args: => List[Boolean])(implicit env: Env): Boolean = args.forall(identity) - protected def interpretNew(fn: RefTree, args: => List[Result])(implicit env: Env): Boolean = args.forall(identity) + protected def interpretModuleAccess(fn: Tree)(implicit env: Env): Boolean = true + protected def interpretNew(fn: RefTree, args: => List[Boolean])(implicit env: Env): Boolean = args.forall(identity) def unexpectedTree(tree: tpd.Tree)(implicit env: Env): Boolean = { // Assuming that top-level splices can only be in inline methods @@ -278,6 +276,7 @@ object Splicer { protected def interpretVarargs(args: List[Result])(implicit env: Env): Result protected def interpretTastyContext()(implicit env: Env): Result protected def interpretStaticMethodCall(fn: Tree, args: => List[Result])(implicit env: Env): Result + protected def interpretModuleAccess(fn: Tree)(implicit env: Env): Result protected def interpretNew(fn: RefTree, args: => List[Result])(implicit env: Env): Result protected def unexpectedTree(tree: Tree)(implicit env: Env): Result @@ -294,8 +293,17 @@ object Splicer { case _ if tree.symbol == defn.TastyTasty_macroContext => interpretTastyContext() - case StaticMethodCall(fn, args) => - interpretStaticMethodCall(fn, args.map(arg => interpretTree(arg))) + case Call(fn, args) => + if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package)) { + interpretNew(fn, args.map(interpretTree)) + } else if (fn.symbol.isStatic) { + if (fn.symbol.is(Module)) interpretModuleAccess(fn) + else interpretStaticMethodCall(fn, args.map(arg => interpretTree(arg))) + } else if (env.contains(fn.name)) { + env(fn.name) + } else { + unexpectedTree(tree) + } // Interpret `foo(j = x, i = y)` which it is expanded to // `val j$1 = x; val i$1 = y; foo(i = y, j = x)` @@ -307,16 +315,9 @@ object Splicer { }) interpretTree(expr)(newEnv) case NamedArg(_, arg) => interpretTree(arg) - case Ident(name) if env.contains(name) => env(name) case Inlined(EmptyTree, Nil, expansion) => interpretTree(expansion) - case Apply(TypeApply(fun: RefTree, _), args) if fun.symbol.isConstructor && fun.symbol.owner.owner.is(Package) => - interpretNew(fun, args.map(interpretTree)) - - case Apply(fun: RefTree, args) if fun.symbol.isConstructor && fun.symbol.owner.owner.is(Package)=> - interpretNew(fun, args.map(interpretTree)) - case Typed(SeqLiteral(elems, _), _) => interpretVarargs(elems.map(e => interpretTree(e))) @@ -324,11 +325,11 @@ object Splicer { unexpectedTree(tree) } - object StaticMethodCall { + object Call { def unapply(arg: Tree): Option[(RefTree, List[Tree])] = arg match { - case fn: RefTree if fn.symbol.isStatic => Some((fn, Nil)) - case Apply(StaticMethodCall(fn, args1), args2) => Some((fn, args1 ::: args2)) // TODO improve performance - case TypeApply(StaticMethodCall(fn, args), _) => Some((fn, args)) + case fn: RefTree => Some((fn, Nil)) + case Apply(Call(fn, args1), args2) => Some((fn, args1 ::: args2)) // TODO improve performance + case TypeApply(Call(fn, args), _) => Some((fn, args)) case _ => None } } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 42a48f09c451..9f26cc6320a2 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -679,20 +679,28 @@ trait Checking { tree.tpe.widenTermRefExpr match { case tp: ConstantType if exprPurity(tree) >= purityLevel => // ok case tp => + def isCaseClassApply(sym: Symbol): Boolean = + sym.name == nme.apply && sym.is(Synthetic) && sym.owner.is(Module) && sym.owner.companionClass.is(Case) + def isCaseClassNew(sym: Symbol): Boolean = + sym.isPrimaryConstructor && sym.owner.is(Case) && sym.owner.isStatic + def isCaseObject(sym: Symbol): Boolean = { + // TODO add alias to Nil in scala package + sym.is(Case) && sym.is(Module) + } val allow = ctx.erasedTypes || ctx.inInlineMethod || - // TODO: Make None and Some constant types? - tree.symbol.eq(defn.NoneModuleRef.termSymbol) || - tree.symbol.eq(defn.SomeClass.primaryConstructor) || - (tree.symbol.name == nme.apply && tree.symbol.owner == defn.SomeClass.companionModule.moduleClass) - if (!allow) ctx.error(em"$what must be a constant expression", tree.pos) - else tree match { - // TODO: add cases for type apply and multiple applies - case Apply(_, args) => - for (arg <- args) - checkInlineConformant(arg, isFinal, what) - case _ => + (tree.symbol.isStatic && isCaseObject(tree.symbol) || isCaseClassApply(tree.symbol)) || + isCaseClassNew(tree.symbol) + if (!allow) ctx.error(em"$what must be a known value", tree.pos) + else { + def checkArgs(tree: Tree): Unit = tree match { + case Apply(fn, args) => + args.foreach(arg => checkInlineConformant(arg, isFinal, what)) + checkArgs(fn) + case _ => + } + checkArgs(tree) } } } diff --git a/compiler/test/dotc/run-test-pickling.blacklist b/compiler/test/dotc/run-test-pickling.blacklist index 6ccfdb431c33..432d926ec813 100644 --- a/compiler/test/dotc/run-test-pickling.blacklist +++ b/compiler/test/dotc/run-test-pickling.blacklist @@ -24,7 +24,11 @@ i5119 i5119b inline-varargs-1 implicitShortcut +inline-case-objects inline-option +inline-macro-staged-interpreter +inline-tuples-1 +inline-tuples-2 lazy-implicit-lists.scala lazy-implicit-nums.scala lazy-traits.scala diff --git a/tests/neg/inline-case-objects/Macro_1.scala b/tests/neg/inline-case-objects/Macro_1.scala new file mode 100644 index 000000000000..95bfeec347bb --- /dev/null +++ b/tests/neg/inline-case-objects/Macro_1.scala @@ -0,0 +1,16 @@ + +import scala.quoted._ + +object Macros { + def impl(foo: Any): Expr[String] = foo.getClass.getCanonicalName.toExpr +} + +class Bar { + case object Baz +} + +package foo { + class Bar { + case object Baz + } +} diff --git a/tests/neg/inline-case-objects/Main_2.scala b/tests/neg/inline-case-objects/Main_2.scala new file mode 100644 index 000000000000..a61b0fc060dc --- /dev/null +++ b/tests/neg/inline-case-objects/Main_2.scala @@ -0,0 +1,11 @@ + +object Test { + + def main(args: Array[String]): Unit = { + val bar = new Bar + println(fooString(bar.Baz)) // error + } + + inline def fooString(inline x: Any): String = ~Macros.impl(x) + +} diff --git a/tests/neg/inline-macro-staged-interpreter/Macro_1.scala b/tests/neg/inline-macro-staged-interpreter/Macro_1.scala new file mode 100644 index 000000000000..3e67577a3874 --- /dev/null +++ b/tests/neg/inline-macro-staged-interpreter/Macro_1.scala @@ -0,0 +1,33 @@ + +import scala.quoted._ + +object E { + + inline def eval[T](inline x: E[T]): T = ~impl(x) + + def impl[T](x: E[T]): Expr[T] = x.lift + +} + +trait E[T] { + def lift: Expr[T] +} + +case class I(n: Int) extends E[Int] { + def lift: Expr[Int] = n.toExpr +} + +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) +} + +trait Op2[T] { + def apply(x: Expr[T], y: Expr[T]): Expr[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) + } +} diff --git a/tests/neg/inline-macro-staged-interpreter/Main_2.scala b/tests/neg/inline-macro-staged-interpreter/Main_2.scala new file mode 100644 index 000000000000..957f656fe17c --- /dev/null +++ b/tests/neg/inline-macro-staged-interpreter/Main_2.scala @@ -0,0 +1,20 @@ + +object Test { + + def main(args: Array[String]): Unit = { + val i = I(2) + E.eval( + i // error + ) + + E.eval(Plus( + i, // error + I(4))) + + val plus = Plus2.IPlus + E.eval(Plus(I(2), I(4))( + plus // error + )) + } + +} diff --git a/tests/neg/inline-tuples-1/Macro_1.scala b/tests/neg/inline-tuples-1/Macro_1.scala new file mode 100644 index 000000000000..0d45729b963f --- /dev/null +++ b/tests/neg/inline-tuples-1/Macro_1.scala @@ -0,0 +1,27 @@ + +import scala.quoted._ + +object Macros { + def tup1(tup: Tuple1[Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup2(tup: Tuple2[Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup3(tup: Tuple3[Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup4(tup: Tuple4[Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup5(tup: Tuple5[Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup6(tup: Tuple6[Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup7(tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup8(tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup9(tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup10(tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup11(tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup12(tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr +} diff --git a/tests/neg/inline-tuples-1/Main_2.scala b/tests/neg/inline-tuples-1/Main_2.scala new file mode 100644 index 000000000000..199c0fbdcbb6 --- /dev/null +++ b/tests/neg/inline-tuples-1/Main_2.scala @@ -0,0 +1,373 @@ + +object Test { + + def main(args: Array[String]): Unit = { + val t1 = Tuple1(1) + val t2 = Tuple2(1, 2) + val t3 = Tuple3(1, 2, 3) + val t4 = Tuple4(1, 2, 3, 4) + val t5 = Tuple5(1, 2, 3, 4, 5) + val t6 = Tuple6(1, 2, 3, 4, 5, 6) + val t7 = Tuple7(1, 2, 3, 4, 5, 6, 7) + val t8 = Tuple8(1, 2, 3, 4, 5, 6, 7, 8) + val t9 = Tuple9(1, 2, 3, 4, 5, 6, 7, 8, 9) + val t10 = Tuple10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val t11 = Tuple11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val t12 = Tuple12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + val t13 = Tuple13(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + val t14 = Tuple14(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + val t15 = Tuple15(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + val t16 = Tuple16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) + val t17 = Tuple17(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) + val t18 = Tuple18(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) + val t19 = Tuple19(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) + val t20 = Tuple20(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) + val t21 = Tuple21(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + val t22 = Tuple22(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) + println(sum(t1)) // error + println(sum(t2)) // error + println(sum(t3)) // error + println(sum(t4)) // error + println(sum(t5)) // error + println(sum(t6)) // error + println(sum(t7)) // error + println(sum(t8)) // error + println(sum(t9)) // error + println(sum(t10)) // error + println(sum(t11)) // error + println(sum(t12)) // error + println(sum(t13)) // error + println(sum(t14)) // error + println(sum(t15)) // error + println(sum(t16)) // error + println(sum(t17)) // error + println(sum(t18)) // error + println(sum(t19)) // error + println(sum(t20)) // error + println(sum(t21)) // error + println(sum(t22)) // error + + val a: Int = 1 + println(sum(Tuple1( + a // error + ))) + println(sum(Tuple2( + a, // error + a // error + ))) + println(sum(Tuple3( + a, // error + a, // error + a // error + ))) + println(sum(Tuple4( + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple5( + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple6( + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple7( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple8( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple9( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple10( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple11( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple12( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple13( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple14( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple15( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple16( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple17( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple18( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple19( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple20( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple21( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + println(sum(Tuple22( + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a, // error + a // error + ))) + } + + inline def sum(inline tup: Tuple1[Int]): Int = ~Macros.tup1(tup) + inline def sum(inline tup: Tuple2[Int, Int]): Int = ~Macros.tup2(tup) + inline def sum(inline tup: Tuple3[Int, Int, Int]): Int = ~Macros.tup3(tup) + inline def sum(inline tup: Tuple4[Int, Int, Int, Int]): Int = ~Macros.tup4(tup) + inline def sum(inline tup: Tuple5[Int, Int, Int, Int, Int]): Int = ~Macros.tup5(tup) + inline def sum(inline tup: Tuple6[Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup6(tup) + inline def sum(inline tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup7(tup) + inline def sum(inline tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup8(tup) + inline def sum(inline tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup9(tup) + inline def sum(inline tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup10(tup) + inline def sum(inline tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup11(tup) + inline def sum(inline tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup12(tup) + inline def sum(inline tup: Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup13(tup) + inline def sum(inline tup: Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup14(tup) + inline def sum(inline tup: Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup15(tup) + inline def sum(inline tup: Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup16(tup) + inline def sum(inline tup: Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup17(tup) + inline def sum(inline tup: Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup18(tup) + inline def sum(inline tup: Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup19(tup) + inline def sum(inline tup: Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup20(tup) + inline def sum(inline tup: Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup21(tup) + inline def sum(inline tup: Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup22(tup) + +} diff --git a/tests/run/inline-case-objects.check b/tests/run/inline-case-objects.check new file mode 100644 index 000000000000..77e4a94bb071 --- /dev/null +++ b/tests/run/inline-case-objects.check @@ -0,0 +1,6 @@ +scala.collection.immutable.Nil$ +scala.None$ +Bar$ +Bar.Baz$ +foo.Bar$ +Bar.Baz$ diff --git a/tests/run/inline-case-objects/Macro_1.scala b/tests/run/inline-case-objects/Macro_1.scala new file mode 100644 index 000000000000..fa8d539cfbd7 --- /dev/null +++ b/tests/run/inline-case-objects/Macro_1.scala @@ -0,0 +1,16 @@ + +import scala.quoted._ + +object Macros { + def impl(foo: Any): Expr[String] = foo.getClass.getCanonicalName.toExpr +} + +case object Bar { + case object Baz +} + +package foo { + case object Bar { + case object Baz + } +} diff --git a/tests/run/inline-case-objects/Main_2.scala b/tests/run/inline-case-objects/Main_2.scala new file mode 100644 index 000000000000..7f03be8a15c4 --- /dev/null +++ b/tests/run/inline-case-objects/Main_2.scala @@ -0,0 +1,15 @@ + +object Test { + + def main(args: Array[String]): Unit = { + println(fooString(scala.collection.immutable.Nil)) + println(fooString(None)) + println(fooString(Bar)) + println(fooString(Bar.Baz)) + println(fooString(foo.Bar)) + println(fooString(foo.Bar.Baz)) + } + + inline def fooString(inline x: Any): String = ~Macros.impl(x) + +} diff --git a/tests/run/inline-macro-staged-interpreter.check b/tests/run/inline-macro-staged-interpreter.check new file mode 100644 index 000000000000..85079a7b9345 --- /dev/null +++ b/tests/run/inline-macro-staged-interpreter.check @@ -0,0 +1,9 @@ +2 +3 +6 +7 +8 +14 +3.1 +20.4 +20.8 diff --git a/tests/run/inline-macro-staged-interpreter/Macro_1.scala b/tests/run/inline-macro-staged-interpreter/Macro_1.scala new file mode 100644 index 000000000000..11bdd3533e00 --- /dev/null +++ b/tests/run/inline-macro-staged-interpreter/Macro_1.scala @@ -0,0 +1,56 @@ + +import scala.quoted._ + +object E { + + inline def eval[T](inline x: E[T]): T = ~impl(x) + + def impl[T](x: E[T]): Expr[T] = x.lift + +} + +trait E[T] { + def lift: Expr[T] +} + +case class I(n: Int) extends E[Int] { + def lift: Expr[Int] = n.toExpr +} + +case class D(n: Double) extends E[Double] { + def lift: Expr[Double] = n.toExpr +} + +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) +} + +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) +} + +trait Op2[T] { + def apply(x: Expr[T], y: Expr[T]): Expr[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) + } + + implicit case object DPlus extends Plus2[Double] { + def apply(x: Expr[Double], y: Expr[Double]): Expr[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) + } + + implicit case object DTimes extends Times2[Double] { + def apply(x: Expr[Double], y: Expr[Double]): Expr[Double] = '(~x * ~y) + } +} diff --git a/tests/run/inline-macro-staged-interpreter/Main_2.scala b/tests/run/inline-macro-staged-interpreter/Main_2.scala new file mode 100644 index 000000000000..d264fe97c349 --- /dev/null +++ b/tests/run/inline-macro-staged-interpreter/Main_2.scala @@ -0,0 +1,17 @@ + +object Test { + + def main(args: Array[String]): Unit = { + println(E.eval(I(2))) + println(E.eval(new I(3))) + println(E.eval(Plus(I(2), I(4)))) + println(E.eval(new Plus(I(3), I(4)))) + println(E.eval(Times(I(2), I(4)))) + println(E.eval(Times(I(2), Plus(I(3), I(4))))) + + println(E.eval(D(3.1))) + println(E.eval(Times(D(2.4), Plus(D(3.9), D(4.6))))) + println(E.eval(new Times(D(2.6), Plus(D(3.9), new D(4.1))))) + } + +} diff --git a/tests/run/inline-tuples-1.check b/tests/run/inline-tuples-1.check new file mode 100644 index 000000000000..277b4807807a --- /dev/null +++ b/tests/run/inline-tuples-1.check @@ -0,0 +1,22 @@ +1 +3 +6 +10 +15 +21 +28 +36 +45 +55 +66 +78 +91 +105 +120 +136 +153 +171 +190 +210 +231 +253 diff --git a/tests/run/inline-tuples-1/Macro_1.scala b/tests/run/inline-tuples-1/Macro_1.scala new file mode 100644 index 000000000000..0d45729b963f --- /dev/null +++ b/tests/run/inline-tuples-1/Macro_1.scala @@ -0,0 +1,27 @@ + +import scala.quoted._ + +object Macros { + def tup1(tup: Tuple1[Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup2(tup: Tuple2[Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup3(tup: Tuple3[Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup4(tup: Tuple4[Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup5(tup: Tuple5[Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup6(tup: Tuple6[Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup7(tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup8(tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup9(tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup10(tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup11(tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + def tup12(tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr + 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.toExpr +} diff --git a/tests/run/inline-tuples-1/Main_2.scala b/tests/run/inline-tuples-1/Main_2.scala new file mode 100644 index 000000000000..54971154d29e --- /dev/null +++ b/tests/run/inline-tuples-1/Main_2.scala @@ -0,0 +1,52 @@ + +object Test { + + def main(args: Array[String]): Unit = { + println(sum(Tuple1(1))) + println(sum(Tuple2(1, 2))) + println(sum(Tuple3(1, 2, 3))) + println(sum(Tuple4(1, 2, 3, 4))) + println(sum(Tuple5(1, 2, 3, 4, 5))) + println(sum(Tuple6(1, 2, 3, 4, 5, 6))) + println(sum(Tuple7(1, 2, 3, 4, 5, 6, 7))) + println(sum(Tuple8(1, 2, 3, 4, 5, 6, 7, 8))) + println(sum(Tuple9(1, 2, 3, 4, 5, 6, 7, 8, 9))) + println(sum(Tuple10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))) + println(sum(Tuple11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11))) + println(sum(Tuple12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))) + println(sum(Tuple13(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13))) + println(sum(Tuple14(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14))) + println(sum(Tuple15(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))) + println(sum(Tuple16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16))) + println(sum(Tuple17(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17))) + println(sum(Tuple18(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18))) + println(sum(Tuple19(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19))) + println(sum(Tuple20(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))) + println(sum(Tuple21(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21))) + println(sum(Tuple22(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22))) + } + + inline def sum(inline tup: Tuple1[Int]): Int = ~Macros.tup1(tup) + inline def sum(inline tup: Tuple2[Int, Int]): Int = ~Macros.tup2(tup) + inline def sum(inline tup: Tuple3[Int, Int, Int]): Int = ~Macros.tup3(tup) + inline def sum(inline tup: Tuple4[Int, Int, Int, Int]): Int = ~Macros.tup4(tup) + inline def sum(inline tup: Tuple5[Int, Int, Int, Int, Int]): Int = ~Macros.tup5(tup) + inline def sum(inline tup: Tuple6[Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup6(tup) + inline def sum(inline tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup7(tup) + inline def sum(inline tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup8(tup) + inline def sum(inline tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup9(tup) + inline def sum(inline tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup10(tup) + inline def sum(inline tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup11(tup) + inline def sum(inline tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup12(tup) + inline def sum(inline tup: Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup13(tup) + inline def sum(inline tup: Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup14(tup) + inline def sum(inline tup: Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup15(tup) + inline def sum(inline tup: Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup16(tup) + inline def sum(inline tup: Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup17(tup) + inline def sum(inline tup: Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup18(tup) + inline def sum(inline tup: Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup19(tup) + inline def sum(inline tup: Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup20(tup) + inline def sum(inline tup: Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup21(tup) + inline def sum(inline tup: Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]): Int = ~Macros.tup22(tup) + +} diff --git a/tests/run/inline-tuples-2.check b/tests/run/inline-tuples-2.check new file mode 100644 index 000000000000..de506527864a --- /dev/null +++ b/tests/run/inline-tuples-2.check @@ -0,0 +1,5 @@ +1 +2 +4 +5 +6 diff --git a/tests/run/inline-tuples-2/Macro_1.scala b/tests/run/inline-tuples-2/Macro_1.scala new file mode 100644 index 000000000000..e33f2022adc0 --- /dev/null +++ b/tests/run/inline-tuples-2/Macro_1.scala @@ -0,0 +1,10 @@ + +import scala.quoted._ + +object Macros { + + def impl(tup: Tuple1[Int]): Expr[Int] = tup._1.toExpr + + def impl2(tup: Tuple1[Tuple1[Int]]): Expr[Int] = impl(tup._1) + +} diff --git a/tests/run/inline-tuples-2/Main_2.scala b/tests/run/inline-tuples-2/Main_2.scala new file mode 100644 index 000000000000..d250d919f941 --- /dev/null +++ b/tests/run/inline-tuples-2/Main_2.scala @@ -0,0 +1,22 @@ + +object Test { + + def main(args: Array[String]): Unit = { + println(get1(Tuple1(1))) + println(get1(new Tuple1(2))) + + println(get2(4)) + println(get3(5)) + + println(get4(Tuple1(Tuple1(6)))) + } + + inline def get1(inline tup: Tuple1[Int]): Int = ~Macros.impl(tup) + + inline def get2(inline i: Int): Int = ~Macros.impl(Tuple1(i)) + + inline def get3(inline i: Int): Int = ~Macros.impl2(Tuple1(Tuple1(i))) + + inline def get4(inline tup: Tuple1[Tuple1[Int]]): Int = ~Macros.impl2(tup) + +}