All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.compiletime.package.scala Maven / Gradle / Ivy

The newest version!
package scala

import scala.quoted._

package object compiletime {

  /** Use this method when you have a type, do not have a value for it but want to
   *  pattern match on it. For example, given a type `Tup <: Tuple`, one can
   *  pattern-match on it as follows:
   *  ```
   *  inline erasedValue[Tup] match {
   *    case _: EmptyTuple => ...
   *    case _: h *: t => ...
   *  }
   *  ```
   *  This value can only be used in an inline match and the value cannot be used in
   *  the branches.
   */
  erased def erasedValue[T]: T = ???

  /** The error method is used to produce user-defined compile errors during inline expansion.
   *  If an inline expansion results in a call error(msgStr) the compiler produces an error message containing the given msgStr.
   *
   *  ```scala
   *  error("My error message")
   *  ```
   *  or
   *  ```scala
   *  error(code"My error of this code: ${println("foo")}")
   *  ```
   */
  inline def error(inline msg: String): Nothing = ???

  extension (inline self: StringContext):
   /** Returns the string representation of interpolated elaborated code:
    *
    *  ```scala
    *  inline def logged(p1: => Any) = {
    *    val c = code"code: $p1"
    *    val res = p1
    *    (c, p1)
    *  }
    *  logged(identity("foo"))
    *  // above is equivalent to:
    *  // ("code: scala.Predef.identity("foo")", identity("foo"))
    *  ```
    *
    * @note only by-name arguments will be displayed as "code".
    *       Other values may display unintutively.
    */
    transparent inline def code (inline args: Any*): String =
      ${ dotty.internal.CompileTimeMacros.codeExpr('self, 'args) }
  end extension

  /** Checks at compiletime that the provided values is a constant after
   *  inlining and constant folding.
   *
   *  Usage:
   *  ```scala
   *  inline def twice(inline n: Int): Int =
   *    requireConst(n) // compile-time assertion that the parameter `n` is a constant
   *    n + n
   *
   *  twice(1)
   *  val m: Int = ...
   *  twice(m) // error: expected a constant value but found: m
   *  ```
   */
  inline def requireConst(inline x: Boolean | Byte | Short | Int | Long | Float | Double | Char | String): Unit = ()

  /** Same as `constValue` but returns a `None` if a constant value
   *  cannot be constructed from the provided type. Otherwise returns
   *  that value wrapped in `Some`.
   */
  inline def constValueOpt[T]: Option[T] = ???

  /** Given a constant, singleton type `T`, convert it to a value
   *  of the same singleton type. For example: `assert(constValue[1] == 1)`.
   */
  inline def constValue[T]: T = ???

  /** Given a tuple type `(X1, ..., Xn)`, returns a tuple value
   *  `(constValue[X1], ..., constValue[Xn])`.
   */
  inline def constValueTuple[T <: Tuple]: Tuple.Widen[T]=
    val res =
      inline erasedValue[T] match
        case _: EmptyTuple => EmptyTuple
        case _: (t *: ts) => constValue[t] *: constValueTuple[ts]
      end match
    res.asInstanceOf[Tuple.Widen[T]]
  end constValueTuple

  /** Summons first given matching one of the listed cases. E.g. in
   *
   *      given B { ... }
   *
   *      summonFrom {
   *        case given A => 1
   *        case given B => 2
   *        case given C => 3
   *        case _ => 4
   *      }
   *
   *  the returned value would be `2`.
   */
  transparent inline def summonFrom[T](f: Nothing => T): T = ???


  /** Summon a given value of type `T`. Usually, the argument is not passed explicitly.
   *  The summoning is delayed until the call has been fully inlined.
   *
   *  @tparam T the type of the value to be summoned
   *  @return the given value typed as the provided type parameter
   */
  transparent inline def summonInline[T]: T = summonFrom {
    case t: T => t
  }

  /** Given a tuple T, summons each of its member types and returns them in
   *  a Tuple.
   *
   *  @tparam T the tuple containing the types of the values to be summoned
   *  @return the given values typed as elements of the tuple
   */
  inline def summonAll[T <: Tuple]: Tuple.Widen[T] =
    val res =
      inline erasedValue[T] match
        case _: EmptyTuple => EmptyTuple
        case _: (t *: ts) => summonInline[t] *: summonAll[ts]
      end match
    res.asInstanceOf[Tuple.Widen[T]]
  end summonAll

  /** Succesor of a natural number where zero is the type 0 and successors are reduced as if the definition was
   *
   *      type S[N <: Int] <: Int = N match {
   *        case 0 => 1
   *        case 1 => 2
   *        case 2 => 3
   *        ...
   *        case 2147483646 => 2147483647
   *      }
   */
  type S[N <: Int] <: Int

  /** Assertion that an argument is by-name. Used for nullability checking. */
  def byName[T](x: => T): T = x
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy