New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsoundness in overriding methods with higher-order type parameters #2066

Closed
scabug opened this Issue Jun 17, 2009 · 9 comments

Comments

Projects
None yet
2 participants
@scabug
Copy link

scabug commented Jun 17, 2009

Try to compile the following code with Scala 2.7.5 final:

trait A {
 def f[T[_]](x : T[Int]) : T[Any]
}

class B extends A {
 def f[T[+_]](x : T[Int]) : T[Any] = x
}

class P[Y](var y : Y)

It is compiled without any errors. But then you can write:

val p = new P(1)
val palias = (new B():A).f[P](p)
palias.y = "hello"

Result:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

So, this way of overriding is unsound.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jun 17, 2009

Imported From: https://issues.scala-lang.org/browse/SI-2066?orig=1
Reporter: Vladimir Reshetnikov (nikov)
See #5517

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jun 19, 2009

Vladimir Reshetnikov (nikov) said:
Similar issue:

class C[T](var y : T)

object A {
val a : AnyRef { def f[T[_]](x : T[int]) : T[Any] } = A
def f[T[+_]](x : T[Int]) : T[Any] = x
}

Scala 2.8.0.r18050-b20090618020144 compiler compiles this without
errors. But it seems unsound, as we can write:

scala> val c = new C(1)
c: C[Int] = C@9e7d46

scala> val c1 = A.a.fC
c1: C[Any] = C@9e7d46

scala> c1.y = ""

scala> c.y
java.lang.ClassCastException: java.lang.String cannot be cast to
java.lang.Integer

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Mar 4, 2011

@soc said:
Behavior has changed, both examples compile in 2.9.0.r24324-b20110222020042 and don't throw at runtime.

Should the compiler reject those examples right at the beginning or can this considered to be fixed?

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Apr 7, 2011

@harrah said:
To the original example, add:

val z: Int = p.y

This will throw a !ClassCastException.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented May 7, 2012

@heathermiller said:
B.f should not be able to implement A.f because the type parameter of T is covariant in B but not in A. This seems like it shouldn't compile.

Added a test case for this one (pull request)

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Feb 3, 2013

@adriaanm said:
fixing this will break existing code -- the rule is only to do that in major versions,
so this will have to wait for 2.11

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Oct 15, 2013

@gkossakowski said:
Unassigning and rescheduling to M7 as previous deadline was missed.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 22, 2013

@retronym said:
Here's an patch that I'm cobbling together:

https://github.com/retronym/scala/compare/ticket;2066?expand=1

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 22, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment