fix(tvix/eval): preserve catchables in nix_cmp_ordering(), fix b/338
This commit fixes b/338 by properly propagating catchables through comparison operations. Change-Id: I6b0283a40f228ecf9a6398d24c060bdacb1077cf Reviewed-on: https://cl.tvl.fyi/c/depot/+/10221 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI Autosubmit: Adam Joseph <adam@westernsemico.com>
This commit is contained in:
parent
ae28dc3ca6
commit
ad566999ca
5 changed files with 15 additions and 9 deletions
|
@ -611,10 +611,11 @@ mod pure_builtins {
|
||||||
#[builtin("lessThan")]
|
#[builtin("lessThan")]
|
||||||
async fn builtin_less_than(co: GenCo, x: Value, y: Value) -> Result<Value, ErrorKind> {
|
async fn builtin_less_than(co: GenCo, x: Value, y: Value) -> Result<Value, ErrorKind> {
|
||||||
let span = generators::request_span(&co).await;
|
let span = generators::request_span(&co).await;
|
||||||
Ok(Value::Bool(matches!(
|
match x.nix_cmp_ordering(y, co, span).await? {
|
||||||
x.nix_cmp_ordering(y, co, span).await?,
|
Err(cek) => Ok(Value::Catchable(cek)),
|
||||||
Ordering::Less
|
Ok(Ordering::Less) => Ok(Value::Bool(true)),
|
||||||
)))
|
Ok(_) => Ok(Value::Bool(false)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[builtin("listToAttrs")]
|
#[builtin("listToAttrs")]
|
||||||
|
|
|
@ -616,7 +616,7 @@ impl Value {
|
||||||
other: Self,
|
other: Self,
|
||||||
co: GenCo,
|
co: GenCo,
|
||||||
span: LightSpan,
|
span: LightSpan,
|
||||||
) -> Result<Ordering, ErrorKind> {
|
) -> Result<Result<Ordering, CatchableErrorKind>, ErrorKind> {
|
||||||
Self::nix_cmp_ordering_(self, other, co, span).await
|
Self::nix_cmp_ordering_(self, other, co, span).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ impl Value {
|
||||||
other: Self,
|
other: Self,
|
||||||
co: GenCo,
|
co: GenCo,
|
||||||
span: LightSpan,
|
span: LightSpan,
|
||||||
) -> Result<Ordering, ErrorKind> {
|
) -> Result<Result<Ordering, CatchableErrorKind>, ErrorKind> {
|
||||||
// this is a stack of ((v1,v2),peq) triples to be compared;
|
// this is a stack of ((v1,v2),peq) triples to be compared;
|
||||||
// after each triple is popped off of the stack, v1 is
|
// after each triple is popped off of the stack, v1 is
|
||||||
// compared to v2 using peq-mode PointerEquality
|
// compared to v2 using peq-mode PointerEquality
|
||||||
|
@ -636,7 +636,7 @@ impl Value {
|
||||||
abp
|
abp
|
||||||
} else {
|
} else {
|
||||||
// stack is empty, so they are equal
|
// stack is empty, so they are equal
|
||||||
return Ok(Ordering::Equal);
|
return Ok(Ok(Ordering::Equal));
|
||||||
};
|
};
|
||||||
if ptr_eq == PointerEquality::AllowAll {
|
if ptr_eq == PointerEquality::AllowAll {
|
||||||
if a.clone()
|
if a.clone()
|
||||||
|
@ -650,6 +650,8 @@ impl Value {
|
||||||
b = b.force(&co, span.clone()).await?;
|
b = b.force(&co, span.clone()).await?;
|
||||||
}
|
}
|
||||||
let result = match (a, b) {
|
let result = match (a, b) {
|
||||||
|
(Value::Catchable(c), _) => return Ok(Err(c)),
|
||||||
|
(_, Value::Catchable(c)) => return Ok(Err(c)),
|
||||||
// same types
|
// same types
|
||||||
(Value::Integer(i1), Value::Integer(i2)) => i1.cmp(&i2),
|
(Value::Integer(i1), Value::Integer(i2)) => i1.cmp(&i2),
|
||||||
(Value::Float(f1), Value::Float(f2)) => f1.total_cmp(&f2),
|
(Value::Float(f1), Value::Float(f2)) => f1.total_cmp(&f2),
|
||||||
|
@ -682,7 +684,7 @@ impl Value {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if result != Ordering::Equal {
|
if result != Ordering::Equal {
|
||||||
return Ok(result);
|
return Ok(Ok(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,10 @@ macro_rules! cmp_op {
|
||||||
let b = generators::request_force(&co, b).await;
|
let b = generators::request_force(&co, b).await;
|
||||||
let span = generators::request_span(&co).await;
|
let span = generators::request_span(&co).await;
|
||||||
let ordering = a.nix_cmp_ordering(b, co, span).await?;
|
let ordering = a.nix_cmp_ordering(b, co, span).await?;
|
||||||
Ok(Value::Bool(cmp_op!(@order $op ordering)))
|
match ordering {
|
||||||
|
Err(cek) => Ok(Value::Catchable(cek)),
|
||||||
|
Ok(ordering) => Ok(Value::Bool(cmp_op!(@order $op ordering))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let gen_span = $frame.current_light_span();
|
let gen_span = $frame.current_light_span();
|
||||||
|
|
Loading…
Reference in a new issue