bug icon indicating copy to clipboard operation
bug copied to clipboard

Spurious illegal premature access to the unconstructed `this` error when using local methods inside a by-name closure in super-class constructor parameter

Open neko-kai opened this issue 5 years ago • 1 comments

reproduction steps

Minimized example:

package example

import scala.util.Try

class X(a: Any)

final class XImpl
  extends X({
    def res = Try(helper())

    def helper() = ()

    res
  })

problem

The above fails to compile with an error:

Error:(10, 19) Implementation restriction: access of method helper$1 from <$anon: Function0>, would require illegal premature access to the unconstructed `this` of class XImpl in package example
    def res = Try(helper())

However, the error can be worked around by enclosing the block in a redundant function with ().pipe { _ => ... }, in which case it will compile and work as expected at runtime:

package example

import scala.util.Try
import scala.util.chaining._

class X(a: Any)

final class XImpl
  extends X(().pipe { _ =>
    def res = Try(helper())

    def helper() = ()

    res
  })

Which shows that the code doesn't actually trigger an implementation restriction.

expectation

Expected it to compile. This bug affects classes that pass an effect value or a block of code to the superconstructor such as this. dotty is not affected.

neko-kai avatar Apr 30 '20 17:04 neko-kai

Note: the above can also be worked around by making X's parameter by-name. However, there's another version of the bug that can't be worked around like that:

package example

class X(a: => Any)

class XImpl(
  param: Int
) extends X({
    def helper(): AutoCloseable = new AutoCloseable {
      def close() = println(param)
    }
    helper()
  })

Despite a: => Any this still does not compile:

Error:(9, 29) Implementation restriction: access of value param$1 from <$anon: AutoCloseable>, would require illegal premature access to the unconstructed `this` of <$anon: Function0>
      def close() = println(param)

But a pipe still works around it.

Dotty release was affected by the above bug, but it's fixed on master - https://github.com/lampepfl/dotty/issues/8846

neko-kai avatar Apr 30 '20 19:04 neko-kai