Skip to content

Unsoundness of variance checking with regard to constructors. #9549

@scabug

Description

@scabug

Consider:

    class C[+A] {

      private[this] var y: A = _
      def getY: A = y

      class Inner(x: A) {
        y = x
      }
    }

    object Test {

      def main(args: Array[String]) = {
        val x = new C[String]
        val y: C[Any] = x
        val i = new y.Inner(1)
        val s: String = x.getY
        println(s)
      }
    }

This demonstrates an unsoundness in the variance checking of scalac.
Scalac excludes symbols owned by constructors from the
checking. This is unsound, as can be demonstrated by compiling the test
and observing output of the program run:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at Test$.main(variances-constr.scala:17)
at Test.main(variances-constr.scala)

Dotty allows this code only under -language:Scala2 and issues a migration warning.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions