diff --git a/core/src/eval/mod.rs b/core/src/eval/mod.rs index 730a8c9a76..2ef753c02a 100644 --- a/core/src/eval/mod.rs +++ b/core/src/eval/mod.rs @@ -185,6 +185,7 @@ impl VirtualMachine { .map(|result| result.body) } + /// Same as [Self::eval_full], but takes a closure as an argument instead of a term. pub fn eval_full_closure(&mut self, t0: Closure) -> Result { self.eval_deep_closure_impl(t0, false) .map(|result| Closure { diff --git a/core/src/eval/operation.rs b/core/src/eval/operation.rs index 1ba6052cef..c10de00cdc 100644 --- a/core/src/eval/operation.rs +++ b/core/src/eval/operation.rs @@ -707,6 +707,10 @@ impl VirtualMachine { env: Environment::new(), }) } + Term::EnumVariant { arg, .. } => Ok(Closure { + body: seq_terms(std::iter::once(arg), pos_op), + env, + }), _ => { if let Some((next, ..)) = self.stack.pop_arg(&self.cache) { Ok(next) @@ -1063,6 +1067,23 @@ impl VirtualMachine { env: Environment::new(), }) } + // For an enum variant, `force x` is simply equivalent to `deep_seq x x`, as + // there's no lazy pending contract to apply. + Term::EnumVariant { tag, arg, attrs } => { + let cont = RichTerm::new( + Term::EnumVariant { + tag, + arg: arg.clone(), + attrs, + }, + pos.into_inherited(), + ); + + Ok(Closure { + body: seq_terms(std::iter::once(arg), pos_op, cont), + env, + }) + } _ => Ok(Closure { body: RichTerm { term: t, pos }, env diff --git a/core/tests/integration/inputs/adts/deep_seq_enum.ncl b/core/tests/integration/inputs/adts/deep_seq_enum.ncl new file mode 100644 index 0000000000..3d273ca9b2 --- /dev/null +++ b/core/tests/integration/inputs/adts/deep_seq_enum.ncl @@ -0,0 +1,7 @@ +# test.type = 'error' +# +# [test.metadata] +# error = 'EvalError::BlameError' + +# Check that deep_eq correctly evaluate the content of an enum variant +%deep_seq% ('Foo 5 | [| 'Foo String |]) null diff --git a/core/tests/integration/inputs/adts/force_enum.ncl b/core/tests/integration/inputs/adts/force_enum.ncl new file mode 100644 index 0000000000..ce312f67c5 --- /dev/null +++ b/core/tests/integration/inputs/adts/force_enum.ncl @@ -0,0 +1,7 @@ +# test.type = 'error' +# +# [test.metadata] +# error = 'EvalError::BlameError' + +# Check that force correctly evaluate the content of an enum variant +%force% ('Foo 5 | [| 'Foo String |])