Description
In 2.12, method value syntax cannot be used to assign a SAM convertible, zero-parameter method to a SAM type (NotOkay
in code sample below). SAM conversion does not seem to occur yet implicit views are not utilized unless SAM conversion is explicitly suppressed (Ok2
below).
Based on the behavior of one-parameter (Ok1
) and parameterless (Ok3
) methods, it would seem that the correct behavior would be for SAM conversion to occur.
class Ok1 {
trait Sam1 { def apply(x: Any): Unit }
def render(x: Any) = {}
val handler: Sam1 = render _ // sam conversion happens here
}
class Ok2 {
implicit def conv(x: Function0[Unit]): Runnable = () => x()
def render() = {}
val handler: Runnable = (render _): Function0[Unit] // suppress sam conversion by typing the method value `render _` as a function-type, which will then expand to `() => render()` via eta-expansion, which will ultimately be converted via the implicit view `conv` to the expected type `Runnable`
}
class Ok3 {
def render = {}
val handler: Runnable = render _ // sam conversion happens here
}
class NotOkay1 {
implicit def conv(x: Function0[Unit]): Runnable = () => x()
def render() = {}
val handler: Runnable = render _ // Fails, neither sam conversion or implicit view is applied
}
In 2.11, method value syntax worked fine for assigning zero-parameter methods to SAM convertible types when an implicit view was present.
Some initial discussion with Adriaan regarding if this is intentional scala/scala#4822 (comment) (tl;dr: behavior is iffy, probably should do sam conversion, file ticket here)
Motivating case: the impact on js.Function0
found when trying to upgrade the Hands-on Scala.js tutorial to 2.12. scala-js/scala-js#2656