refactor(tvix/eval): Simplify forcing in builtins
Refactor the `force!` macro to a method on `Value` which returns a smart-pointer-esque type, which simplifies the callsite and eliminates rightward drift, especially for high-arity builtins. Change-Id: I97a7837580accfb4bbd03b24f2acdbd38645efa5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6656 Autosubmit: grfn <grfn@gws.fyi> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
This commit is contained in:
parent
bcbe1603c8
commit
69cbcc1eda
2 changed files with 90 additions and 97 deletions
|
|
@ -1,5 +1,7 @@
|
|||
//! This module implements the backing representation of runtime
|
||||
//! values in the Nix language.
|
||||
use std::cell::Ref;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use std::{fmt::Display, path::PathBuf};
|
||||
|
||||
|
|
@ -95,6 +97,26 @@ pub enum CoercionKind {
|
|||
Strong,
|
||||
}
|
||||
|
||||
/// A reference to a [`Value`] returned by a call to [`Value::force`], whether the value was
|
||||
/// originally a thunk or not.
|
||||
///
|
||||
/// Implements [`Deref`] to [`Value`], so can generally be used as a [`Value`]
|
||||
pub(crate) enum ForceResult<'a> {
|
||||
ForcedThunk(Ref<'a, Value>),
|
||||
Immediate(&'a Value),
|
||||
}
|
||||
|
||||
impl<'a> Deref for ForceResult<'a> {
|
||||
type Target = Value;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
ForceResult::ForcedThunk(r) => r,
|
||||
ForceResult::Immediate(v) => v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Value {
|
||||
/// Coerce a `Value` to a string. See `CoercionKind` for a rundown of what
|
||||
/// input types are accepted under what circumstances.
|
||||
|
|
@ -292,6 +314,17 @@ impl Value {
|
|||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure `self` is forced if it is a thunk, and return a reference to the resulting value.
|
||||
pub(crate) fn force(&self, vm: &mut VM) -> Result<ForceResult, ErrorKind> {
|
||||
match self {
|
||||
Self::Thunk(thunk) => {
|
||||
thunk.force(vm)?;
|
||||
Ok(ForceResult::ForcedThunk(thunk.value()))
|
||||
}
|
||||
_ => Ok(ForceResult::Immediate(self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Value {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue