Skip to content

inferred type eludes variance check: unsoundness results #5060

@scabug

Description

@scabug

I thought I was going to fix this, but I started getting pretty far afield so I'll open it.

class A[+T] {
  val foo0 = {
    class AsVariantAsIWantToBe { def contains(x: T) = () }
    new AsVariantAsIWantToBe
  }
  def foo1 = {
    class VarianceIsTheSpiceOfTypes { def contains(x: T) = () }
    new VarianceIsTheSpiceOfTypes
  }
}

object Test {
  def main(args: Array[String]): Unit = {
    val xs: A[String] = new A[String]
    println(xs.foo0 contains "abc")
    println((xs: A[Any]).foo0 contains 5)
    // java.lang.NoSuchMethodException: A$AsVariantAsIWantToBe$1.contains(java.lang.String)
  }
}

My understand is as follows: the variance validator takes the position that you can use type parameters however you like if your owner is a term, like val foo0. Though you are prohibited from declaring foo0 to have the unsound type ("Parameter type in structural refinement may not refer to an abstract type defined outside that refinement"), scala is still willing to infer it. In this case, that it infers within A[T] that foo0 has type

ScalaObject{def contains(z0: T):Unit}

Since A is covariant in T, it's bedlam in soundness town.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions