fix(tvix/eval): catchable in type field of nix_eq()

Change-Id: I165ff77764e272cc94d18cb03ad6cbc9a8ebefde
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10348
Autosubmit: Adam Joseph <adam@westernsemico.com>
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
This commit is contained in:
Adam Joseph 2023-12-12 21:18:09 -08:00 committed by tazjin
parent 2af8174e2e
commit 7ddea7340f
5 changed files with 26 additions and 8 deletions

View file

@ -312,8 +312,11 @@ mod pure_builtins {
#[builtin("elem")] #[builtin("elem")]
async fn builtin_elem(co: GenCo, x: Value, xs: Value) -> Result<Value, ErrorKind> { async fn builtin_elem(co: GenCo, x: Value, xs: Value) -> Result<Value, ErrorKind> {
for val in xs.to_list()? { for val in xs.to_list()? {
if generators::check_equality(&co, x.clone(), val, PointerEquality::AllowAll).await? { match generators::check_equality(&co, x.clone(), val, PointerEquality::AllowAll).await?
return Ok(true.into()); {
Ok(true) => return Ok(true.into()),
Ok(false) => continue,
Err(cek) => return Ok(Value::Catchable(cek)),
} }
} }
Ok(false.into()) Ok(false.into())
@ -1183,7 +1186,7 @@ mod pure_builtins {
/// value has been seen before. /// value has been seen before.
async fn bgc_insert_key(co: &GenCo, key: Value, done: &mut Vec<Value>) -> Result<bool, ErrorKind> { async fn bgc_insert_key(co: &GenCo, key: Value, done: &mut Vec<Value>) -> Result<bool, ErrorKind> {
for existing in done.iter() { for existing in done.iter() {
if generators::check_equality( match generators::check_equality(
co, co,
existing.clone(), existing.clone(),
key.clone(), key.clone(),
@ -1192,7 +1195,11 @@ async fn bgc_insert_key(co: &GenCo, key: Value, done: &mut Vec<Value>) -> Result
) )
.await? .await?
{ {
return Ok(false); Ok(true) => return Ok(false),
Ok(false) => (),
Err(_cek) => {
unimplemented!("TODO(amjoseph): not sure what the correct behavior is here")
}
} }
} }

View file

@ -0,0 +1 @@
(builtins.tryEval (builtins.elem { type = rec { x = throw "fred"; }.x; } [ { type = 3; } ])).success

View file

@ -547,8 +547,16 @@ impl Value {
#[allow(clippy::single_match)] // might need more match arms later #[allow(clippy::single_match)] // might need more match arms later
match (a1.select("type"), a2.select("type")) { match (a1.select("type"), a2.select("type")) {
(Some(v1), Some(v2)) => { (Some(v1), Some(v2)) => {
let s1 = v1.clone().force(co, span.clone()).await?.to_str(); let s1 = v1.clone().force(co, span.clone()).await?;
let s2 = v2.clone().force(co, span.clone()).await?.to_str(); if s1.is_catchable() {
return Ok(s1);
}
let s2 = v2.clone().force(co, span.clone()).await?;
if s2.is_catchable() {
return Ok(s2);
}
let s1 = s1.to_str();
let s2 = s2.to_str();
if let (Ok(s1), Ok(s2)) = (s1, s2) { if let (Ok(s1), Ok(s2)) = (s1, s2) {
if s1.as_str() == "derivation" && s2.as_str() == "derivation" { if s1.as_str() == "derivation" && s2.as_str() == "derivation" {

View file

@ -631,12 +631,13 @@ pub(crate) async fn check_equality(
a: Value, a: Value,
b: Value, b: Value,
ptr_eq: PointerEquality, ptr_eq: PointerEquality,
) -> Result<bool, ErrorKind> { ) -> Result<Result<bool, CatchableErrorKind>, ErrorKind> {
match co match co
.yield_(VMRequest::NixEquality(Box::new((a, b)), ptr_eq)) .yield_(VMRequest::NixEquality(Box::new((a, b)), ptr_eq))
.await .await
{ {
VMResponse::Value(value) => value.as_bool(), VMResponse::Value(Value::Bool(b)) => Ok(Ok(b)),
VMResponse::Value(Value::Catchable(cek)) => Ok(Err(cek)),
msg => panic!( msg => panic!(
"Tvix bug: VM responded with incorrect generator message: {}", "Tvix bug: VM responded with incorrect generator message: {}",
msg msg