bug
bug copied to clipboard
`StringBuilder` change in 2.13.9 (`append` returning `this.type`) exposes poor interaction between eta-expansion and overloading
Reproduction steps
Scala version: 2.13.9
Welcome to Scala 2.13.9 (OpenJDK 64-Bit Server VM, Java 1.8.0_322).
Type in expressions for evaluation. Or try :help.
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class TestObj(testValue: Option[String] = None)
def appendToBuilder(obj: TestObj, builder: StringBuilder): Unit = {
obj.testValue.foreach(builder.append)
}
// Exiting paste mode, now interpreting.
obj.testValue.foreach(builder.append)
^
<pastie>:3: error: type mismatch;
found : (x: Char): builder.type <and> (x: Double): builder.type <and> (x: Float): builder.type <and> (x: Long): builder.type <and> (x: Int): builder.type <and> (x: Short): builder.type <and> (x: Byte): builder.type <and> (x: Boolean): builder.type <and> (s: StringBuilder): builder.type <and> (cs: CharSequence): builder.type <and> (s: String): builder.type <and> (x: Any): builder.type (with underlying type (x: Char): builder.type <and> (x: Double): builder.type <and> (x: Float): builder.type <and> (x: Long): builder.type <and> (x: Int): builder.type <and> (x: Short): builder.type <and> (x: Byte): builder.type <and> (x: Boolean): builder.type <and> (s: StringBuilder): builder.type <and> (cs: CharSequence): builder.type <and> (s: String): builder.type <and> (x: Any): builder.type)
required: String => ?
This code can be compiled with Scala 2.13.8
Welcome to Scala 2.13.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_322).
Type in expressions for evaluation. Or try :help.
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class TestObj(testValue: Option[String] = None)
def appendToBuilder(obj: TestObj, builder: StringBuilder): Unit = {
obj.testValue.foreach(builder.append)
}
// Exiting paste mode, now interpreting.
class TestObj
def appendToBuilder(obj: TestObj, builder: StringBuilder): Unit
Problem
The same code can be compiled with 2.13.8, but fails with 2.13.9
cc @SethTisue
This is likely related to https://github.com/scala/scala/commit/35c99eac200cc579f56376a5e8b25fdb1813e8cc, but there's an existing underlying problem:
trait A {
def foo(s: String): this.type
def foo(s: Int): this.type
}
trait T {
val a1: A
val o: Option[String]
def t(a2: A): Unit = {
o.foreach(a1.foo) // ok
o.foreach(a2.foo) // type mismatch
}
}
removing the overload gives a hint (i assume):
trait A {
def foo(s: String): this.type
}
trait T {
val a1: A
val o: Option[String]
def t(a2: A): Unit = {
o.foreach(a1.foo) // ok
o.foreach(a2.foo) // error
}
}
results in
Test.scala:10: error: method with dependent type (s: String): a2.type cannot be converted to function value
o.foreach(a2.foo)
^
1 error
Note that the workaround is to write a lambda instead of relying on eta expansion:
obj.testValue.foreach(builder.append(_))
Tentatively milestoned this for 2.13.10 since maybe we could at least improve the error message?