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

2.9.0 regression: null interferes with irrefutability #4574

Closed
scabug opened this issue May 12, 2011 · 2 comments
Closed

2.9.0 regression: null interferes with irrefutability #4574

scabug opened this issue May 12, 2011 · 2 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented May 12, 2011

It was observed that a for comprehension and foreach showed different behavior when iterating over a sorted map. This led to the discover that the tuple pattern in

for ((x, y) <- map) println(x)

is not presently considered irrefutable, due to null. It was irrefutable in 2.8.1, but that was more out of the absence of implementation than out of intention.

// scala 2.8.1
scala> (null: Any) match { case List(_*) => true }
res4: Boolean = true

So the filter call being added in 2.9 (in addition to impacting performance and increasing bytecode size) loses the sortedness of the map.

Irrefutable specification says:

> > A pattern p is irrefutable for a type T , if one of the following applies:
> > 1. pisavariablepattern,
> > 2. pisatypedpatternx:T′,andT<:T′,
> > 3. pisaconstructorpatternc(p1,...,pn),thetypeTisaninstanceofclassc,the primary constructor (�5.3) of type T has argument types T1, ..., Tn, and each pi isirrefutableforTi.

I suggest it wouldn't hurt to explicitly account for null somewhere in the above lines. A typed pattern _: T' or a constructor pattern T(..) does not match null, but conditions 2 and 3 above quietly add in null. (I'm not suggesting changing the specified behavior -- in the absence of first class support for NotNull-ness, if null undid irrefutability there would be little left to be irrefutable.)

So I am proceeding under the belief that the 2.8.1 behavior shown below is what we want.

Scala 2.8.1:

scala> val xs: List[(Int, Int)] = List((2, 2), null)
xs: List[(Int, Int)] = List((2,2), null)

scala> for ((x, y) <- xs) yield x
scala.MatchError: null
	at $$anonfun$$1.apply(<console>:7)

Scala 2.9.0:

scala> val xs: List[(Int, Int)] = List((2, 2), null)
xs: List[(Int, Int)] = List((2,2), null)

scala> for ((x, y) <- xs) yield x
res0: List[Int] = List(2)
@scabug
Copy link
Author

scabug commented May 12, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4574?orig=1
Reporter: @paulp
Other Milestones: 2.10.0

@scabug
Copy link
Author

scabug commented Mar 20, 2012

@paulp said:
fb44bb28b8

@scabug scabug closed this as completed Mar 20, 2012
@scabug scabug added the patmat label Apr 7, 2017
@scabug scabug added this to the 2.10.0-M2 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants