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
-
trait ConstantAnnotationtrait StaticAnnotationclass Annotationclass Objecttrait Matchableclass Any