Description
Starting with Scala 2.13 the default Seq
type is immutable.Seq
. This change apply to repeated arguments:
scala> def foo(x: Int*) = 1
foo: (x: Int*)Int
scala> foo(immutable.Seq(1, 2): _*)
res0: Int = 1
scala> foo(mutable.Seq(1, 2): _*)
^
error: type mismatch;
found : Seq[Int] (in scala.collection.mutable)
required: Seq[Int] (in scala.collection.immutable)
scala> foo(Array(1, 2): _*)
res2: Int = 1
However, it is still possible to pass an Array where repeated arguments are expected. This is a requirement for java interoperability.
In Dotty, given foo: _*
, foo
must be a subtype of Seq
. If foo
is an array, then an implicit conversion is applied (i.e. Predef.wrapXXXArray
). We don't need to special case arrays in typer but latter (in ElimRepeated) we have to revert the conversion if the array is used as a repeated arguments of a java defined method. E.g.
// xs: Array[String]
java.nio.file.Paths.get("foo", xs: _*)
// >>>>>> Typer
java.nio.file.Paths.get("foo", Predef.wrapRefArray(xs): String*)
// >>>>>> ElimRepeated
java.nio.file.Paths.get("foo", xs)
The current implicit conversions defined in Predef
returns a mutable.Seq
.
How do we solve this problem in the future when Dotty switch its default Seq
type to immutable.Seq
instead of collection.Seq
? Here are my thoughts, either:
- Introduce new implicit conversions in
DottyPredef
(orPredef
?) fromArray
toimmutable.Seq
. - Change typing rules for repeated arguments. In expression position:
foo <:< Array[A] or foo <:< immutable.Seq[A] --------------------------------------------- foo: _* ⊢ Repeated[A]
I think scalac
does 2). @adriaanm, any thoughts on this?