Consider the following code:
object Main {
implicit class BytesExt(private val _value: Array[Byte]) extends AnyVal {
def drop(when: Boolean): Array[Byte] = if (when) Array.empty else _value }
val a: Array[Byte] = Array(0)
val b = a.drop(1) }
This compiles fine under Scala 2.13.8 whereas it fails under Scala 3.1.1 with
[error] -- [E007] Type Mismatch Error: .../src/main/scala/Main.scala:7:17
[error] 7 | val b = a.drop(1) }
[error] | ^
[error] | Found: (1 : Int)
[error] | Required: Boolean
Is this the consequence of some changes in the implicit method resolution or is it a compiler bug?
Remarks:
-
changing to the new syntax with
extension
makes no difference.
-
adding the option “-source:3.0-migration” makes the behaviour equal to Scala 2 again.
1 Like
Note that the code compiles if you move BytesExt
outside of Main
. So it looks like point 2 on Changes in Implicit Resolution to me:
Nesting is now taken into account for selecting an implicit […]
1 Like
Do you mean like this?
implicit class BytesExt(private val _value: Array[Byte]) extends AnyVal {
def drop(when: Boolean): Array[Byte] = if (when) Array.empty else _value }
object Main {
val a: Array[Byte] = Array(0)
val b = a.drop(1) }
I still get the error though. Besides that, in Scala2 there also was no ambiguity error, which the explanation you refer to suggests. But, maybe it is still related though.
Here’s a Scala 3.1.1 REPL session showing it compiling:
scala> implicit class BytesExt(private val _value: Array[Byte]) extends AnyVal {
| def drop(when: Boolean): Array[Byte] = if (when) Array.empty else _value }
// defined class BytesExt
def BytesExt(_value: Array[Byte]): BytesExt
scala> object Main {
| val a: Array[Byte] = Array(0)
| val b = a.drop(1) }
// defined object Main
I don’t know (without digging, anyway) why the result is different than in your Scastie.
I confirm that the REPL works, but compiling with SBT 1.6.2 and this build.sbt
:
scalaVersion := "3.1.1"
scalacOptions ++= Seq("-feature","-deprecation","-unchecked")
gives the same error. (scalacOptions
may also be omitted). So the REPL may somehow overcome this, but it does not seem to be Scastie problem. So the question remains, i guess. Is this expected behaviour or a compiler bug?