From 90998f4f140ed2443c9b09763e4a285094ff9f8b Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 6 Dec 2022 21:41:38 +0800 Subject: [PATCH] Allow closures in parse expressions. --- CHANGELOG.md | 1 + src/parser.rs | 7 +++---- tests/expressions.rs | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb8861ff..e84197cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Bug fixes * Integer numbers that are too large to deserialize into `INT` now fall back to `Decimal` or `FLOAT` instead of silently truncating. * Parsing deeply-nested closures (e.g. `||{||{||{||{||{||{||{...}}}}}}}`) no longer panics but will be confined to the nesting limit. +* Closures containing a single expression are now allowed in `Engine::eval_expression` etc. Breaking API changes -------------------- diff --git a/src/parser.rs b/src/parser.rs index bd60a331..171d1113 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3845,8 +3845,6 @@ impl Engine { let mut functions = StraightHashMap::default(); let options = self.options & !LangOptions::STMT_EXPR & !LangOptions::LOOP_EXPR; - #[cfg(not(feature = "no_function"))] - let options = options & !LangOptions::ANON_FN; let mut settings = ParseSettings { level: 0, @@ -3861,6 +3859,7 @@ impl Engine { let expr = self.parse_expr(&mut input, state, &mut functions, settings)?; + #[cfg(feature = "no_function")] assert!(functions.is_empty()); match input.peek().expect(NEVER_ENDS) { @@ -3877,7 +3876,7 @@ impl Engine { state.scope, statements, #[cfg(not(feature = "no_function"))] - StaticVec::new_const(), + functions.into_iter().map(|(.., v)| v).collect(), _optimization_level, )); @@ -3885,7 +3884,7 @@ impl Engine { return Ok(AST::new( statements, #[cfg(not(feature = "no_function"))] - crate::Module::new(), + functions.into_iter().map(|(.., v)| v).collect(), )); } diff --git a/tests/expressions.rs b/tests/expressions.rs index ed5e3a16..34938a57 100644 --- a/tests/expressions.rs +++ b/tests/expressions.rs @@ -16,6 +16,24 @@ fn test_expressions() -> Result<(), Box> { engine.eval_expression_with_scope::(&mut scope, "if x > 0 { 42 } else { 123 }")?, 42 ); + #[cfg(not(feature = "no_index"))] + #[cfg(not(feature = "no_object"))] + #[cfg(not(feature = "no_function"))] + { + assert_eq!( + engine.eval_expression_with_scope::( + &mut scope, + "[1, 2, 3, 4].map(|x| x * x).reduce(|a, v| a + v, 0)" + )?, + 30 + ); + assert!(engine + .eval_expression_with_scope::( + &mut scope, + "[1, 2, 3, 4].map(|x| { let r = 2; x * r }).reduce(|a, v| a + v, 0)" + ) + .is_err()); + } assert!(engine .eval_expression_with_scope::(&mut scope, "if x > 0 { let y = 42; y } else { 123 }") .is_err());