Skip to content

Right associative byname arguments not as byname as they could be #10693

Open
scala/scala
#7741
@milessabin

Description

@milessabin

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions