From bc4468cdd266fc12fe164c1b6ec4da94b71a4129 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 9 Oct 2011 19:24:48 +0000 Subject: Flipped varargs eta-expansion behavior. (T*)U now eta-expands to Seq[T] => U, not T* => U. There is a transition command line switch to get the old behavior for any who may have relied upon it: -Yeta-expand-keeps-star Closes SI-4176, no review. --- src/compiler/scala/reflect/internal/Types.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 6 ++++++ src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 1 + test/files/neg/eta-expand-star.check | 4 ++++ test/files/neg/eta-expand-star.scala | 8 ++++++++ test/files/run/byname.scala | 6 +++--- test/files/run/eta-expand-star.check | 1 + test/files/run/eta-expand-star.scala | 8 ++++++++ test/files/run/eta-expand-star2.check | 1 + test/files/run/eta-expand-star2.flags | 1 + test/files/run/eta-expand-star2.scala | 8 ++++++++ 11 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 test/files/neg/eta-expand-star.check create mode 100644 test/files/neg/eta-expand-star.scala create mode 100644 test/files/run/eta-expand-star.check create mode 100644 test/files/run/eta-expand-star.scala create mode 100644 test/files/run/eta-expand-star2.check create mode 100644 test/files/run/eta-expand-star2.flags create mode 100644 test/files/run/eta-expand-star2.scala diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index c313f079ae..1e0a265f4b 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -3092,7 +3092,7 @@ A type's typeSymbol should never be inspected directly. // Or false for Seq[A] => Seq[A] // (It will rewrite A* everywhere but method parameters.) // This is the specified behavior. - private final val etaExpandKeepsStar = true + protected def etaExpandKeepsStar = false object dropRepeatedParamType extends TypeMap { def apply(tp: Type): Type = tp match { diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 604379d33f..e166b42436 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -300,6 +300,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def lubDebug = (sys.props contains "scalac.debug.lub") } + // The current division between scala.reflect.* and scala.tools.nsc.* is pretty + // clunky. It is often difficult to have a setting influence something without having + // to create it on that side. For this one my strategy is a constant def at the file + // where I need it, and then an override in Global with the setting. + override protected val etaExpandKeepsStar = settings.etaExpandKeepsStar.value + // True if -Xscript has been set, indicating a script run. def isScriptRun = opt.script.isDefined diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 10ba5b200a..5cf5767257 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -168,6 +168,7 @@ trait ScalaSettings extends AbsScalaSettings val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.") val YdepMethTpes = BooleanSetting ("-Ydependent-method-types", "Allow dependent method types.") val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") + val etaExpandKeepsStar = BooleanSetting("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") diff --git a/test/files/neg/eta-expand-star.check b/test/files/neg/eta-expand-star.check new file mode 100644 index 0000000000..6765d504fc --- /dev/null +++ b/test/files/neg/eta-expand-star.check @@ -0,0 +1,4 @@ +eta-expand-star.scala:6: error: too many arguments for method apply: (v1: Seq[T])Unit in trait Function1 + g(1, 2) + ^ +one error found diff --git a/test/files/neg/eta-expand-star.scala b/test/files/neg/eta-expand-star.scala new file mode 100644 index 0000000000..5749692522 --- /dev/null +++ b/test/files/neg/eta-expand-star.scala @@ -0,0 +1,8 @@ +object Test { + def f[T](xs: T*): Unit = () + def g[T] = f[T] _ + + def main(args: Array[String]): Unit = { + g(1, 2) + } +} diff --git a/test/files/run/byname.scala b/test/files/run/byname.scala index 8aff1ec23f..1325552348 100644 --- a/test/files/run/byname.scala +++ b/test/files/run/byname.scala @@ -36,13 +36,13 @@ def testVarargs(x: Int*) = x.reduceLeft((x: Int, y: Int) => x + y) test("varargs", 4, testVarargs(1, 2, 1)) val testVarargsR = testVarargs _ -test("varargs r", 4, testVarargsR(1, 2, 1)) +test("varargs r", 4, testVarargsR(Seq(1, 2, 1))) def testAll(x: Int, y: => Int, z: Int*) = x + y + z.size test("all", 5, testAll(1, 2, 22, 23)) val testAllR = testAll _ -test("all r", 7, testAllR(2, 3, 34, 35)) +test("all r", 7, testAllR(2, 3, Seq(34, 35))) val testAllS: (Int, =>Int, Int*) => Int = testAll _ test("all s", 8, testAllS(1, 5, 78, 89)) @@ -73,7 +73,7 @@ def testCVV(a: Int*)(z: String, b: Int*) = a.size + b.size test("cvv", 3, testCVV(1, 2)("", 8)) val testCVVR = testCVV _ -test("cvv r", 3, testCVVR(1)("", 8, 9)) +test("cvv r", 3, testCVVR(Seq(1))("", Seq(8, 9))) val testCVVRS: (String, Int*) => Int = testCVV(2, 3) test("cvv rs", 4, testCVVRS("", 5, 6)) diff --git a/test/files/run/eta-expand-star.check b/test/files/run/eta-expand-star.check new file mode 100644 index 0000000000..ce01362503 --- /dev/null +++ b/test/files/run/eta-expand-star.check @@ -0,0 +1 @@ +hello diff --git a/test/files/run/eta-expand-star.scala b/test/files/run/eta-expand-star.scala new file mode 100644 index 0000000000..7717c4bc91 --- /dev/null +++ b/test/files/run/eta-expand-star.scala @@ -0,0 +1,8 @@ +object Test { + def f[T](xs: T*): T = xs.head + def g[T] = f[T] _ + + def main(args: Array[String]): Unit = { + println(g("hello" +: args)) + } +} diff --git a/test/files/run/eta-expand-star2.check b/test/files/run/eta-expand-star2.check new file mode 100644 index 0000000000..ce01362503 --- /dev/null +++ b/test/files/run/eta-expand-star2.check @@ -0,0 +1 @@ +hello diff --git a/test/files/run/eta-expand-star2.flags b/test/files/run/eta-expand-star2.flags new file mode 100644 index 0000000000..0402fe55a4 --- /dev/null +++ b/test/files/run/eta-expand-star2.flags @@ -0,0 +1 @@ +-Yeta-expand-keeps-star \ No newline at end of file diff --git a/test/files/run/eta-expand-star2.scala b/test/files/run/eta-expand-star2.scala new file mode 100644 index 0000000000..eb650788d0 --- /dev/null +++ b/test/files/run/eta-expand-star2.scala @@ -0,0 +1,8 @@ +object Test { + def f[T](xs: T*): T = xs.head + def g[T] = f[T] _ + + def main(args: Array[String]): Unit = { + println(g("hello")) + } +} -- cgit v1.2.3