Skip to content

Inline and beta reduction can generate incorrect Inlined trees #16374

Closed
@nicolasstucki

Description

@nicolasstucki

Compiler version

3.2.1

Minimized code

Compiling with -Ycheck:all

def method(using String): String = ???

inline def inlineMethod(inline op: String => Unit)(using String): Unit =
  println(op(method))

def test(using String) =
  inlineMethod(c => ())

Output

*** error while checking test.scala after phase inlining ***
java.util.NoSuchElementException: head of empty list while running Ycheck on tests.scala
exception occurred while compiling tests.scala
java.util.NoSuchElementException: head of empty list while compiling tests.scala
Exception in thread "main" java.util.NoSuchElementException: head of empty list
        at scala.collection.immutable.Nil$.head(List.scala:662)
        at scala.collection.immutable.Nil$.head(List.scala:661)
        at dotty.tools.dotc.transform.YCheckPositions$$anon$1.traverse(YCheckPositions.scala:45)
        ...

The tree is

def test(using x$1: String): Unit =
      {{ /* inlined from 
        inlineMethod(
          {
            def $anonfun(c: String): Unit = ()
            closure($anonfun)
          }
        )(x$1)
       */
        println(
          {{ /* inlined from outside */
            {
              val c$proxy1: String = method({{ /* inlined from outside */x$1}})
              ()
            }
          }}
        ):Unit
      }}

It seems we are adding an Inlined with no call when beta-reducing the lambda.

Expectation

It should work. Beta reduction should not add this additional Inlined node, or it should balance it. Maybe the proxy should be in the Inlined bindings.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions