scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

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

Open scabug opened 11 years ago

scabug commented 11 years ago

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 commented 11 years ago

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

scabug commented 11 years ago

@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 commented 11 years ago

@retronym said:

testing: [...]/files/run/Meter.scala                                  [FAILED]
testing: [...]/files/run/MeterCaseClass.scala                         [FAILED]
...
scabug commented 11 years ago

@retronym said: Those failures some from the difference between

scala> 1d.hashCode
res0: Int = 1072693248

scala> 1d.##
res1: Int = 1
scabug commented 11 years ago

@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 commented 11 years ago

@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 commented 10 years ago

@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 commented 8 years ago

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

scabug commented 8 years ago

@dwijnand said: Sure.

scabug commented 7 years ago

@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 commented 4 years ago

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