scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Can't infer type of `Array.apply` when `ClassTag` and implicit conversion to `Seq` are both involved #12920

Open pengmaokui opened 6 months ago

pengmaokui commented 6 months ago

Reproduction steps

Scala version: (2.13.12)

  import reflect.ClassTag
  def main(args: Array[String]): Unit = {

    test(Array("jan", "feb", "mar", "april", "may", "jun"))
  }

  def test[T: ClassTag](seq: Seq[T]): Unit = {
    println(seq)
  }

Problem

Compile not pass

overloaded method apply with alternatives:
  (x: Unit,xs: Unit*)Array[Unit] <and>
  (x: Double,xs: Double*)Array[Double] <and>
  (x: Float,xs: Float*)Array[Float] <and>
  (x: Long,xs: Long*)Array[Long] <and>
  (x: Int,xs: Int*)Array[Int] <and>
  (x: Char,xs: Char*)Array[Char] <and>
  (x: Short,xs: Short*)Array[Short] <and>
  (x: Byte,xs: Byte*)Array[Byte] <and>
  (x: Boolean,xs: Boolean*)Array[Boolean]
 cannot be applied to (String, String, String, String, String, String)
    test(Array("jan", "feb", "mar", "april", "may", "jun"))
som-snytt commented 6 months ago

Scala 3 infers String, but the copying conversion is deprecated.

scala 2.13.12> test(Array[String]("jan", "feb", "mar", "april", "may", "jun")) // print

test[String](scala.Predef.copyArrayToImmutableIndexedSeq[String](scala.Array.apply[scala.Predef.String]("jan", "feb", "mar", "april", "may", "jun")(scala.reflect.`package`.materializeClassTag[String]()))) // : (implicit evidence$1: scala.reflect.ClassTag[String]): Unit

If you take the advice and use toIndexedSeq, it will also infer String:

scala 2.13.12> test(Array[String]("jan", "feb", "mar", "april", "may", "jun")) // print
                                 ^
               warning: method copyArrayToImmutableIndexedSeq in class LowPriorityImplicits2 is deprecated (since 2.13.0): implicit conversions from Array to immutable.IndexedSeq are implemented by copying; use `toIndexedSeq` explicitly if you want to copy, or use the more efficient non-copying ArraySeq.unsafeWrapArray
ArraySeq(jan, feb, mar, april, may, jun)

scala 2.13.12> test(Array[String]("jan", "feb", "mar", "april", "may", "jun").toIndexedSeq)
ArraySeq(jan, feb, mar, april, may, jun)

scala 2.13.12> test(Array("jan", "feb", "mar", "april", "may", "jun").toIndexedSeq)
ArraySeq(jan, feb, mar, april, may, jun)

Of the overloads of Array.apply, the primitive versions are more specific than the generic.

Maybe Scala 3 defers inferring the type until after it finds the conversion. (Just a guess.)