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

asInstanceOf doesn't issue due erasure warning #1558

Closed
scabug opened this issue Dec 2, 2008 · 6 comments
Closed

asInstanceOf doesn't issue due erasure warning #1558

scabug opened this issue Dec 2, 2008 · 6 comments
Assignees

Comments

@scabug
Copy link

scabug commented Dec 2, 2008

Consider this code:

import scala.collection.mutable.HashSet

class A
class B

object Up extends Application {
  val l:HashSet[A]=new HashSet[A]
  l+=new A
  val l2=l.asInstanceOf[HashSet[B]]
//  val b=l.isInstanceOf[HashSet[B]]

  for (x <- l2) println(x)
}

In this example, isInstanceOf would warn that B is eliminated by erasure, but surprisingly asInstanceOf issues no warning at at all (even though extracting an element from the converted HashSet results, of course, in a ClassCastException).

@scabug
Copy link
Author

scabug commented Dec 2, 2008

Imported From: https://issues.scala-lang.org/browse/SI-1558?orig=1
Reporter: @cunei

@scabug
Copy link
Author

scabug commented Feb 8, 2009

@paulp said:
Can you elaborate on why you would expect a warning here? isInstanceOf issues warnings about erasure because you're asking the type system for information it may not have. There's no symmetry with asInstanceOf, where you are telling the type system rather than asking.

You get a ClassCastException in this example because you casted it to something it isn't. I think a more applicable example is:

class A
class B extends A

object Up extends Application {
  val l:HashSet[A]=new HashSet[A]
  l+=new B
  val l2=l.asInstanceOf[HashSet[B]]

  for (x <- l2) println(x)
}

This works fine, as expected, and would surely not benefit from a warning.

@scabug
Copy link
Author

scabug commented Feb 8, 2009

@cunei said:
The rationale for the ticket is that both asInstanceOf and isInstanceOf in the example are compiled to code that does not behave as non-erased code would. Specifically, the shown asInstanceOf performs a conversion that will not, due to erasure, issue a ClassCastException at the conversion point (as all other casts), but will rather perform a "silent" conversion which will result in type-unsafe operations at a later, non-obvious point in the code. Surely that warrants at least a warning.

@scabug
Copy link
Author

scabug commented Feb 8, 2009

@paulp said:
If that merits a warning, then wouldn't this also merit a warning for the identical reason (modulo the name of the runtime exception):

scala> val strs = Array("abc", "def")            
strs: Array[java.lang.String] = Array(abc, def)

scala> val arr = strs.asInstanceOf[Array[AnyRef]] // no warning
arr: Array[AnyRef] = Array(abc, def)

scala> strs(0) = new AnyRef                      
<console>:6: error: type mismatch;
 found   : java.lang.Object
 required: java.lang.String
       strs(0) = new AnyRef
                 ^

scala> arr(0) = new AnyRef                       
java.lang.ArrayStoreException: java.lang.Object

I'll defer to more sophisticated type system users than myself on this, but I have always been under the impression that asInstanceOf is how you say "I know what I'm doing, please Mr. Type System, just do it."

@scabug
Copy link
Author

scabug commented Jun 12, 2009

@odersky said:
Paul is right. asInstanceOf is indeed used as a ``I know what I'm dping' alternative to pattern matches. So we can't change that now.

@scabug
Copy link
Author

scabug commented Mar 28, 2010

@SethTisue said:
It seems to me that the spec requires an unchecked warning to be issued. SLS 12.1 defines asInstanceOf in terms of pattern matching, and SLS 8.2 says that "The Scala compiler will issue an “unchecked” warning for these patterns to flag the pos- sible loss of type-safety."

If we don't want a warning here, then it seems to me that a spec change is needed in order not to require one. see also #1447

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

2 participants