Search code examples
scalainlineextractor

Scala inline unapply extractor


The following code:

object Test {
  @inline def unapply(i: Int): Option[String] =
    i match {
      case 1 => Some("Got 1")
      case 2 => Some("Got 2")
      case 3 => throw new Exception("Should not test 3")
      case _ => None
  }
  def test(i: Int) = i match {
    case Test(k) => k
    case 4 => "Another 4"
    case _ => ""
  }
}
Test.test(3)

results in the following error:

...
at Test$.unapply(<console>:13)
at Test$.test(<console>:17)
...

Note that it's clear where the error comes from. However, the error shows that the method unapply is not inlined as I wanted to.
How can I inline this unapply method? This is for performance reason as well as code reuse.


Solution

  • @inline only requests that the compiler try to inline a method, but it doesn't have to, and in some cases, it can't. I don't think there is a spec for exactly what can and cannot be inlined by the compiler (though I'd love to see one if there is), but I'd bet the compiler simply won't in this case, no matter what you do.

    Generally, you would only want to inline something that is a constant or small and unlikely to change, anyway. Otherwise, many uses of Test.unapply will cause the compiled code to increase in size quickly, and changes to the inlined method will proliferate across everything that references it.

    This answer from @RexKerr says enough.