scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.88k stars 1.06k forks source link

Issue with enqueuing an akka ByteString to an immutable Queue #17946

Open pjfanning opened 1 year ago

pjfanning commented 1 year ago

Compiler version

Scala 3.3.0

Minimized code

https://scastie.scala-lang.org/pjfanning/nrTQr59WTAy2uIMYUFtkTw/4

val byteString = akka.util.ByteString("abc")
var queue = scala.collection.immutable.Queue.empty[akka.util.ByteString]
queue = queue.enqueue(byteString)

This code works in Scala 2.13 but fails to compile in Scala 3.3.0.

A minimised example that reproduces this:

class MyByteString extends Iterable[Byte] {
  override def iterator: Iterator[Byte] = ???
}

val byteString = new MyByteString
var queue = scala.collection.immutable.Queue.empty[MyByteString]
queue = queue.enqueue(byteString)

Output

Compiler issue on the queue = queue.enqueue(byteString) call

Found:    akka.util.ByteString
Required: Iterable[akka.util.ByteString]

Expectation

This should compile.

I think Scala3 is confused by the fact that akka.util.ByteString extends Iterable[Byte] but the Queue is explicitly setup to be Queue[ByteString].

dwijnand commented 1 year ago

@odersky do you mind having a look? I'm surprised to see a case where Scala 2 seems to disambiguate overloads (enqueue is overloaded) better than Scala 3.

som-snytt commented 1 year ago

The unexpectedly unfortunate overload is deprecated:

def enqueue[B >: A](iter: scala.collection.Iterable[B])

so you get

enqueue[MyByteString | Byte]

The workaround is to be explicit

queue = queue.enqueue[MyByteString](byteString)
pjfanning commented 1 year ago

@som-snytt that workaround seems to work

It would be nice not to have to use the workaround but it's good that there is an easy one.