E217: Erased Not Pure

This error is emitted when an argument to an erased parameter or the right-hand-side of an erased value is not a pure expression.

Erased definitions are a feature that allows values to exist at compile time but be completely removed at runtime. Because erased values don't exist at runtime, their arguments must be pure expressions - expressions that are clearly side-effect free and terminating.

Pure expressions include:

  • Literals
  • References to values
  • Side-effect-free instance creations
  • Applications of inline functions to pure arguments

Example

import scala.language.experimental.erasedDefinitions

def foo(erased a: Int): Int = 42

def example: Int =
  foo(println("side effect").asInstanceOf[Int])

Error

-- [E217] Type Error: example.scala:6:41 ---------------------------------------
6 |  foo(println("side effect").asInstanceOf[Int])
  |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |      argument to an erased parameter fails to be a pure expression
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | The argument to an erased parameter must be a pure expression, but I found:
  |
  |   println("side effect").asInstanceOf[Int]
  |
  | This expression is not classified to be pure.
  | A pure expression is an expression that is clearly side-effect free and terminating.
  |           |Some examples of pure expressions are:
  |           |  - literals,
  |           |  - references to values,
  |           |  - side-effect-free instance creations,
  |           |  - applications of inline functions to pure arguments.
   -----------------------------------------------------------------------------

Solution

Use a pure expression as the argument to the erased parameter:

import scala.language.experimental.erasedDefinitions

def foo(erased a: Int): Int = 42

def example: Int =
  foo(0)  // literal is a pure expression

Or use a value reference:

import scala.language.experimental.erasedDefinitions

def foo(erased a: Int): Int = 42

def example: Int =
  val pureValue = 123
  foo(pureValue)  // reference to a value is pure