What on Earth is going on here?

42 views
Skip to first unread message

Paul Butcher

unread,
May 19, 2012, 4:04:22 PM5/19/12
to scalate...@googlegroups.com
With Scala 2.10.0-M3 and ScalaTest 1.8-SNAPSHOT:

Welcome to Scala version 2.10.0-M3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_31). Type in expressions to have them evaluated.
Type :help for more information.

scala> def foo[R] = null.asInstanceOf[R] foo: [R]=> R

scala> foo[String] res0: String = null

scala> foo[Int] res1: Int = 0

scala> import org.scalatest.Suite import org.scalatest.Suite

scala> class BugSuite extends Suite { def test1 = expect(0) { foo[Int] }; def test2 = { val x = foo[Int]; expect(0) { x } } } defined class BugSuite

scala> (new BugSuite).execute()

BugSuite:

- test1 *** FAILED ***
Expected 0, but got null (<console>:9)

- test2 


Why does test1 fail? And why does introducing the temporary variable in test2 make it pass?

--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Paul Butcher

unread,
May 19, 2012, 4:23:20 PM5/19/12
to scalate...@googlegroups.com
Hmm - let's try that again, with slightly less screwed up formatting this time, I hope:

Welcome to Scala version 2.10.0-M3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_31).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def foo[R] = null.asInstanceOf[R]
foo: [R]=> R

scala> foo[String]
res0: String = null

scala> foo[Int]
res1: Int = 0

scala> import org.scalatest.Suite
import org.scalatest.Suite

scala> class BugSuite extends Suite { def test1 = expect(0) { foo[Int] }; def test2 = { val x = foo[Int]; expect(0) { x } } }
defined class BugSuite

scala> (new BugSuite).execute()
BugSuite:
- test1 *** FAILED ***
  Expected 0, but got null (<console>:9)
- test2
 
--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Vlad Patryshev

unread,
May 20, 2012, 2:33:04 AM5/20/12
to scalate...@googlegroups.com
Safe unboxing of Int to default value?

Thanks,
-Vlad


On Sat, May 19, 2012 at 1:23 PM, Paul Butcher <pa...@paulbutcher.com> wrote:
Hmm - let's try that again, with slightly less screwed up formatting this time, I hopev
--
You received this message because you are subscribed to the Google
Groups "scalatest-users" group.
To post to this group, send email to scalate...@googlegroups.com
To unsubscribe from this group, send email to
scalatest-use...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/scalatest-users?hl=en
ScalaTest itself, and documentation, is available here:
http://www.artima.com/scalatest

Paul Butcher

unread,
May 20, 2012, 4:26:13 AM5/20/12
to scalate...@googlegroups.com
I'm sorry Vlad - what is "safe unboxing"? And are you suggesting that it's the cause of the problem, or a potential cure?

--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Bill Venners

unread,
May 20, 2012, 10:50:58 AM5/20/12
to scalate...@googlegroups.com
Hi Paul,

Sorry for the delay in responding. Was flying yesterday and too bushed
once I got in to investigate. I will guess that this is a corner case
of casting behavior in Scala. It smells like it could be a Scala
compiler bug but I'm not sure. It might just be trying to delay the
possibly unintended behavior of changing a null into a 0. What seems
to happen is that if an Int is needed, the null does get transformed
to a zero by the process. That's shown in these two cases:

scala> def foo[R] = null.asInstanceOf[R]
foo: [R]=> R

scala> foo[String]
res0: String = null

scala> foo[Int]
res1: Int = 0

scala> val x = foo[Int]
x: Int = 0

scala> val y: Int = foo[Int]
y: Int = 0

I'm guessing that's behaving as specified, because the other possible
behavior is a NullPointerException, which was a problem with Java's
autoboxing. That does make sense, but frankly magically transforming a
null to an 0 might also cause bugs.

ScalaTest's except's second param is an Any, and that's where you were
seeing the persistent null, so I tried this:

scala> val z: Any = foo[Int]
z: Any = null

Same behavior you saw with except. If it doesn't need an Int yet, then
it stays null. You might want to ask the scala-internals list if this
is specified behavior. It might be, but worth asking.

Bill
Bill Venners
Artima, Inc.
http://www.artima.com

Vlad Patryshev

unread,
May 20, 2012, 11:59:10 AM5/20/12
to scalate...@googlegroups.com
Paul,

I believe Bill has explained it in details below.

Thanks,
-Vlad

Paul Butcher

unread,
May 20, 2012, 5:57:25 PM5/20/12
to scalate...@googlegroups.com
This turns out to be a particularly wormy can:


--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Reply all
Reply to author
Forward
0 new messages