scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.81k stars 1.05k forks source link

Too eager to remove wildcard types #14152

Closed Atry closed 2 years ago

Atry commented 2 years ago

Compiler version

3.1.0

Minimized code

val aa1 = {
  object O1 extends AnyRef
  Array(Array(O1))
}

val aa2: Array[_ <: Array[_ <: AnyRef]] = aa1

https://scastie.scala-lang.org/8WGftp2KTAmmjTZdIqZduw

Output

Found:    Array[?1.CAP]
Required: Array[? <: Array[? <: AnyRef]]

where:    ?1 is an unknown value of type scala.runtime.TypeBox[Nothing, Any]

Expectation

It should compile.

Note that the same code compiles in Scala 2 with warnings https://scastie.scala-lang.org/QDjOfT5RTleWMtlhRot12A

inferred existential type Array[Array[O1.type]] forSome { val O1: AnyRef }, which cannot be expressed by wildcards, should be enabled
by making the implicit value scala.language.existentials visible.
----
This can be achieved by adding the import clause 'import scala.language.existentials'
or by setting the compiler option -language:existentials.
See the Scaladoc for value scala.language.existentials for a discussion
why the feature should be explicitly enabled.

Workaround

The following code compiles:

val aa1: Array[_ <: Array[_ <: AnyRef]] = {
  object O1 extends AnyRef
  Array(Array(O1))
}
dwijnand commented 2 years ago

Now, as in using the HEAD of master, this causes a Cyclic Error:

-- [E045] Cyclic Error: tests/pos/i14152.scala:2:2 -----------------------------
2 |  object O1 extends AnyRef
  |  ^
  |  Recursive value aa1 needs type

longer explanation available when compiling with `-explain`
exception occurred while typechecking tests/pos/i14152.scala
exception occurred while compiling tests/pos/i14152.scala
java.lang.AssertionError: assertion failed: leak: O1 in {
  val O1: O1 = new O1()
  final module class O1() extends AnyRef() { this: O1.type =>}
  Array.apply[Array[O1.type]](
    [
      Array.apply[O1.type]([O1 : O1.type]*)(
        scala.reflect.ClassTag.apply[O1.type](classOf[O1])
      )
     : Array[O1.type]]*
  )(scala.reflect.ClassTag.apply[O1.type](classOf[O1]).wrap):
    Array[Array[O1.type]]
} while compiling tests/pos/i14152.scala
Exception in thread "main" java.lang.AssertionError: assertion failed: leak: O1 in {
  val O1: O1 = new O1()
  final module class O1() extends AnyRef() { this: O1.type =>}
  Array.apply[Array[O1.type]](
    [
      Array.apply[O1.type]([O1 : O1.type]*)(
        scala.reflect.ClassTag.apply[O1.type](classOf[O1])
      )
     : Array[O1.type]]*
  )(scala.reflect.ClassTag.apply[O1.type](classOf[O1]).wrap):
    Array[Array[O1.type]]
}