From dd47092e8d58bc750b7ee9478b5aa3db6de7717e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 21 Jan 2020 14:32:52 +0100 Subject: [PATCH 1/2] Redefine semantics of inline parameters See docs/docs/reference/metaprogramming/inline.md --- community-build/community-projects/scalatest | 2 +- community-build/community-projects/utest | 2 +- .../community-projects/xml-interpolator | 2 +- .../dotty/tools/dotc/core/TypeErasure.scala | 2 +- .../src/dotty/tools/dotc/core/Types.scala | 4 +- .../dotty/tools/dotc/reporting/trace.scala | 29 + .../src/dotty/tools/dotc/typer/Checking.scala | 39 +- .../src/dotty/tools/dotc/typer/Inliner.scala | 20 +- .../src/dotty/tools/dotc/typer/Typer.scala | 2 - .../src/dotty/tools/dotc/util/Stats.scala | 9 +- .../tools/backend/jvm/ArrayApplyOptTest.scala | 60 +- .../backend/jvm/InlineBytecodeTests.scala | 14 +- docs/docs/reference/metaprogramming/inline.md | 28 +- library/src/dotty/DottyPredef.scala | 2 +- library/src/scala/IArray.scala | 47 +- .../inline-case-objects/Macro_1.scala | 16 - .../inline-case-objects/Main_2.scala | 11 - .../Macro_1.scala | 3 +- .../Main_2.scala | 8 +- tests/neg-macros/inline-option/Macro_1.scala | 2 +- tests/neg-macros/inline-option/Main_2.scala | 8 +- .../neg-macros/inline-tuples-1/Macro_1.scala | 44 +- tests/neg-macros/inline-tuples-1/Main_2.scala | 594 +++++++++--------- .../tasty-macro-assert-1/quoted_1.scala | 2 +- .../tasty-macro-assert-2/quoted_1.scala | 2 +- tests/neg/i6622f.scala | 2 +- tests/neg/inlinevals.scala | 3 +- .../tasty-definitions-2/Macro_1.scala | 2 +- .../tasty-definitions-3/Macro_1.scala | 2 +- .../tasty-extractors-owners/quoted_1.scala | 2 +- .../tasty-load-tree-1/quoted_1.scala | 2 +- .../tasty-load-tree-2/quoted_1.scala | 2 +- tests/run-macros/expr-map-1/Macro_1.scala | 2 +- tests/run-macros/expr-map-2.check | 2 +- tests/run-macros/expr-map-2/Macro_1.scala | 2 +- tests/run-macros/expr-map-2/Test_2.scala | 2 +- .../f-interpolator-neg/Macros_1.scala | 2 +- .../run-macros/flops-rewrite-2/Macro_1.scala | 2 +- .../run-macros/flops-rewrite-3/Macro_1.scala | 2 +- tests/run-macros/flops-rewrite/Macro_1.scala | 2 +- tests/run-macros/i4947e/Test_2.scala | 2 +- tests/run-macros/i4947f/Macro_1.scala | 2 +- tests/run-macros/i5941/macro_1.scala | 2 +- .../inferred-repeated-result/test_1.scala | 2 +- .../quote-impure-by-name/quoted_1.scala | 2 +- tests/run-macros/quote-inline-function.check | 21 +- .../quote-inline-function/quoted_1.scala | 1 + .../quote-inline-function/quoted_2.scala | 4 + .../quote-matcher-runtime/quoted_1.scala | 2 +- .../quoted_1.scala | 2 +- .../quote-matching-optimize-1/Macro_1.scala | 2 +- .../quote-matching-optimize-2/Macro_1.scala | 2 +- .../quote-matching-optimize-3/Macro_1.scala | 2 +- .../string-context-implicits/Macro_1.scala | 2 +- .../tasty-custom-show/quoted_1.scala | 2 +- .../tasty-extractors-1/quoted_1.scala | 2 +- .../tasty-extractors-2/quoted_1.scala | 2 +- .../tasty-extractors-3/quoted_1.scala | 2 +- .../tasty-macro-assert/quoted_1.scala | 2 +- .../Macros_1.scala | 4 +- tests/run-with-compiler/i6270/Macro_1.scala | 2 +- tests/run/i4947.scala | 2 +- tests/run/i4947a2.scala | 2 +- tests/run/i4947b/Lib_1.scala | 4 +- tests/run/i4947c.scala | 2 +- tests/run/inline-param-semantics.check | 52 ++ tests/run/inline-param-semantics.scala | 55 ++ 67 files changed, 648 insertions(+), 516 deletions(-) delete mode 100644 tests/neg-macros/inline-case-objects/Macro_1.scala delete mode 100644 tests/neg-macros/inline-case-objects/Main_2.scala create mode 100644 tests/run/inline-param-semantics.check create mode 100644 tests/run/inline-param-semantics.scala diff --git a/community-build/community-projects/scalatest b/community-build/community-projects/scalatest index 4761d52382cc..c9a7d5883150 160000 --- a/community-build/community-projects/scalatest +++ b/community-build/community-projects/scalatest @@ -1 +1 @@ -Subproject commit 4761d52382cc21cb29643bca5b82b22b2bc2d03d +Subproject commit c9a7d5883150fba08942755867b619694aff498e diff --git a/community-build/community-projects/utest b/community-build/community-projects/utest index a714eb9161ed..e1f7a918da2e 160000 --- a/community-build/community-projects/utest +++ b/community-build/community-projects/utest @@ -1 +1 @@ -Subproject commit a714eb9161ed733138f25a115a7a9c5ce268fefd +Subproject commit e1f7a918da2eec8ad1740c614f9cbc6cbdb13fd5 diff --git a/community-build/community-projects/xml-interpolator b/community-build/community-projects/xml-interpolator index f3185019a161..48ce1920e0e4 160000 --- a/community-build/community-projects/xml-interpolator +++ b/community-build/community-projects/xml-interpolator @@ -1 +1 @@ -Subproject commit f3185019a16182a2fba20523ccfff6665436424a +Subproject commit 48ce1920e0e4b8849f35defe8e73a4fb0a7ecebf diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 394e9a58fe5e..ff5671246529 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -533,7 +533,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean // but potentially re-introduced by ResolveSuper, when we add // forwarders to mixin methods. // See doc comment for ElimByName for speculation how we could improve this. - else MethodType(Nil, Nil, eraseResult(sym.info.finalResultType)) + else MethodType(Nil, Nil, eraseResult(sym.info.finalResultType.underlyingIfRepeated(isJava))) case tp: PolyType => eraseResult(tp.resultType) match { case rt: MethodType => rt diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 4d789c05ba85..8e8d105695c8 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -3360,11 +3360,11 @@ object Types { /** Produce method type from parameter symbols, with special mappings for repeated * and inline parameters: * - replace @repeated annotations on Seq or Array types by types - * - add @inlineParam to inline call-by-value parameters + * - add @inlineParam to inline parameters */ def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context): MethodType = { def translateInline(tp: Type): Type = tp match { - case _: ExprType => tp + case ExprType(resType) => ExprType(AnnotatedType(resType, Annotation(defn.InlineParamAnnot))) case _ => AnnotatedType(tp, Annotation(defn.InlineParamAnnot)) } def paramInfo(param: Symbol) = { diff --git a/compiler/src/dotty/tools/dotc/reporting/trace.scala b/compiler/src/dotty/tools/dotc/reporting/trace.scala index bf85dc8de82d..948038a54721 100644 --- a/compiler/src/dotty/tools/dotc/reporting/trace.scala +++ b/compiler/src/dotty/tools/dotc/reporting/trace.scala @@ -25,9 +25,18 @@ object trace extends TraceSyntax { abstract class TraceSyntax { val isForced: Boolean + // FIXME Use this signature after reference compiler is updated + // inline def onDebug[TD](inline question: String)(inline op: TD)(implicit ctx: Context): TD = inline def onDebug[TD](question: => String)(op: => TD)(implicit ctx: Context): TD = conditionally(ctx.settings.YdebugTrace.value, question, false)(op) + // FIXME Use this implementation after reference compiler is updated + // inline def conditionally[TC](inline cond: Boolean, inline question: String, inline show: Boolean)(op: => TC)(implicit ctx: Context): TC = + // inline if (isForced || Config.tracingEnabled) { + // if (cond) apply[TC](question, Printers.default, show)(op) + // else op + // } + // else op inline def conditionally[TC](cond: Boolean, question: => String, show: Boolean)(op: => TC)(implicit ctx: Context): TC = inline if (isForced || Config.tracingEnabled) { def op1 = op @@ -36,6 +45,13 @@ abstract class TraceSyntax { } else op + // FIXME Use this implementation after reference compiler is updated + // inline def apply[T](inline question: String, inline printer: Printers.Printer, inline showOp: Any => String)(op: => T)(implicit ctx: Context): T = + // inline if (isForced || Config.tracingEnabled) { + // if (!isForced && printer.eq(config.Printers.noPrinter)) op + // else doTrace[T](question, printer, showOp)(op) + // } + // else op inline def apply[T](question: => String, printer: Printers.Printer, showOp: Any => String)(op: => T)(implicit ctx: Context): T = inline if (isForced || Config.tracingEnabled) { def op1 = op @@ -44,6 +60,13 @@ abstract class TraceSyntax { } else op + // FIXME Use this implementation after reference compiler is updated + // inline def apply[T](inline question: String, inline printer: Printers.Printer, inline show: Boolean)(op: => T)(implicit ctx: Context): T = + // inline if (isForced || Config.tracingEnabled) { + // if (!isForced && printer.eq(config.Printers.noPrinter)) op + // else doTrace[T](question, printer, if (show) showShowable(_) else alwaysToString)(op) + // } + // else op inline def apply[T](question: => String, printer: Printers.Printer, show: Boolean)(op: => T)(implicit ctx: Context): T = inline if (isForced || Config.tracingEnabled) { def op1 = op @@ -52,12 +75,18 @@ abstract class TraceSyntax { } else op + // FIXME Use this signature after reference compiler is updated + // inline def apply[T](inline question: String, inline printer: Printers.Printer)(inline op: T)(implicit ctx: Context): T = inline def apply[T](question: => String, printer: Printers.Printer)(op: => T)(implicit ctx: Context): T = apply[T](question, printer, false)(op) + // FIXME Use this signature after reference compiler is updated + // inline def apply[T](inline question: String, inline show: Boolean)(inline op: T)(implicit ctx: Context): T = inline def apply[T](question: => String, show: Boolean)(op: => T)(implicit ctx: Context): T = apply[T](question, Printers.default, show)(op) + // FIXME Use this signature after reference compiler is updated + // inline def apply[T](inline question: String)(inline op: T)(implicit ctx: Context): T = inline def apply[T](question: => String)(op: => T)(implicit ctx: Context): T = apply[T](question, Printers.default, false)(op) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index b6a14e6d6ae9..4351164fdc3a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -818,43 +818,8 @@ trait Checking { tree.tpe.widenTermRefExpr match { case tp: ConstantType if exprPurity(tree) >= purityLevel => // ok case _ => - tree match { - case Typed(expr, _) => - checkInlineConformant(expr, isFinal, what) - case Inlined(_, Nil, expr) => - checkInlineConformant(expr, isFinal, what) - case SeqLiteral(elems, _) => - elems.foreach(elem => checkInlineConformant(elem, isFinal, what)) - case Apply(fn, List(arg)) if defn.WrapArrayMethods().contains(fn.symbol) => - checkInlineConformant(arg, isFinal, what) - case _ => - 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) - def isStaticEnumCase(sym: Symbol): Boolean = - sym.is(Enum) && sym.is(JavaStatic) && sym.is(Case) - val allow = - ctx.erasedTypes || - ctx.inInlineMethod || - (tree.symbol.isStatic && isCaseObject(tree.symbol) || isCaseClassApply(tree.symbol)) || - isStaticEnumCase(tree.symbol) || - isCaseClassNew(tree.symbol) - - if (!allow) ctx.error(em"$what must be a known value", tree.sourcePos) - else { - def checkArgs(tree: Tree): Unit = tree match { - case Apply(fn, args) => - args.foreach(arg => checkInlineConformant(arg, isFinal, what)) - checkArgs(fn) - case _ => - } - checkArgs(tree) - } - } + if (!ctx.erasedTypes && !ctx.inInlineMethod) + ctx.error(em"$what must be a known value", tree.sourcePos) } } diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 3dc8032d139c..c824e9ef403e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -208,7 +208,8 @@ object Inliner { } val Apply(_, codeArg :: Nil) = tree - ConstFold(stripTyped(codeArg.underlyingArgument)).tpe.widenTermRefExpr match { + val underlyingCodeArg = stripTyped(codeArg.underlying) + ConstFold(underlyingCodeArg).tpe.widenTermRefExpr match { case ConstantType(Constant(code: String)) => val source2 = SourceFile.virtual("tasty-reflect", code) val ctx2 = ctx.fresh.setNewTyperState().setTyper(new Typer).setSource(source2) @@ -223,7 +224,7 @@ object Inliner { res ++= typerErrors.map(e => ErrorKind.Typer -> e) res.toList case t => - assert(ctx.reporter.hasErrors) // at least: argument to inline parameter must be a known value + ctx.error("argument to compileError must be a statically known String", underlyingCodeArg.sourcePos) Nil } @@ -333,9 +334,10 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { val argtpe = arg.tpe.dealiasKeepAnnots val isByName = paramtp.dealias.isInstanceOf[ExprType] var inlineFlags: FlagSet = InlineProxy - if (paramtp.hasAnnotation(defn.InlineParamAnnot)) inlineFlags |= Inline + if (paramtp.widenExpr.hasAnnotation(defn.InlineParamAnnot)) inlineFlags |= Inline + if (isByName) inlineFlags |= Method val (bindingFlags, bindingType) = - if (isByName) (InlineByNameProxy.toTermFlags, ExprType(argtpe.widen)) + if (isByName) (inlineFlags, ExprType(argtpe.widen)) else (inlineFlags, argtpe.widen) val boundSym = newSym(name, bindingFlags, bindingType).asTerm val binding = { @@ -765,10 +767,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { def search(buf: mutable.ListBuffer[ValOrDefDef]) = buf.find(_.name == tree.name) if (paramProxies.contains(tree.typeOpt)) search(bindingsBuf) match { - case Some(vdef: ValDef) if vdef.symbol.is(Inline) => - Some(integrate(vdef.rhs, vdef.symbol)) - case Some(ddef: DefDef) => - Some(integrate(ddef.rhs, ddef.symbol)) + case Some(bind: ValOrDefDef) if bind.symbol.is(Inline) => + Some(integrate(bind.rhs, bind.symbol)) case _ => None } else None @@ -1198,7 +1198,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { val bindingOfSym = newMutableSymbolMap[MemberDef] def isInlineable(binding: MemberDef) = binding match { - case DefDef(_, Nil, Nil, _, _) => true + case ddef @ DefDef(_, Nil, Nil, _, _) => isPureExpr(ddef.rhs) case vdef @ ValDef(_, _, _) => isPureExpr(vdef.rhs) case _ => false } @@ -1236,7 +1236,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { case Some(x) => x > 1 || x == 1 && !boundSym.is(Method) case none => true } - } && !(boundSym.isAllOf(InlineMethod) && boundSym.isOneOf(GivenOrImplicit)) + } && !boundSym.is(Inline) val inlineBindings = new TreeMap { override def transform(t: Tree)(implicit ctx: Context) = t match { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index fccde2085179..d74d54c70a81 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2910,8 +2910,6 @@ class Typer extends Namer tree } else if (tree.tpe.widenExpr <:< pt) { - if (pt.hasAnnotation(defn.InlineParamAnnot)) - checkInlineConformant(tree, isFinal = false, "argument to inline parameter") if (ctx.typeComparer.GADTused && pt.isValueType) // Insert an explicit cast, so that -Ycheck in later phases succeeds. // I suspect, but am not 100% sure that this might affect inferred types, diff --git a/compiler/src/dotty/tools/dotc/util/Stats.scala b/compiler/src/dotty/tools/dotc/util/Stats.scala index e7a28861fdd4..e5ec584cc48b 100644 --- a/compiler/src/dotty/tools/dotc/util/Stats.scala +++ b/compiler/src/dotty/tools/dotc/util/Stats.scala @@ -19,6 +19,8 @@ import collection.mutable override def default(key: String): Int = 0 } + // FIXME Use this signature after reference compiler is updated + // inline def record(inline fn: String, inline n: Int = 1): Unit = inline def record(fn: => String, n: => Int = 1): Unit = if (enabled) doRecord(fn, n) @@ -28,16 +30,17 @@ import collection.mutable hits(name) += n } + // FIXME Use this signature after reference compiler is updated + // inline def trackTime[T](fn: String)(inline op: T): T = inline def trackTime[T](fn: String)(op: => T): T = if (enabled) doTrackTime(fn)(op) else op def doTrackTime[T](fn: String)(op: => T): T = { - def op1 = op if (monitored) { val start = System.nanoTime - try op1 finally record(fn, ((System.nanoTime - start) / 1000).toInt) + try op finally record(fn, ((System.nanoTime - start) / 1000).toInt) } - else op1 + else op } final val GroupChar = '/' diff --git a/compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala b/compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala index 502edbd8b170..1b79ab624415 100644 --- a/compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala +++ b/compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala @@ -8,6 +8,8 @@ import scala.tools.asm.Opcodes._ class ArrayApplyOptTest extends DottyBytecodeTest { import ASMConverters._ + // FIXME: Re-enable IArray bytecode tests (requires updated reference compiler) + // Also change: library/src/scala/IArray.scala @Test def testArrayEmptyGenericApply= { test("Array[String]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/String"), Op(POP), Op(RETURN))) test("Array[Unit]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(POP), Op(RETURN))) @@ -22,18 +24,18 @@ class ArrayApplyOptTest extends DottyBytecodeTest { test("Array[Char]()", newArray0Opcodes(T_CHAR)) test("Array[T]()", newArray0Opcodes(T_INT)) - test("IArray[String]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/String"), TypeOp(CHECKCAST, "[Ljava/lang/String;"), Op(POP), Op(RETURN))) - test("IArray[Unit]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN))) - test("IArray[Object]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/Object"), TypeOp(CHECKCAST, "[Ljava/lang/Object;"), Op(POP), Op(RETURN))) - test("IArray[Boolean]()", newArray0Opcodes(T_BOOLEAN, TypeOp(CHECKCAST, "[Z") :: Nil)) - test("IArray[Byte]()", newArray0Opcodes(T_BYTE, TypeOp(CHECKCAST, "[B") :: Nil)) - test("IArray[Short]()", newArray0Opcodes(T_SHORT, TypeOp(CHECKCAST, "[S") :: Nil)) - test("IArray[Int]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil)) - test("IArray[Long]()", newArray0Opcodes(T_LONG, TypeOp(CHECKCAST, "[J") :: Nil)) - test("IArray[Float]()", newArray0Opcodes(T_FLOAT, TypeOp(CHECKCAST, "[F") :: Nil)) - test("IArray[Double]()", newArray0Opcodes(T_DOUBLE, TypeOp(CHECKCAST, "[D") :: Nil)) - test("IArray[Char]()", newArray0Opcodes(T_CHAR, TypeOp(CHECKCAST, "[C") :: Nil)) - test("IArray[T]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil)) + // test("IArray[String]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/String"), TypeOp(CHECKCAST, "[Ljava/lang/String;"), Op(POP), Op(RETURN))) + // test("IArray[Unit]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN))) + // test("IArray[Object]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/Object"), TypeOp(CHECKCAST, "[Ljava/lang/Object;"), Op(POP), Op(RETURN))) + // test("IArray[Boolean]()", newArray0Opcodes(T_BOOLEAN, TypeOp(CHECKCAST, "[Z") :: Nil)) + // test("IArray[Byte]()", newArray0Opcodes(T_BYTE, TypeOp(CHECKCAST, "[B") :: Nil)) + // test("IArray[Short]()", newArray0Opcodes(T_SHORT, TypeOp(CHECKCAST, "[S") :: Nil)) + // test("IArray[Int]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil)) + // test("IArray[Long]()", newArray0Opcodes(T_LONG, TypeOp(CHECKCAST, "[J") :: Nil)) + // test("IArray[Float]()", newArray0Opcodes(T_FLOAT, TypeOp(CHECKCAST, "[F") :: Nil)) + // test("IArray[Double]()", newArray0Opcodes(T_DOUBLE, TypeOp(CHECKCAST, "[D") :: Nil)) + // test("IArray[Char]()", newArray0Opcodes(T_CHAR, TypeOp(CHECKCAST, "[C") :: Nil)) + // test("IArray[T]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil)) } @Test def testArrayGenericApply= { @@ -44,74 +46,74 @@ class ArrayApplyOptTest extends DottyBytecodeTest { def opCodes2(tpe: String) = List(Op(ICONST_2), TypeOp(ANEWARRAY, tpe), Op(DUP), Op(ICONST_0), Ldc(LDC, "a"), Op(AASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, "b"), Op(AASTORE), TypeOp(CHECKCAST, s"[L$tpe;"), Op(POP), Op(RETURN)) - test("""IArray("a", "b")""", opCodes2("java/lang/String")) - test("""IArray[Object]("a", "b")""", opCodes2("java/lang/Object")) + // test("""IArray("a", "b")""", opCodes2("java/lang/String")) + // test("""IArray[Object]("a", "b")""", opCodes2("java/lang/Object")) } @Test def testArrayApplyBoolean = { val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_0), Op(BASTORE)) test("Array(true, false)", newArray2Opcodes(T_BOOLEAN, init)) - test("IArray(true, false)", newArray2Opcodes(T_BOOLEAN, init :+ TypeOp(CHECKCAST, "[Z"))) + // test("IArray(true, false)", newArray2Opcodes(T_BOOLEAN, init :+ TypeOp(CHECKCAST, "[Z"))) } @Test def testArrayApplyByte = { val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(BASTORE)) test("Array[Byte](1, 2)", newArray2Opcodes(T_BYTE, init)) - test("IArray[Byte](1, 2)", newArray2Opcodes(T_BYTE, init :+ TypeOp(CHECKCAST, "[B"))) + // test("IArray[Byte](1, 2)", newArray2Opcodes(T_BYTE, init :+ TypeOp(CHECKCAST, "[B"))) } @Test def testArrayApplyShort = { val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(SASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(SASTORE)) test("Array[Short](1, 2)", newArray2Opcodes(T_SHORT, init)) - test("IArray[Short](1, 2)", newArray2Opcodes(T_SHORT, init :+ TypeOp(CHECKCAST, "[S"))) + // test("IArray[Short](1, 2)", newArray2Opcodes(T_SHORT, init :+ TypeOp(CHECKCAST, "[S"))) } @Test def testArrayApplyInt = { val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE)) test("Array(1, 2)", newArray2Opcodes(T_INT, init)) - test("IArray(1, 2)", newArray2Opcodes(T_INT, init :+ TypeOp(CHECKCAST, "[I"))) + // test("IArray(1, 2)", newArray2Opcodes(T_INT, init :+ TypeOp(CHECKCAST, "[I"))) val init2 = List(Op(DUP), Op(ICONST_0), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE), Op(DUP), Op(ICONST_1), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE)) test("""Array[T](t, t)""", newArray2Opcodes(T_INT, init2)) - test("""IArray[T](t, t)""", newArray2Opcodes(T_INT, init2 :+ TypeOp(CHECKCAST, "[I"))) + // test("""IArray[T](t, t)""", newArray2Opcodes(T_INT, init2 :+ TypeOp(CHECKCAST, "[I"))) } @Test def testArrayApplyLong = { val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2), Op(LASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3), Op(LASTORE)) test("Array(2L, 3L)", newArray2Opcodes(T_LONG, init)) - test("IArray(2L, 3L)", newArray2Opcodes(T_LONG, init :+ TypeOp(CHECKCAST, "[J"))) + // test("IArray(2L, 3L)", newArray2Opcodes(T_LONG, init :+ TypeOp(CHECKCAST, "[J"))) } @Test def testArrayApplyFloat = { val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.1f), Op(FASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.1f), Op(FASTORE)) test("Array(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init)) - test("IArray(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init :+ TypeOp(CHECKCAST, "[F"))) + // test("IArray(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init :+ TypeOp(CHECKCAST, "[F"))) } @Test def testArrayApplyDouble = { val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.2d), Op(DASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.2d), Op(DASTORE)) test("Array(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init)) - test("IArray(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init :+ TypeOp(CHECKCAST, "[D"))) + // test("IArray(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init :+ TypeOp(CHECKCAST, "[D"))) } @Test def testArrayApplyChar = { val init = List(Op(DUP), Op(ICONST_0), IntOp(BIPUSH, 120), Op(CASTORE), Op(DUP), Op(ICONST_1), IntOp(BIPUSH, 121), Op(CASTORE)) test("Array('x', 'y')", newArray2Opcodes(T_CHAR, init)) - test("IArray('x', 'y')", newArray2Opcodes(T_CHAR, init :+ TypeOp(CHECKCAST, "[C"))) + // test("IArray('x', 'y')", newArray2Opcodes(T_CHAR, init :+ TypeOp(CHECKCAST, "[C"))) } @Test def testArrayApplyUnit = { test("Array[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP), Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP), Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(POP), Op(RETURN))) - test("IArray[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP), - Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP), - Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN))) + // test("IArray[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP), + // Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP), + // Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN))) } @Test def testArrayInlined = test( """{ - | inline def array(xs: =>Int*): Array[Int] = Array(xs: _*) + | inline def array(inline xs: Int*): Array[Int] = Array(xs: _*) | array(1, 2) |}""".stripMargin, newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE), TypeOp(CHECKCAST, "[I"))) @@ -119,7 +121,7 @@ class ArrayApplyOptTest extends DottyBytecodeTest { @Test def testArrayInlined2 = test( """{ - | inline def array(x: =>Int, xs: =>Int*): Array[Int] = Array(x, xs: _*) + | inline def array(inline x: Int, inline xs: Int*): Array[Int] = Array(x, xs: _*) | array(1, 2) |}""".stripMargin, newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE))) @@ -127,7 +129,7 @@ class ArrayApplyOptTest extends DottyBytecodeTest { @Test def testArrayInlined3 = test( """{ - | inline def array[T](xs: =>T*)(given ct: =>scala.reflect.ClassTag[T]): Array[T] = Array(xs: _*) + | inline def array[T](inline xs: T*)(given inline ct: scala.reflect.ClassTag[T]): Array[T] = Array(xs: _*) | array(1, 2) |}""".stripMargin, newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE), TypeOp(CHECKCAST, "[I"))) diff --git a/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala b/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala index 78282717be8b..10de64f45df0 100644 --- a/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala +++ b/compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala @@ -44,7 +44,7 @@ class InlineBytecodeTests extends DottyBytecodeTest { @Test def i4947 = { val source = """class Foo { - | inline def track[T](f: => T) <: T = { + | inline def track[T](inline f: T) <: T = { | foo("tracking") // line 3 | f // line 4 | } @@ -103,11 +103,11 @@ class InlineBytecodeTests extends DottyBytecodeTest { @Test def i4947b = { val source = """class Foo { - | inline def track2[T](f: => T) <: T = { + | inline def track2[T](inline f: T) <: T = { | foo("tracking2") // line 3 | f // line 4 | } - | inline def track[T](f: => T) <: T = { + | inline def track[T](inline f: T) <: T = { | foo("tracking") // line 7 | track2 { // line 8 | f // line 9 @@ -163,11 +163,11 @@ class InlineBytecodeTests extends DottyBytecodeTest { @Test def i4947c = { val source = """class Foo { - | inline def track2[T](f: => T) <: T = { + | inline def track2[T](inline f: T) <: T = { | foo("tracking2") // line 3 | f // line 4 | } - | inline def track[T](f: => T) <: T = { + | inline def track[T](inline f: T) <: T = { | track2 { // line 7 | foo("fgh") // line 8 | f // line 9 @@ -223,11 +223,11 @@ class InlineBytecodeTests extends DottyBytecodeTest { @Test def i4947d = { val source = """class Foo { - | inline def track2[T](f: => T) <: T = { + | inline def track2[T](inline f: T) <: T = { | foo("tracking2") // line 3 | f // line 4 | } - | inline def track[T](f: => T) <: T = { + | inline def track[T](inline f: T) <: T = { | track2 { // line 7 | track2 { // line 8 | f // line 9 diff --git a/docs/docs/reference/metaprogramming/inline.md b/docs/docs/reference/metaprogramming/inline.md index 4b732eafc6f0..e6f3c117e4fc 100644 --- a/docs/docs/reference/metaprogramming/inline.md +++ b/docs/docs/reference/metaprogramming/inline.md @@ -121,11 +121,23 @@ power(expr, 10) ``` Parameters of inline methods can have an `inline` modifier as well. This means -that actual arguments to these parameters must be constant expressions. -For example: +that actual arguments to these parameters will be inlined in the body of the `inline def`. +`inline` parameter have call semantics equivalent to by-name parameters but allows for duplication +of the code in the argument. It is usualy useful constant values need to be propagated to allow +further optimizations/reductions. + +The following example shows the difference in translation between by-value, by-name and `inline` +parameters: ```scala -inline def power(x: Double, inline n: Int): Double +inline def sumTwice(a: Int, b: =>Int, inline c: Int) = a + a + b + b + c + c + +sumTwice(x(), y(), z()) +// translates to +// +// val a = x() +// def b = y() +// a + a + b + b + z() + z() ``` ### Relationship to @inline @@ -414,7 +426,7 @@ fail(identity("foo")) // error: failed on: identity("foo") ### The `scala.compiletime.ops` package The `scala.compiletime.ops` package contains types that provide support for -primitive operations on singleton types. For example, +primitive operations on singleton types. For example, `scala.compiletime.ops.int.*` provides support for multiplying two singleton `Int` types, and `scala.compiletime.ops.boolean.&&` for the conjunction of two `Boolean` types. When all arguments to a type in `scala.compiletime.ops` are @@ -425,14 +437,14 @@ import scala.compiletime.ops.int._ import scala.compiletime.ops.boolean._ val conjunction: true && true = true -val multiplication: 3 * 5 = 15 +val multiplication: 3 * 5 = 15 ``` Many of these singleton operation types are meant to be used infix (as in [SLS ยง 3.2.8](https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#infix-types)), and are annotated with [`@infix`](scala.annotation.infix) accordingly. -Since type aliases have the same precedence rules as their term-level +Since type aliases have the same precedence rules as their term-level equivalents, the operations compose with the expected precedence rules: ```scala @@ -440,10 +452,10 @@ import scala.compiletime.ops.int._ val x: 1 + 2 * 3 = 7 ``` -The operation types are located in packages named after the type of the +The operation types are located in packages named after the type of the left-hand side parameter: for instance, `scala.compiletime.int.+` represents addition of two numbers, while `scala.compiletime.string.+` represents string -concatenation. To use both and distinguish the two types from each other, a +concatenation. To use both and distinguish the two types from each other, a match type can dispatch to the correct implementation: ```scala diff --git a/library/src/dotty/DottyPredef.scala b/library/src/dotty/DottyPredef.scala index 69040aef4961..175687be6b53 100644 --- a/library/src/dotty/DottyPredef.scala +++ b/library/src/dotty/DottyPredef.scala @@ -8,7 +8,7 @@ object DottyPredef { assertFail(message) } - inline final def assert(assertion: => Boolean) <: Unit = { + inline final def assert(inline assertion: => Boolean) <: Unit = { if (!assertion) assertFail() } diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 46867b530127..744fcd025598 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -262,32 +262,51 @@ type IArray[+T] = opaques.IArray[T] object IArray { - /** An immutable array of length 0. - */ + /** An immutable array of length 0. */ def empty[T: ClassTag]: IArray[T] = new Array[T](0).asInstanceOf + /** An immutable boolean array of length 0. */ def emptyBooleanIArray = Array.emptyBooleanArray.asInstanceOf[IArray[Boolean]] + /** An immutable byte array of length 0. */ def emptyByteIArray = Array.emptyByteArray.asInstanceOf[IArray[Byte]] + /** An immutable char array of length 0. */ def emptyCharIArray = Array.emptyCharArray.asInstanceOf[IArray[Char]] + /** An immutable double array of length 0. */ def emptyDoubleIArray = Array.emptyDoubleArray.asInstanceOf[IArray[Double]] + /** An immutable float array of length 0. */ def emptyFloatIArray = Array.emptyFloatArray.asInstanceOf[IArray[Float]] + /** An immutable int array of length 0. */ def emptyIntIArray = Array.emptyIntArray.asInstanceOf[IArray[Int]] + /** An immutable long array of length 0. */ def emptyLongIArray = Array.emptyLongArray.asInstanceOf[IArray[Long]] + /** An immutable short array of length 0. */ def emptyShortIArray = Array.emptyShortArray.asInstanceOf[IArray[Short]] + /** An immutable object array of length 0. */ def emptyObjectIArray = Array.emptyObjectArray.asInstanceOf[IArray[Object]] - /** An immutable array with given elements. - */ - inline def apply[T](xs: =>T*)(given ct: => ClassTag[T]): IArray[T] = Array(xs: _*).asInstanceOf - inline def apply(x: Boolean, xs: =>Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Byte, xs: =>Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Short, xs: =>Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Char, xs: =>Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Int, xs: =>Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Long, xs: =>Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Float, xs: =>Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Double, xs: =>Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf - inline def apply(x: Unit, xs: =>Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf + // FIXME: add inline parameters (requires updated reference compiler) + // Also change: compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala + + /** An immutable array with given elements. */ + inline def apply[T](/*inline*/ xs: T*)(given ct: => ClassTag[T]): IArray[T] = Array(xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Boolean, /*inline*/ xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Byte, /*inline*/ xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Short, /*inline*/ xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Char, /*inline*/ xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Int, /*inline*/ xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Long, /*inline*/ xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Float, /*inline*/ xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Double, /*inline*/ xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf + /** An immutable array with given elements. */ + inline def apply(/*inline*/ x: Unit, /*inline*/ xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf /** Concatenates all arrays into a single immutable array. * diff --git a/tests/neg-macros/inline-case-objects/Macro_1.scala b/tests/neg-macros/inline-case-objects/Macro_1.scala deleted file mode 100644 index c0e771cc24db..000000000000 --- a/tests/neg-macros/inline-case-objects/Macro_1.scala +++ /dev/null @@ -1,16 +0,0 @@ - -import scala.quoted._ - -object Macros { - def impl(foo: Any) with QuoteContext : Expr[String] = Expr(foo.getClass.getCanonicalName) -} - -class Bar { - case object Baz -} - -package foo { - class Bar { - case object Baz - } -} diff --git a/tests/neg-macros/inline-case-objects/Main_2.scala b/tests/neg-macros/inline-case-objects/Main_2.scala deleted file mode 100644 index 95488814cadf..000000000000 --- a/tests/neg-macros/inline-case-objects/Main_2.scala +++ /dev/null @@ -1,11 +0,0 @@ - -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-macros/inline-macro-staged-interpreter/Macro_1.scala b/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala index 735f9248db2c..26d8d4ae15b3 100644 --- a/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala +++ b/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala @@ -12,7 +12,8 @@ object E { implicit def ev1[T: Type]: ValueOfExpr[E[T]] = new ValueOfExpr { def apply(x: Expr[E[T]]) with QuoteContext : Option[E[T]] = x match { case '{ I(${Const(n)}) } => Some(I(n).asInstanceOf[E[T]]) - case '{ Plus[T](${Value(x)}, ${Value(y)})(given $op) } => Some(Plus(x, y)(given Plus2.IPlus.asInstanceOf[Plus2[T]]).asInstanceOf[E[T]]) + case '{ Plus[T](${Value(x)}, ${Value(y)})(given $op) } if op.matches('{Plus2.IPlus}) => Some(Plus(x, y)(given Plus2.IPlus.asInstanceOf[Plus2[T]]).asInstanceOf[E[T]]) + case _ => None } } diff --git a/tests/neg-macros/inline-macro-staged-interpreter/Main_2.scala b/tests/neg-macros/inline-macro-staged-interpreter/Main_2.scala index 957f656fe17c..e6b68b2b71b0 100644 --- a/tests/neg-macros/inline-macro-staged-interpreter/Main_2.scala +++ b/tests/neg-macros/inline-macro-staged-interpreter/Main_2.scala @@ -7,13 +7,13 @@ object Test { i // error ) - E.eval(Plus( - i, // error + E.eval(Plus( // error + i, I(4))) val plus = Plus2.IPlus - E.eval(Plus(I(2), I(4))( - plus // error + E.eval(Plus(I(2), I(4))( // error + plus )) } diff --git a/tests/neg-macros/inline-option/Macro_1.scala b/tests/neg-macros/inline-option/Macro_1.scala index 7ca34882a06d..1662011dcb3e 100644 --- a/tests/neg-macros/inline-option/Macro_1.scala +++ b/tests/neg-macros/inline-option/Macro_1.scala @@ -2,7 +2,7 @@ import scala.quoted._ object Macro { - def impl(opt: Option[Int]) with QuoteContext : Expr[Int] = opt match { + def impl(opt: Expr[Option[Int]]) with QuoteContext : Expr[Int] = opt.value match { case Some(i) => Expr(i) case None => '{-1} } diff --git a/tests/neg-macros/inline-option/Main_2.scala b/tests/neg-macros/inline-option/Main_2.scala index 37425a3b4aa3..66f14582e2c9 100644 --- a/tests/neg-macros/inline-option/Main_2.scala +++ b/tests/neg-macros/inline-option/Main_2.scala @@ -6,10 +6,10 @@ object Main { val b: Option[Int] = Some(4) size(b) // error - inline def size(inline opt: Option[Int]): Int = ${ Macro.impl(opt) } + inline def size(inline opt: Option[Int]): Int = ${ Macro.impl('opt) } - inline def size2(inline i: Int): Int = ${ Macro.impl(None) } + inline def size2(inline i: Int): Int = ${ Macro.impl('None) } + + inline def size3(inline i: Int): Int = ${ Macro.impl('{Some(i)}) } - inline def size3(inline i: Int): Int = ${ Macro.impl(Some(i)) } - } \ No newline at end of file diff --git a/tests/neg-macros/inline-tuples-1/Macro_1.scala b/tests/neg-macros/inline-tuples-1/Macro_1.scala index 7317640726bd..bdf0bdf0f63d 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.{given _} object Macros { - def tup1(tup: Tuple1[Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup2(tup: Tuple2[Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup3(tup: Tuple3[Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup4(tup: Tuple4[Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup5(tup: Tuple5[Int, Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup6(tup: Tuple6[Int, Int, Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup7(tup: Tuple7[Int, Int, Int, Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup8(tup: Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup9(tup: Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup10(tup: Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup11(tup: Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum - def tup12(tup: Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : 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]) with QuoteContext : Expr[Int] = tup.productIterator.map(_.asInstanceOf[Int]).sum + def tup1(tup: Expr[Tuple1[Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup2(tup: Expr[Tuple2[Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup3(tup: Expr[Tuple3[Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup4(tup: Expr[Tuple4[Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup5(tup: Expr[Tuple5[Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup6(tup: Expr[Tuple6[Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup7(tup: Expr[Tuple7[Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup8(tup: Expr[Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup9(tup: Expr[Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup10(tup: Expr[Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup11(tup: Expr[Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup12(tup: Expr[Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup13(tup: Expr[Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup14(tup: Expr[Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup15(tup: Expr[Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup16(tup: Expr[Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup17(tup: Expr[Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup18(tup: Expr[Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup19(tup: Expr[Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup20(tup: Expr[Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup21(tup: Expr[Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum + def tup22(tup: Expr[Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) with QuoteContext : Expr[Int] = tup.value.productIterator.map(_.asInstanceOf[Int]).sum } diff --git a/tests/neg-macros/inline-tuples-1/Main_2.scala b/tests/neg-macros/inline-tuples-1/Main_2.scala index 16d7916c55a1..9ce12b88e694 100644 --- a/tests/neg-macros/inline-tuples-1/Main_2.scala +++ b/tests/neg-macros/inline-tuples-1/Main_2.scala @@ -48,326 +48,326 @@ object Test { println(sum(t22)) // error val a: Int = 1 - println(sum(Tuple1( - a // error + println(sum(Tuple1( // error + a ))) - println(sum(Tuple2( - a, // error - a // error + println(sum(Tuple2( // error + a, + a ))) - println(sum(Tuple3( - a, // error - a, // error - a // error + println(sum(Tuple3( // error + a, + a, + a ))) - println(sum(Tuple4( - a, // error - a, // error - a, // error - a // error + println(sum(Tuple4( // error + a, + a, + a, + a ))) - println(sum(Tuple5( - a, // error - a, // error - a, // error - a, // error - a // error + println(sum(Tuple5( // error + a, + a, + a, + a, + a ))) - println(sum(Tuple6( - a, // error - a, // error - a, // error - a, // error - a, // error - a // error + println(sum(Tuple6( // error + a, + a, + a, + a, + a, + a ))) - println(sum(Tuple7( - a, // error - a, // error - a, // error - a, // error - a, // error - a, // error - a // error + println(sum(Tuple7( // error + a, + a, + a, + a, + a, + a, + a ))) - println(sum(Tuple8( - a, // error - a, // error - a, // error - a, // error - a, // error - a, // error - a, // error - a // error + println(sum(Tuple8( // error + a, + a, + a, + a, + a, + a, + a, + a ))) - println(sum(Tuple9( - a, // error - a, // error - a, // error - a, // error - a, // error - a, // error - a, // error - a, // error - a // error + println(sum(Tuple9( // error + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple10( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple11( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple12( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple13( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple14( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple15( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple16( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple17( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple18( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple19( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple20( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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(Tuple21( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) - 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 + println(sum(Tuple22( // error + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a ))) } - 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) } + 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/neg-macros/tasty-macro-assert-1/quoted_1.scala b/tests/neg-macros/tasty-macro-assert-1/quoted_1.scala index 4d7c7bec2926..66a3bc96e2cd 100644 --- a/tests/neg-macros/tasty-macro-assert-1/quoted_1.scala +++ b/tests/neg-macros/tasty-macro-assert-1/quoted_1.scala @@ -9,7 +9,7 @@ object Asserts { object Ops - inline def macroAssert(cond: => Boolean): Unit = + inline def macroAssert(inline cond: Boolean): Unit = ${impl('cond)} def impl(cond: Expr[Boolean]) with (qctx: QuoteContext) : Expr[Unit] = { 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 76c8e04bfbfe..1c2996a71307 100644 --- a/tests/neg-macros/tasty-macro-assert-2/quoted_1.scala +++ b/tests/neg-macros/tasty-macro-assert-2/quoted_1.scala @@ -9,7 +9,7 @@ object Asserts { object Ops - inline def macroAssert(cond: => Boolean): Unit = + inline def macroAssert(inline cond: Boolean): Unit = ${ impl('cond) } def impl(cond: Expr[Boolean]) with (qctx: QuoteContext) : Expr[Unit] = { diff --git a/tests/neg/i6622f.scala b/tests/neg/i6622f.scala index e90a44172d29..72dd8308e071 100644 --- a/tests/neg/i6622f.scala +++ b/tests/neg/i6622f.scala @@ -6,6 +6,6 @@ object Test { fail(println("foo")) // error } - inline def fail(p1: => Any) = error(code"failed: $p1 ...") + inline def fail(inline p1: Any) = error(code"failed: $p1 ...") } diff --git a/tests/neg/inlinevals.scala b/tests/neg/inlinevals.scala index 45d073850eaa..eeac86c525d3 100644 --- a/tests/neg/inlinevals.scala +++ b/tests/neg/inlinevals.scala @@ -2,7 +2,8 @@ object Test { def power0(x: Double, inline n: Int): Double = ??? // error - inline def power(x: Double, inline n: Int): Double = ??? // ok + inline def power(x: Double, inline n: Int): Double = // ok + inline if n == 0 then ??? else ??? inline val N = 10 def X = 20 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 c28fa19f308a..b8571a9e454b 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 @@ -3,7 +3,7 @@ import scala.quoted.autolift.{given _} object Foo { - inline def inspectBody(i: => Int): String = + inline def inspectBody(inline i: Int): String = ${ inspectBodyImpl('i) } def inspectBodyImpl(x: Expr[Int]) with (qctx: QuoteContext) : Expr[String] = { 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 6f8789afbd3d..07a55cadda58 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 @@ -3,7 +3,7 @@ import scala.quoted.autolift.{given _} object Foo { - inline def inspectBody(i: => Int): String = + inline def inspectBody(inline i: Int): String = ${ inspectBodyImpl('i) } def inspectBodyImpl(x: Expr[Int]) with (qctx: QuoteContext) : Expr[String] = { 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 d254a5223a8c..3d94c09f539e 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 @@ -3,7 +3,7 @@ import scala.quoted.autolift.{given _} object Macros { - implicit inline def printOwners[T](x: => T): Unit = + implicit inline def printOwners[T](inline x: T): Unit = ${ impl('x) } def impl[T](x: Expr[T]) with (qctx: QuoteContext) : Expr[Unit] = { 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 3fbfeb9cc9a5..fd1b2baf44a9 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 @@ -3,7 +3,7 @@ import scala.quoted._ object Foo { - inline def inspectBody(i: => Int): String = + inline def inspectBody(inline i: Int): String = ${ inspectBodyImpl('i) } def inspectBodyImpl(x: Expr[Int]) with (qctx: QuoteContext) : Expr[String] = { 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 b748dbad9bbb..3efa8fe98648 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 @@ -2,7 +2,7 @@ import scala.quoted._ object Foo { - inline def inspectBody(i: => Int): String = + inline def inspectBody(inline i: Int): String = ${ inspectBodyImpl('i) } def inspectBodyImpl(x: Expr[Int]) with (qctx: QuoteContext) : Expr[String] = { diff --git a/tests/run-macros/expr-map-1/Macro_1.scala b/tests/run-macros/expr-map-1/Macro_1.scala index 3e7d84d97662..5353992b9892 100644 --- a/tests/run-macros/expr-map-1/Macro_1.scala +++ b/tests/run-macros/expr-map-1/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.matching._ -inline def rewrite[T](x: => Any): Any = ${ stringRewriter('x) } +inline def rewrite[T](inline x: Any): Any = ${ stringRewriter('x) } private def stringRewriter(e: Expr[Any]) with QuoteContext : Expr[Any] = StringRewriter.transform(e) diff --git a/tests/run-macros/expr-map-2.check b/tests/run-macros/expr-map-2.check index cbaaa5a883be..f3755cf1e9ad 100644 --- a/tests/run-macros/expr-map-2.check +++ b/tests/run-macros/expr-map-2.check @@ -1,3 +1,3 @@ Foo(2) -4 +2 4 diff --git a/tests/run-macros/expr-map-2/Macro_1.scala b/tests/run-macros/expr-map-2/Macro_1.scala index 31b355ddb0cb..0f64f7940e8d 100644 --- a/tests/run-macros/expr-map-2/Macro_1.scala +++ b/tests/run-macros/expr-map-2/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.matching._ -inline def rewrite[T](x: => Any): Any = ${ stringRewriter('x) } +inline def rewrite[T](inline x: Any): Any = ${ stringRewriter('x) } private def stringRewriter(e: Expr[Any]) with QuoteContext : Expr[Any] = StringRewriter.transform(e) diff --git a/tests/run-macros/expr-map-2/Test_2.scala b/tests/run-macros/expr-map-2/Test_2.scala index 7790ec34cf9f..383398ec8d22 100644 --- a/tests/run-macros/expr-map-2/Test_2.scala +++ b/tests/run-macros/expr-map-2/Test_2.scala @@ -2,7 +2,7 @@ object Test { def main(args: Array[String]): Unit = { println(rewrite(new Foo(2))) - println(rewrite(new Foo(2).x)) + println(rewrite(new Foo(2).x)) // partially evaluated away by inliner to rewrite(2) rewrite { val foo = new Foo(2) diff --git a/tests/run-macros/f-interpolator-neg/Macros_1.scala b/tests/run-macros/f-interpolator-neg/Macros_1.scala index 5ea8dbf21fab..a45e3abecedd 100644 --- a/tests/run-macros/f-interpolator-neg/Macros_1.scala +++ b/tests/run-macros/f-interpolator-neg/Macros_1.scala @@ -6,7 +6,7 @@ import scala.language.implicitConversions object TestFooErrors { // Defined in tests implicit object StringContextOps { - inline def (ctx: => StringContext).foo(args: => Any*): List[(Boolean, Int, Int, Int, String)] = ${ Macro.fooErrors('ctx, 'args) } + inline def (inline ctx: StringContext).foo(inline args: Any*): List[(Boolean, Int, Int, Int, String)] = ${ Macro.fooErrors('ctx, 'args) } } } diff --git a/tests/run-macros/flops-rewrite-2/Macro_1.scala b/tests/run-macros/flops-rewrite-2/Macro_1.scala index 49fd483fa8bc..291309a274ea 100644 --- a/tests/run-macros/flops-rewrite-2/Macro_1.scala +++ b/tests/run-macros/flops-rewrite-2/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.matching._ -inline def rewrite[T](x: => T): T = ${ rewriteMacro('x) } +inline def rewrite[T](inline x: T): T = ${ rewriteMacro('x) } def plus(x: Int, y: Int): Int = x + y def times(x: Int, y: Int): Int = x * y diff --git a/tests/run-macros/flops-rewrite-3/Macro_1.scala b/tests/run-macros/flops-rewrite-3/Macro_1.scala index 1e7a3a3a2e39..e39adfe63a68 100644 --- a/tests/run-macros/flops-rewrite-3/Macro_1.scala +++ b/tests/run-macros/flops-rewrite-3/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.matching._ -inline def rewrite[T](x: => T): T = ${ rewriteMacro('x) } +inline def rewrite[T](inline x: T): T = ${ rewriteMacro('x) } def plus(x: Int, y: Int): Int = x + y def times(x: Int, y: Int): Int = x * y diff --git a/tests/run-macros/flops-rewrite/Macro_1.scala b/tests/run-macros/flops-rewrite/Macro_1.scala index 062eb31771ae..b8aad1c308be 100644 --- a/tests/run-macros/flops-rewrite/Macro_1.scala +++ b/tests/run-macros/flops-rewrite/Macro_1.scala @@ -1,6 +1,6 @@ import scala.quoted._ -inline def rewrite[T](x: => T): T = ${ rewriteMacro('x) } +inline def rewrite[T](inline x: T): T = ${ rewriteMacro('x) } private def rewriteMacro[T: Type](x: Expr[T]) with QuoteContext : Expr[T] = { val rewriter = Rewriter( diff --git a/tests/run-macros/i4947e/Test_2.scala b/tests/run-macros/i4947e/Test_2.scala index 13af75fd5009..9c4227b88e88 100644 --- a/tests/run-macros/i4947e/Test_2.scala +++ b/tests/run-macros/i4947e/Test_2.scala @@ -1,6 +1,6 @@ object Test { - inline def assert2(expr: => Boolean): Unit = ${ Macros.assertImpl('expr) } + inline def assert2(inline expr: Boolean): Unit = ${ Macros.assertImpl('expr) } def main(args: Array[String]): Unit = { val x = 1 diff --git a/tests/run-macros/i4947f/Macro_1.scala b/tests/run-macros/i4947f/Macro_1.scala index 76cc47e94af8..a1a300367055 100644 --- a/tests/run-macros/i4947f/Macro_1.scala +++ b/tests/run-macros/i4947f/Macro_1.scala @@ -9,6 +9,6 @@ object Macros { println($expr) } - inline def assert2(expr: => Boolean): Unit = ${ Macros.assertImpl('expr) } + inline def assert2(inline expr: Boolean): Unit = ${ Macros.assertImpl('expr) } } diff --git a/tests/run-macros/i5941/macro_1.scala b/tests/run-macros/i5941/macro_1.scala index 4c40cd36c20b..cbe66e7ffd39 100644 --- a/tests/run-macros/i5941/macro_1.scala +++ b/tests/run-macros/i5941/macro_1.scala @@ -69,7 +69,7 @@ object GenLens { def apply[S] = new MkGenLens[S] class MkGenLens[S] { - inline def apply[T](get: => (S => T)): Lens[S, T] = ${ Lens.impl('get) } + inline def apply[T](inline get: (S => T)): Lens[S, T] = ${ Lens.impl('get) } } } diff --git a/tests/run-macros/inferred-repeated-result/test_1.scala b/tests/run-macros/inferred-repeated-result/test_1.scala index 1c4c10db47bd..3f19d4461f78 100644 --- a/tests/run-macros/inferred-repeated-result/test_1.scala +++ b/tests/run-macros/inferred-repeated-result/test_1.scala @@ -2,7 +2,7 @@ object Macros { import scala.quoted._ import scala.quoted.autolift.{given _} - inline def go[T](t: => T) = ${ impl('t) } + inline def go[T](inline t: T) = ${ impl('t) } def impl[T](expr: Expr[T]) with (qctx: QuoteContext) : Expr[Unit] = { import qctx.tasty.{_, given _} diff --git a/tests/run-macros/quote-impure-by-name/quoted_1.scala b/tests/run-macros/quote-impure-by-name/quoted_1.scala index ffa86ae1ef84..e75743d1d6a5 100644 --- a/tests/run-macros/quote-impure-by-name/quoted_1.scala +++ b/tests/run-macros/quote-impure-by-name/quoted_1.scala @@ -9,7 +9,7 @@ object Index { implicit def zero[K, T]: Index[K, (K, T)] = new Index("0") - implicit inline def succ[K, H, T](implicit prev: => Index[K, T]): Index[K, (H, T)] = ${ succImpl[K, H, T]('prev) } + implicit inline def succ[K, H, T](implicit inline prev: Index[K, T]): Index[K, (H, T)] = ${ succImpl[K, H, T]('prev) } def succImpl[K: Type, H: Type, T: Type](prev: Expr[Index[K, T]]) with QuoteContext : Expr[Index[K, (H, T)]] = { val value = s"1 + {${prev.show}}" diff --git a/tests/run-macros/quote-inline-function.check b/tests/run-macros/quote-inline-function.check index fea8ac8da71c..958a2c455b9d 100644 --- a/tests/run-macros/quote-inline-function.check +++ b/tests/run-macros/quote-inline-function.check @@ -21,12 +21,29 @@ By name function val j: scala.Int = 5 while (i.<(j)) { val x$3: scala.Int = i - scala.Predef.println(x$3) + f.apply(x$3) i = i.+(1) } while ({ val x$4: scala.Int = i - scala.Predef.println(x$4) + f.apply(x$4) + i = i.+(1) + i.<(j) + }) () +} + +Inline function +{ + var i: scala.Int = 0 + val j: scala.Int = 5 + while (i.<(j)) { + val x$5: scala.Int = i + scala.Predef.println(x$5) + i = i.+(1) + } + while ({ + val x$6: scala.Int = i + scala.Predef.println(x$6) i = i.+(1) i.<(j) }) () diff --git a/tests/run-macros/quote-inline-function/quoted_1.scala b/tests/run-macros/quote-inline-function/quoted_1.scala index 302f6b1029dd..345e699b36b1 100644 --- a/tests/run-macros/quote-inline-function/quoted_1.scala +++ b/tests/run-macros/quote-inline-function/quoted_1.scala @@ -5,6 +5,7 @@ object Macros { inline def foreach1(start: Int, end: Int, f: Int => Unit): String = ${impl('start, 'end, 'f)} inline def foreach2(start: Int, end: Int, f: => Int => Unit): String = ${impl('start, 'end, 'f)} + inline def foreach3(start: Int, end: Int, inline f: Int => Unit): String = ${impl('start, 'end, 'f)} def impl(start: Expr[Int], end: Expr[Int], f: Expr[Int => Unit]) with (qctx: QuoteContext) : Expr[String] = { import qctx.tasty.{_, given _} diff --git a/tests/run-macros/quote-inline-function/quoted_2.scala b/tests/run-macros/quote-inline-function/quoted_2.scala index ea5023e0f8e8..b42249f4ee48 100644 --- a/tests/run-macros/quote-inline-function/quoted_2.scala +++ b/tests/run-macros/quote-inline-function/quoted_2.scala @@ -9,5 +9,9 @@ object Test { println("By name function") println(foreach2(0, 5, x => println(x))) + println() + + println("Inline function") + println(foreach3(0, 5, x => println(x))) } } diff --git a/tests/run-macros/quote-matcher-runtime/quoted_1.scala b/tests/run-macros/quote-matcher-runtime/quoted_1.scala index 46e58ec531d4..bc946744f502 100644 --- a/tests/run-macros/quote-matcher-runtime/quoted_1.scala +++ b/tests/run-macros/quote-matcher-runtime/quoted_1.scala @@ -4,7 +4,7 @@ import scala.quoted.matching._ object Macros { - inline def matches[A, B](a: => A, b: => B): Unit = ${impl('a, 'b)} + inline def matches[A, B](inline a: A, inline b: B): Unit = ${impl('a, 'b)} private def impl[A, B](a: Expr[A], b: Expr[B]) with (qctx: QuoteContext) : Expr[Unit] = { import qctx.tasty.{Bind => _, _} diff --git a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala index cb1fd02c0a9a..559ca528646f 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala @@ -4,7 +4,7 @@ import scala.quoted.matching._ object Macros { - inline def (self: => StringContext) xyz(args: => String*): String = ${impl('self, 'args)} + inline def (self: => StringContext) xyz(inline args: String*): String = ${impl('self, 'args)} private def impl(self: Expr[StringContext], args: Expr[Seq[String]]) with QuoteContext : Expr[String] = { (self, args) match { diff --git a/tests/run-macros/quote-matching-optimize-1/Macro_1.scala b/tests/run-macros/quote-matching-optimize-1/Macro_1.scala index 921d573aab0e..c788e089de21 100644 --- a/tests/run-macros/quote-matching-optimize-1/Macro_1.scala +++ b/tests/run-macros/quote-matching-optimize-1/Macro_1.scala @@ -3,7 +3,7 @@ import scala.quoted.autolift.{given _} object Macro { - inline def optimize[T](x: => T): Any = ${ Macro.impl('x) } + inline def optimize[T](inline x: T): Any = ${ Macro.impl('x) } def impl[T: Type](x: Expr[T]) with QuoteContext : Expr[Any] = { diff --git a/tests/run-macros/quote-matching-optimize-2/Macro_1.scala b/tests/run-macros/quote-matching-optimize-2/Macro_1.scala index 2f37e4630c49..a0b24f4ccde0 100644 --- a/tests/run-macros/quote-matching-optimize-2/Macro_1.scala +++ b/tests/run-macros/quote-matching-optimize-2/Macro_1.scala @@ -5,7 +5,7 @@ import scala.tasty.Reflection object Macro { - inline def optimize[T](x: => T): Any = ${ Macro.impl('x) } + inline def optimize[T](inline x: T): Any = ${ Macro.impl('x) } def impl[T: Type](x: Expr[T]) with QuoteContext : Expr[Any] = { diff --git a/tests/run-macros/quote-matching-optimize-3/Macro_1.scala b/tests/run-macros/quote-matching-optimize-3/Macro_1.scala index d69493310e90..aa08354b1b10 100644 --- a/tests/run-macros/quote-matching-optimize-3/Macro_1.scala +++ b/tests/run-macros/quote-matching-optimize-3/Macro_1.scala @@ -5,7 +5,7 @@ import scala.tasty.Reflection object Macro { - inline def optimize[T](x: => T): Any = ${ Macro.impl('x) } + inline def optimize[T](inline x: T): Any = ${ Macro.impl('x) } def impl[T: Type](x: Expr[T]) with QuoteContext : Expr[Any] = { diff --git a/tests/run-macros/string-context-implicits/Macro_1.scala b/tests/run-macros/string-context-implicits/Macro_1.scala index f8dd6315b915..03f72fda7b5c 100644 --- a/tests/run-macros/string-context-implicits/Macro_1.scala +++ b/tests/run-macros/string-context-implicits/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.matching._ -inline def (sc: StringContext) showMe(args: =>Any*): String = ${ showMeExpr('sc, 'args) } +inline def (sc: StringContext) showMe(inline args: Any*): String = ${ showMeExpr('sc, 'args) } private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]]) with (qctx: QuoteContext) : Expr[String] = { argsExpr match { diff --git a/tests/run-macros/tasty-custom-show/quoted_1.scala b/tests/run-macros/tasty-custom-show/quoted_1.scala index ebcd20a8e7bb..e333856e171e 100644 --- a/tests/run-macros/tasty-custom-show/quoted_1.scala +++ b/tests/run-macros/tasty-custom-show/quoted_1.scala @@ -4,7 +4,7 @@ import scala.quoted.autolift.{given _} object Macros { - implicit inline def printOwners[T](x: => T): Unit = + implicit inline def printOwners[T](inline x: T): Unit = ${ impl('x) } def impl[T](x: Expr[T]) with (qctx: QuoteContext) : Expr[Unit] = { diff --git a/tests/run-macros/tasty-extractors-1/quoted_1.scala b/tests/run-macros/tasty-extractors-1/quoted_1.scala index 5e90067b432b..383373ee03a3 100644 --- a/tests/run-macros/tasty-extractors-1/quoted_1.scala +++ b/tests/run-macros/tasty-extractors-1/quoted_1.scala @@ -3,7 +3,7 @@ import scala.quoted.autolift.{given _} object Macros { - implicit inline def printTree[T](x: => T): Unit = + implicit inline def printTree[T](inline x: T): Unit = ${ impl('x) } def impl[T](x: Expr[T]) with (qctx: QuoteContext) : Expr[Unit] = { diff --git a/tests/run-macros/tasty-extractors-2/quoted_1.scala b/tests/run-macros/tasty-extractors-2/quoted_1.scala index b1010f6fff1d..47c054ba36ee 100644 --- a/tests/run-macros/tasty-extractors-2/quoted_1.scala +++ b/tests/run-macros/tasty-extractors-2/quoted_1.scala @@ -3,7 +3,7 @@ import scala.quoted.autolift.{given _} object Macros { - implicit inline def printTree[T](x: => T): Unit = + implicit inline def printTree[T](inline x: T): Unit = ${ impl('x) } def impl[T](x: Expr[T]) with (qctx: QuoteContext) : Expr[Unit] = { diff --git a/tests/run-macros/tasty-extractors-3/quoted_1.scala b/tests/run-macros/tasty-extractors-3/quoted_1.scala index 2dbbfd65b025..7847e1b649f4 100644 --- a/tests/run-macros/tasty-extractors-3/quoted_1.scala +++ b/tests/run-macros/tasty-extractors-3/quoted_1.scala @@ -4,7 +4,7 @@ import scala.quoted.autolift.{given _} object Macros { - implicit inline def printTypes[T](x: => T): Unit = + implicit inline def printTypes[T](inline x: T): Unit = ${impl('x)} def impl[T](x: Expr[T]) with (qctx: QuoteContext) : Expr[Unit] = { diff --git a/tests/run-macros/tasty-macro-assert/quoted_1.scala b/tests/run-macros/tasty-macro-assert/quoted_1.scala index a284bd15eb5a..178af48d82f1 100644 --- a/tests/run-macros/tasty-macro-assert/quoted_1.scala +++ b/tests/run-macros/tasty-macro-assert/quoted_1.scala @@ -9,7 +9,7 @@ object Asserts { object Ops - inline def macroAssert(cond: => Boolean): Unit = + inline def macroAssert(inline cond: Boolean): Unit = ${impl('cond)} def impl(cond: Expr[Boolean]) with (qctx: QuoteContext) : Expr[Unit] = { diff --git a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala index 059afb5037dc..e07771d50ac3 100644 --- a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala +++ b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala @@ -6,14 +6,14 @@ import scala.language.implicitConversions object Foo { implicit object StringContextOps { - inline def (ctx: => StringContext) foo (args: => Any*): String = ${ Macro.foo('ctx, 'args) } + inline def (inline ctx: StringContext) foo (inline args: Any*): String = ${ Macro.foo('ctx, 'args) } } } object TestFooErrors { // Defined in tests implicit object StringContextOps { - inline def (ctx: => StringContext) foo (args: => Any*): List[(Int, Int, Int, String)] = ${ Macro.fooErrors('ctx, 'args) } + inline def (inline ctx: StringContext) foo (inline args: Any*): List[(Int, Int, Int, String)] = ${ Macro.fooErrors('ctx, 'args) } } } diff --git a/tests/run-with-compiler/i6270/Macro_1.scala b/tests/run-with-compiler/i6270/Macro_1.scala index ab0e44e83894..786e66679eea 100644 --- a/tests/run-with-compiler/i6270/Macro_1.scala +++ b/tests/run-with-compiler/i6270/Macro_1.scala @@ -2,7 +2,7 @@ import scala.quoted._ import scala.quoted.show.SyntaxHighlight.ANSI object api { - inline def (x: => String) reflect : String = + inline def (inline x: String) reflect : String = ${ reflImpl('x) } private def reflImpl(x: Expr[String]) with (qctx: QuoteContext) : Expr[String] = { diff --git a/tests/run/i4947.scala b/tests/run/i4947.scala index 8f2d810c543f..fcae2fb0d58a 100644 --- a/tests/run/i4947.scala +++ b/tests/run/i4947.scala @@ -1,6 +1,6 @@ object Test { - inline def track[T](f: => T): T = { + inline def track[T](inline f: T): T = { printStack("track") printStack("track") f diff --git a/tests/run/i4947a2.scala b/tests/run/i4947a2.scala index a08e9fe01f46..e07fb8326ecd 100644 --- a/tests/run/i4947a2.scala +++ b/tests/run/i4947a2.scala @@ -1,6 +1,6 @@ object Test { - inline def fact[T](inline i: Int)(f: => T): Int = { + inline def fact[T](inline i: Int)(inline f: T): Int = { printStack(i, "track") printStack(i, "track") f diff --git a/tests/run/i4947b/Lib_1.scala b/tests/run/i4947b/Lib_1.scala index 0b6a8c82e28e..8a507bb3ce91 100644 --- a/tests/run/i4947b/Lib_1.scala +++ b/tests/run/i4947b/Lib_1.scala @@ -1,5 +1,5 @@ object Lib { - inline def track[T](f: => T): T = { + inline def track[T](inline f: T): T = { printStack("track") printStack("track") f @@ -12,7 +12,7 @@ object Lib { println(s"$tag (i = $i): ${new Exception().getStackTrace().apply(1)}") } - inline def fact[T](inline i: Int)(f: => T): Int = { + inline def fact[T](inline i: Int)(inline f: T): Int = { printStack("track", i) printStack("track", i) track { diff --git a/tests/run/i4947c.scala b/tests/run/i4947c.scala index 12188de7004d..bd096f6b7202 100644 --- a/tests/run/i4947c.scala +++ b/tests/run/i4947c.scala @@ -1,6 +1,6 @@ object Foo { - inline def track[T](f: => T): T = { + inline def track[T](inline f: T): T = { printStack("track") printStack("track") f diff --git a/tests/run/inline-param-semantics.check b/tests/run/inline-param-semantics.check new file mode 100644 index 000000000000..1d3184e80a0b --- /dev/null +++ b/tests/run/inline-param-semantics.check @@ -0,0 +1,52 @@ +f1(42) + +f2(42) + +g1(42) + +g2(42) + +h1(ArraySeq(42)) + +h2(ArraySeq(42)) + +i1(ArraySeq(42)) + +i2(ArraySeq(42)) + +y +f1(43) + +y +f2(43) +y + +y +g1(43) +y + +y +g2(43) +y + +y +y +h1(ArraySeq(43, 43)) + +y +y +h2(ArraySeq(43, 43)) +y +y + +y +y +i1(ArraySeq(43, 43)) +y +y + +y +y +i2(ArraySeq(43, 43)) +y +y diff --git a/tests/run/inline-param-semantics.scala b/tests/run/inline-param-semantics.scala new file mode 100644 index 000000000000..1bfec4596676 --- /dev/null +++ b/tests/run/inline-param-semantics.scala @@ -0,0 +1,55 @@ + +inline def f1(x: Int): Int = + println(s"f1($x)") + x + +inline def f2(inline x: Int): Int = + println(s"f2($x)") + x + +inline def g1(x: =>Int): Int = + println(s"g1($x)") + x + +inline def g2(inline x: =>Int): Int = + println(s"g2($x)") + x + +inline def h1(x: Int*): Int = + println(s"h1($x)") + x.sum + +inline def h2(inline x: Int*): Int = + println(s"h2($x)") + x.sum + +inline def i1(x: =>Int*): Int = + println(s"i1($x)") + x.sum + +inline def i2(inline x: =>Int*): Int = + println(s"i2($x)") + x.sum + +def y: Int = + println("y") + 43 + +@main() def Test: Unit = { + f1(42); println() + f2(42); println() + g1(42); println() + g2(42); println() + h1(42); println() + h2(42); println() + i1(42); println() + i2(42); println() + f1(y); println() + f2(y); println() + g1(y); println() + g2(y); println() + h1(y, y); println() + h2(y, y); println() + i1(y, y); println() + i2(y, y) +} From c80644c5c384efa7ac6fed069206132a5c93459f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 27 Jan 2020 14:56:43 +0100 Subject: [PATCH 2/2] Update inline.md --- docs/docs/reference/metaprogramming/inline.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/reference/metaprogramming/inline.md b/docs/docs/reference/metaprogramming/inline.md index e6f3c117e4fc..c9bad79d5a28 100644 --- a/docs/docs/reference/metaprogramming/inline.md +++ b/docs/docs/reference/metaprogramming/inline.md @@ -132,12 +132,12 @@ parameters: ```scala inline def sumTwice(a: Int, b: =>Int, inline c: Int) = a + a + b + b + c + c -sumTwice(x(), y(), z()) +sumTwice(f(), g(), h()) // translates to // -// val a = x() -// def b = y() -// a + a + b + b + z() + z() +// val a = f() +// def b = g() +// a + a + b + b + h() + h() ``` ### Relationship to @inline