From 1d26443e637c4b61089782723af8151f338f110a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 7 Oct 2018 21:23:41 +0200 Subject: [PATCH 1/3] Fix #5188: See through annotations when computing argument types. See through annotations (and typevars) when computing argument types. --- compiler/src/dotty/tools/dotc/core/TypeApplications.scala | 2 +- tests/pos/i5188.scala | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i5188.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala index 59243d7e19eb..ec2b72a1508d 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala @@ -461,7 +461,7 @@ class TypeApplications(val self: Type) extends AnyVal { * otherwise return Nil. * Existential types in arguments are returned as TypeBounds instances. */ - final def argInfos(implicit ctx: Context): List[Type] = self match { + final def argInfos(implicit ctx: Context): List[Type] = self.stripTypeVar.stripAnnots match { case AppliedType(tycon, args) => args case _ => Nil } diff --git a/tests/pos/i5188.scala b/tests/pos/i5188.scala new file mode 100644 index 000000000000..26fdaa729d08 --- /dev/null +++ b/tests/pos/i5188.scala @@ -0,0 +1,4 @@ +object Test { + inline def sum(inline args: Int*): Int = 0 + sum(1, 2, 3) +} \ No newline at end of file From 7f2f5ce1dd5d7c3b14374b41759438263bbf4932 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 10 Oct 2018 10:28:41 +0200 Subject: [PATCH 2/3] Allow sequence literals in inline parameters --- .../src/dotty/tools/dotc/typer/Checking.scala | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index a853965ea1bf..4e33016e89b3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -678,29 +678,39 @@ trait Checking { val purityLevel = if (isFinal) Idempotent else Pure 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 || - (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) + case _ => + tree match { + case Typed(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) + } + val allow = + ctx.erasedTypes || + ctx.inInlineMethod || + (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) + } } } } From 94987ea932ea5d490076ee2a07d066dec9764465 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 10 Oct 2018 10:29:57 +0200 Subject: [PATCH 3/3] Fix interpretation of inlined sequence literals --- compiler/src/dotty/tools/dotc/transform/Splicer.scala | 5 ++++- compiler/test/dotc/run-test-pickling.blacklist | 1 + tests/run/i5188a.check | 4 ++++ tests/run/i5188a/Macro_1.scala | 6 ++++++ tests/run/i5188a/Test_2.scala | 9 +++++++++ 5 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/run/i5188a.check create mode 100644 tests/run/i5188a/Macro_1.scala create mode 100644 tests/run/i5188a/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index a566f90cf38d..7900810e0185 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -318,7 +318,10 @@ object Splicer { case Inlined(EmptyTree, Nil, expansion) => interpretTree(expansion) - case Typed(SeqLiteral(elems, _), _) => + case Typed(expr, _) => + interpretTree(expr) + + case SeqLiteral(elems, _) => interpretVarargs(elems.map(e => interpretTree(e))) case _ => diff --git a/compiler/test/dotc/run-test-pickling.blacklist b/compiler/test/dotc/run-test-pickling.blacklist index 432d926ec813..a325fa8a995d 100644 --- a/compiler/test/dotc/run-test-pickling.blacklist +++ b/compiler/test/dotc/run-test-pickling.blacklist @@ -22,6 +22,7 @@ i4803f i4947b i5119 i5119b +i5188a inline-varargs-1 implicitShortcut inline-case-objects diff --git a/tests/run/i5188a.check b/tests/run/i5188a.check new file mode 100644 index 000000000000..d6d579b01993 --- /dev/null +++ b/tests/run/i5188a.check @@ -0,0 +1,4 @@ +0 +1 +3 +6 diff --git a/tests/run/i5188a/Macro_1.scala b/tests/run/i5188a/Macro_1.scala new file mode 100644 index 000000000000..77f6183df67c --- /dev/null +++ b/tests/run/i5188a/Macro_1.scala @@ -0,0 +1,6 @@ +import scala.quoted._ + +object Lib { + inline def sum(inline args: Int*): Int = ~impl(args: _*) + def impl(args: Int*): Expr[Int] = args.sum.toExpr +} diff --git a/tests/run/i5188a/Test_2.scala b/tests/run/i5188a/Test_2.scala new file mode 100644 index 000000000000..189edde7e212 --- /dev/null +++ b/tests/run/i5188a/Test_2.scala @@ -0,0 +1,9 @@ + +object Test { + def main(args: Array[String]): Unit = { + println(Lib.sum()) + println(Lib.sum(1)) + println(Lib.sum(1, 2)) + println(Lib.sum(1, 2, 3)) + } +}