Skip to content

Inline implicit methods with lambdas cause AssertionError across files #5793

Closed
@guyde2011

Description

@guyde2011

If you use in implicit inline method for instance generation, and you return an anonymous instance, which has a lambda in one of its methods implementation, then an assertion error is thrown.

Example:

Exec.scala

object exec{
  trait Runner[T]{
    def run(t: T): Unit
  }
  object Runner{
    def run[T: Runner](t: T): Unit = implicitly[Runner[T]].run(t) 
    implicit inline def runImplicitly[T]: Runner[T] = new {
      def run(t: T) = List(()).map(x => x).head // <<<
    }
  }  
}

Main.scala

object Main{
  def main(args: Array[String]): Unit = {
    import exec._
    Runner.run(Some(5))
  }
}

And it crashes with:

[error] Total time: 1 s, completed 15:17:31 25/01/2019
java.lang.AssertionError: assertion failed: private method $anonfun in object Main in C:\vscode\dotty\crash\main\src\main\scala\Main.scala accessed from method run in C:\vscode\dotty\crash\main\src\main\scala\Exec.scala while compiling C:\vscode\dotty\crash\main\src\main\scala\Exec.scala, C:\vscode\dotty\crash\main\src\main\scala\Main.scala

If we were to change

  object Runner{
    def run[T: Runner](t: T): Unit = implicitly[Runner[T]].run(t) 
    implicit inline def runImplicitly[T]: Runner[T] = new {
      def run(t: T) = List(()).map(x => x).head // <<<
    }
  }  

to

  object Runner{
    val mapping = (x: Unit) => x
    def run[T: Runner](t: T): Unit = implicitly[Runner[T]].run(t) 
    implicit inline def runImplicitly[T]: Runner[T] = new {
      def run(t: T) = List(()).map(mapping).head // <<<
    }
  }  

It works.

It works as well if we move the two sources to the same file.

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