From 8b8b7a0eb45156a41e9eb4560227e2d9a45ee82b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 1 Feb 2022 17:50:48 +0100 Subject: [PATCH 1/3] Infer parameters of eta applications with vararg parameters Fixes #14367 --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 11 +++++++---- tests/neg/i14367.check | 7 +++++++ tests/neg/i14367.scala | 5 +++++ tests/pos/i14367.scala | 7 +++++++ 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 tests/neg/i14367.check create mode 100644 tests/neg/i14367.scala create mode 100644 tests/pos/i14367.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 02f3f6b4f164..f16af293fe83 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1227,8 +1227,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case mtpe: MethodType => val pos = paramIndex(param.name) if pos < mtpe.paramInfos.length then - val ptype = mtpe.paramInfos(pos) - if ptype.isRepeatedParam then NoType else ptype + mtpe.paramInfos(pos) + // This works only if vararg annotations match up. + // See neg/i14367.scala for an example where the inferred type is mispredicated. + // Nevertheless, the alternative would be to give up completely, so this is + // defensible. else NoType case _ => NoType if target.exists then formal <:< target @@ -1317,10 +1320,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer */ var fnBody = tree.body - def refersTo(arg: untpd.Tree, param: untpd.ValDef): Boolean = arg match { + def refersTo(arg: untpd.Tree, param: untpd.ValDef): Boolean = arg match case Ident(name) => name == param.name + case Typed(arg1, _) if untpd.isWildcardStarArg(arg) => refersTo(arg1, param) case _ => false - } /** If parameter `param` appears exactly once as an argument in `args`, * the singleton list consisting of its position in `args`, otherwise `Nil`. diff --git a/tests/neg/i14367.check b/tests/neg/i14367.check new file mode 100644 index 000000000000..92d974db120f --- /dev/null +++ b/tests/neg/i14367.check @@ -0,0 +1,7 @@ +-- [E007] Type Mismatch Error: tests/neg/i14367.scala:2:16 ------------------------------------------------------------- +2 |val h2 = i => p(i) // error: Found (i : Seq[Int]), Required: Int + | ^ + | Found: (i : Seq[Int]) + | Required: Int + +longer explanation available when compiling with `-explain` diff --git a/tests/neg/i14367.scala b/tests/neg/i14367.scala new file mode 100644 index 000000000000..2778ade8dfa1 --- /dev/null +++ b/tests/neg/i14367.scala @@ -0,0 +1,5 @@ +def p(i: Int*) = i.sum +val h2 = i => p(i) // error: Found (i : Seq[Int]), Required: Int + // It would be more logical to fail with a "missing parameter type", however. + + diff --git a/tests/pos/i14367.scala b/tests/pos/i14367.scala new file mode 100644 index 000000000000..d74f0aa8373e --- /dev/null +++ b/tests/pos/i14367.scala @@ -0,0 +1,7 @@ +def m(i: Int*) = i.sum +val f1 = m +val f2 = i => m(i*) + +def n(i: Seq[Int]) = i.sum +val g1 = n +val g2 = i => n(i) From 66a5c68c68ee8a9f69c08309fc1411db6b5e1e5d Mon Sep 17 00:00:00 2001 From: odersky Date: Tue, 1 Feb 2022 17:53:35 +0100 Subject: [PATCH 2/3] Update compiler/src/dotty/tools/dotc/typer/Typer.scala --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index f16af293fe83..09acde2ac845 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1229,7 +1229,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if pos < mtpe.paramInfos.length then mtpe.paramInfos(pos) // This works only if vararg annotations match up. - // See neg/i14367.scala for an example where the inferred type is mispredicated. + // See neg/i14367.scala for an example where the inferred type is mispredicted. // Nevertheless, the alternative would be to give up completely, so this is // defensible. else NoType From a696dd26d1371f28b72040a5f12bd8fe3926bfb3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 1 Feb 2022 22:19:04 +0100 Subject: [PATCH 3/3] Drop invalid test --- compiler/test-resources/repl/errorThenValid | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 compiler/test-resources/repl/errorThenValid diff --git a/compiler/test-resources/repl/errorThenValid b/compiler/test-resources/repl/errorThenValid deleted file mode 100644 index bfe97c5a7400..000000000000 --- a/compiler/test-resources/repl/errorThenValid +++ /dev/null @@ -1,10 +0,0 @@ -scala> val xs = scala.collection.mutable.ListBuffer[Int] --- [E081] Type Error: ---------------------------------------------------------- -1 | val xs = scala.collection.mutable.ListBuffer[Int] - | ^ - | Missing parameter type - | - | I could not infer the type of the parameter elems. -1 error found -scala> val xs = scala.collection.mutable.ListBuffer[Int]() -val xs: scala.collection.mutable.ListBuffer[Int] = ListBuffer()