Open
Description
Running this example,
import scala.language.implicitConversions
object Test extends App {
class Foo {
def andThen_:(b: => Bar) = { println("pre"); b ; println("post") }
}
class Bar
object Bar {
implicit def fromString(s: String): Bar = new Bar
}
def mkFoo: Foo = { println("foo") ; new Foo }
def mkBarString: String = { println("bar"); "Bar" }
mkBarString andThen_: mkFoo
println
mkFoo.andThen_:(mkBarString)
}
yields,
bar
foo
pre
post
foo
pre
bar
post
Compiling with -Xprint:typer
shows that mkBarString andThen_: mkFoo
has been rewritten to,
<synthetic> <artifact> val rassoc$1: String = Test.this.mkBarString;
Test.this.mkFoo.andThen_:(Test.this.Bar.fromString(rassoc$1))
ie. the synthetic rassoc$1
has been captured before the implicit conversion fromString
is applied, and consequently the later inlining is not applied and the rhs is evaluated too early because the converted byname method argument doesn't match the expected form.
Conversely mkFoo.andThen_:(mkBarString)
is rewritten to,
Test.this.mkFoo.andThen_:(Test.this.Bar.fromString(Test.this.mkBarString))
as expected, and the entire rhs is deferred and the synthetic val is inlined correctly.
/cc @szeiger