elidable

scala.annotation.elidable
See theelidable companion object
final class elidable(val level: Int) extends ConstantAnnotation

An annotation for methods whose bodies may be excluded from compiler-generated bytecode.

Behavior is influenced by passing -Xelide-below <arg> to scalac. Calls to methods marked elidable (as well as the method body) will be omitted from generated code if the priority given the annotation is lower than that given on the command line.

@elidable(123)           // annotation priority
scalac -Xelide-below 456 // command line priority

The method call will be replaced with an expression which depends on the type of the elided expression. In decreasing order of precedence:

Unit            ()
Boolean         false
T <: AnyVal     0
T >: Null       null
T >: Nothing    Predef.???

Complete example:

import scala.annotation._, elidable._
object Test extends App {
  def expensiveComputation(): Int = { Thread.sleep(1000) ; 172 }

  @elidable(WARNING) def warning(msg: String) = println(msg)
  @elidable(FINE) def debug(msg: String)      = println(msg)
  @elidable(FINE) def computedValue           = expensiveComputation()

  warning("Warning! Danger! Warning!")
  debug("Debug! Danger! Debug!")
  println("I computed a value: " + computedValue)
}
% scalac example.scala && scala Test
Warning! Danger! Warning!
Debug! Danger! Debug!
I computed a value: 172

// INFO lies between WARNING and FINE
% scalac -Xelide-below INFO example.scala && scala Test
Warning! Danger! Warning!
I computed a value: 0

Note that only concrete methods can be marked @elidable. A non-annotated method is not elided, even if it overrides / implements a method that has the annotation.

Also note that the static type determines which annotations are considered:

import scala.annotation._, elidable._
class C { @elidable(0) def f(): Unit = ??? }
object O extends C { override def f(): Unit = println("O.f") }
object Test extends App {
  O.f()      // not elided
  (O: C).f() // elided if compiled with `-Xelide-below 1`
}

Note for Scala 3 users: If you're using Scala 3, the annotation exists since Scala 3 uses the Scala 2 standard library, but it's unsupported by the Scala 3 compiler. Instead, to achieve the same result you'd want to utilize the inline if feature to introduce behavior that makes a method de facto elided at compile-time.

type LogLevel = Int

object LogLevel:
  inline val Info = 0
  inline val Warn = 1
  inline val Debug = 2

inline val appLogLevel = LogLevel.Warn

inline def log(msg: String, inline level: LogLevel): Unit =
  inline if (level <= appLogLevel) then println(msg)

log("Warn log", LogLevel.Warn)

log("Debug log", LogLevel. Debug)

Attributes

Companion
object
Source
elidable.scala
Graph
Supertypes
class Annotation
class Object
trait Matchable
class Any
Show all

Members list

Value members

Concrete fields

final val level: Int

Attributes

Source
elidable.scala