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

Behavior changes of intersect operations related to Array.empty[T] between 2.13.5 and 2.13.6 #12403

Closed
LuciferYang opened this issue May 25, 2021 · 4 comments · Fixed by scala/scala#9641

Comments

@LuciferYang
Copy link

reproduction steps

using Scala 2.13.6,

Welcome to Scala 2.13.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_232).
Type in expressions for evaluation. Or try :help.

scala> Array.empty[Double].intersect(Array(0.0))
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [D
  ... 32 elided

scala> Array(0.0).intersect(Array.empty[Double])
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [D
  ... 32 elided

scala> Array.empty[Double].intersect(Array.empty[Double])
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [D
  ... 32 elided

but using Scala 2.13.5

Welcome to Scala 2.13.5 (OpenJDK 64-Bit Server VM, Java 1.8.0_232).
Type in expressions for evaluation. Or try :help.

scala> Array.empty[Double].intersect(Array(0.0))
val res0: Array[Double] = Array()

scala> Array(0.0).intersect(Array.empty[Double])
val res1: Array[Double] = Array()

scala> Array.empty[Double].intersect(Array.empty[Double])
val res2: Array[Double] = Array()

problem

There are behavior changes of intersect operations related to Array.empty[T], return Array() is replaced by throw ClassCastException, Is this expected or a bug?

@LuciferYang
Copy link
Author

I try these operations with dotty, the behavior is same as Scala 2.13.5, All expressions return Array()

@som-snytt
Copy link

This is due to a recent change to pick empty on input.isEmpty. However, there was an ancient effort to reduce churn in empty arrays in ArraySeq.

Is it arguable that one ought never check the component type of an empty array? But I noticed a pattern match on array types, and some API take empty arrays for type info.

Alternatively, empty could keep a cache of useful empty arrays for wrapping. I did not explore that option, lest the horse get out of the barn, the genie out of the bottle, the worms out of the can.

@martijnhoekstra may not have an opinion.

@som-snytt
Copy link

For the record, dotty head is now on 2.13.6 library with same result. (To exclude bad ClassTag, etc.)

@dwijnand dwijnand added this to the 2.13.7 milestone May 25, 2021
@martijnhoekstra
Copy link

The failing cast happens here: https://github.com/scala/scala/blob/v2.13.6/src/library/scala/collection/ArrayOps.scala#L1583
it casts the underlying array of the ArraySeq, of which the documentation says here: https://github.com/scala/scala/blob/v2.13.6/src/library/scala/collection/mutable/ArraySeq.scala#L67

The underlying array. Its element type does not have to be equal to the element type of this ArraySeq. A primitive can be backed by an array of boxed values and a reference ArraySeq can be backed by an array of a supertype or subtype of the element type.

I failed at not having an opinion about casting that array, so you'll have to settle for me not sharing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants