Attribute Macro tvix_eval_builtin_macros::builtins

source ·
#[builtins]
Expand description

Mark the annotated module as a module for defining Nix builtins.

An optional type definition may be specified as an argument (e.g. #[builtins(Rc<State>)]), which will add a parameter to the builtins function of that type which is passed to each builtin upon instantiation. Using this, builtins that close over some external state can be written.

The type of each function is rewritten to receive a Vec<Value>, containing each Value argument that the function receives. The body of functions is accordingly rewritten to “unwrap” values from this vector and bind them to the correct names, so unless a static error occurs this transformation is mostly invisible to users of the macro.

A function fn builtins() -> Vec<Builtin> will be defined within the annotated module, returning a list of [tvix_eval::Builtin] for each function annotated with the #[builtin] attribute within the module. If a state type is specified, the builtins function will take a value of that type.

Each invocation of the #[builtin] annotation within the module should be passed a string literal for the name of the builtin.

§Examples


#[builtins]
mod builtins {
    use tvix_eval::{GenCo, ErrorKind, Value};

    #[builtin("identity")]
    pub async fn builtin_identity(co: GenCo, x: Value) -> Result<Value, ErrorKind> {
        Ok(x)
    }

    // Builtins can request their argument not be forced before being called by annotating the
    // argument with the `#[lazy]` attribute

    #[builtin("tryEval")]
    pub async fn builtin_try_eval(co: GenCo, #[lazy] x: Value) -> Result<Value, ErrorKind> {
        todo!()
    }
}