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

regression in result of null.## (when wrapped by a Value Class) #7396

Open
scabug opened this issue Apr 20, 2013 · 11 comments
Open

regression in result of null.## (when wrapped by a Value Class) #7396

scabug opened this issue Apr 20, 2013 · 11 comments

Comments

@scabug
Copy link

scabug commented Apr 20, 2013

As you can see in #4311, null.## is supposed to be 0 and not an NPE. And it is, right up until extension methods get involved.


scala> null.##
res0: Int = 0

scala> (null: Predef.Ensuring[_]).##
java.lang.NullPointerException
	at scala.Predef$Ensuring$.hashCode$extension(Predef.scala:236)
	at scala.Predef$Ensuring.hashCode(Predef.scala:236)
	at scala.runtime.ScalaRunTime$.hash(ScalaRunTime.scala:214)
	at .<init>(<console>:7)
	at .<clinit>(<console>)
	at .<init>(<console>:7)
	at .<clinit>(<console>)
	at $print(<console>)
@scabug
Copy link
Author

scabug commented Apr 20, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7396?orig=1
Reporter: @paulp
Affected Versions: 2.10.0
See #4311

@scabug
Copy link
Author

scabug commented Apr 21, 2013

@retronym said:
"It's harder to fix than it looks, unfortunately."

I'm running tests now, so perhaps the reasons will dawn on me soon, but I would have thought we could just call underlying.## from the synthetic value class hashCode and all would be peachy.

https://github.com/retronym/scala/compare/ticket/7396

scala> class Foo(val a: Any) extends AnyVal
defined class Foo

scala> implicit class Foo(val a: Any) extends AnyVal
defined class Foo

scala> (null: Foo).##
res0: Int = 0

@scabug
Copy link
Author

scabug commented Apr 21, 2013

@retronym said:

testing: [...]/files/run/Meter.scala                                  [FAILED]
testing: [...]/files/run/MeterCaseClass.scala                         [FAILED]
...

@scabug
Copy link
Author

scabug commented Apr 21, 2013

@retronym said:
Those failures some from the difference between

scala> 1d.hashCode
res0: Int = 1072693248

scala> 1d.##
res1: Int = 1

@scabug
Copy link
Author

scabug commented Apr 21, 2013

@paulp said:
"I would have thought we could just call underlying.## from the synthetic value class hashCode"

The problem is that it isn't correct. hashCode has different behavior than ##. As you discovered.

@scabug
Copy link
Author

scabug commented May 29, 2013

@retronym said (edited on May 29, 2013 12:46:47 PM UTC):
A variation reported on the mailing lists:

scala> class A(val a: Any) extends AnyVal
defined class A

scala> new Array[A](1).apply(0).hashCode
java.lang.NullPointerException
	at .<init>(<console>:10)
	at .<clinit>(<console>)
	at .$print$lzycompute(<console>:7)
	at .$print(<console>:6)

@scabug
Copy link
Author

scabug commented Jul 29, 2014

@lrytz said:
@retronym this last example seems unrelated to hashCode:

scala> class A(val a: Any) extends AnyVal
defined class A

scala> new Array[A](1).apply(0)
java.lang.NullPointerException

@scabug
Copy link
Author

scabug commented Jun 22, 2016

@adriaanm said:
@dwijnand, perhaps you'd like to take a look?

@scabug
Copy link
Author

scabug commented Jun 23, 2016

@dwijnand said:
Sure.

@scabug
Copy link
Author

scabug commented Oct 5, 2016

@dwijnand said:
Is the last expression here therefore equally wrong?

scala> 1d.hashCode
res0: Int = 1072693248

scala> 1d.##
res1: Int = 1

scala> class Foo(val x: Double) extends AnyVal
defined class Foo

scala> new Foo(1d).hashCode
res2: Int = 1072693248

scala> new Foo(1d).##
res3: Int = 1072693248

(Also, is it part of this ticket, or a separate issue?)

@Alexey-NM
Copy link

removed the critical label on 27 Jul 2017

Nevertheless this bug is completely breaking some methods in collection library.

class WString(val u: String) extends AnyVal
 val v1 = new WString(null)
 val v2 = new WString(null)
 val v3 = (v1::v2::Nil).distinct //throws NPE 

Is it part of this ticket, or a separate issue?

Is it possible to change SIP 15 specification something like:

def hashCode = if (u==null) 0 else u.hashCode

@scala scala deleted a comment from scabug Feb 17, 2020
@scala scala deleted a comment from scabug Feb 17, 2020
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

4 participants