Skip to content
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

bogus "eliminated by erasure" warning #6791

Open
scabug opened this issue Dec 9, 2012 · 4 comments
Open

bogus "eliminated by erasure" warning #6791

scabug opened this issue Dec 9, 2012 · 4 comments

Comments

@scabug
Copy link

scabug commented Dec 9, 2012

This program should not warn about the abstract type being eliminated by erasure because we are testing for a more specific type than the one which is eliminated by erasure - it is a test which we can perform.

object Foo {
  def f[T <: AnyRef](x: Any, y: T) = x match {
    case _: y.type => true
  }
}
@scabug
Copy link
Author

scabug commented Dec 9, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6791?orig=1
Reporter: @paulp
Affected Versions: 2.10.0-RC5, 2.11.0
See #4577

@scabug
Copy link
Author

scabug commented Dec 10, 2013

Stephen Compall (s11001001) said (edited on Dec 10, 2013 4:36:13 AM UTC):
As it stands, I don't think this warning is bogus, because unsafeCoerce can be derived in a couple ways from testing singleton types by trusting equals:

package test.sixtysevenninetyone

object UCs {
  abstract class Ooh[+A] extends Tuple1[Unit](()) {
    val phantom: A
  }
  def ooh[A](a: => A): Ooh[A] = new Ooh[A]{lazy val phantom = a}

  def uc1[A, B]: A =:= B = {
    val aa = ooh(implicitly[A =:= A])
    val no = ooh(???)
    aa match {case ano: no.type => ano.phantom}
  }

  import collection.mutable.Buffer

  def uc2[A, B]: A =:= B = {
    val es = Buffer[A =:= B]()
    val gs = Buffer[A =:= A]()
    (gs: Buffer[_]) match {
      case es: es.type => gs += implicitly; es.head
    }
  }

  def oops = (uc1[String, ClassLoader]("twenty-one"),
              uc2[String, ClassLoader]("forty-two"))
}

Yielding session (excluding uninteresting warnings about subclassing tuple; the basic principle of getting equals to lie has wide application):

[warn] 6791.scala:12: non-variable type argument Nothing in type pattern test.sixtysevenninetyone.UCs.Ooh[Nothing] is unchecked since it is eliminated by erasure
[warn]     aa match {case ano: no.type => ano.phantom}
[warn]                           ^
[warn] 6791.scala:21: non-variable type argument =:=[A,B] in type pattern scala.collection.mutable.Buffer[=:=[A,B]] is unchecked since it is eliminated by erasure
[warn]       case es: es.type => gs += implicitly; es.head
[warn]                  ^
[warn] four warnings found
[info] Starting scala interpreter...
[info] 
Welcome to Scala version 2.11.0-M7 (OpenJDK 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> test.sixtysevenninetyone.UCs.oops
res0: (ClassLoader, ClassLoader) = (twenty-one,forty-two)

Also as in 2.10.3.

@scabug
Copy link
Author

scabug commented Dec 11, 2013

@paulp said:
It doesn't matter if equals lies, the pattern match in this ticket should never even call equals. The match is only supposed to happen if x is reference equal to y, which will make it difficult to introduce unsoundness based on the type of y.

There is definitely grave unsoundness related to trusting equals - #1503 is the main ticket - this is not that. See #4577, which I marked as a "blocker" at some point, ha ha.

@scabug
Copy link
Author

scabug commented May 16, 2014

@adriaanm said:
The pattern match does use eq in 2.11, but the warning machinery hasn't caught up yet.

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

No branches or pull requests

1 participant