diff --git a/CHANGELOG.md b/CHANGELOG.md index 24034e1e..80fc04b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,20 @@ Rhai Release Notes ================== +Version 1.4.2 +============= + +Bug fixes +--------- + +* Variables introduced inside `try` blocks are now properly cleaned up upon an exception. + + Version 1.4.1 ============= +This is primarily a bug-fix version which fixes a large number of bugs. + Bug fixes --------- diff --git a/Cargo.toml b/Cargo.toml index e51286bb..006c67bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "codegen"] [package] name = "rhai" -version = "1.4.1" +version = "1.5.0" edition = "2018" authors = ["Jonathan Turner", "Lukáš Hozda", "Stephen Chung", "jhwgh1968"] description = "Embedded scripting for Rust" diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 47760a04..96aa85bc 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -35,7 +35,7 @@ impl Engine { state.scope_level += 1; } - let mut result = Dynamic::UNIT; + let mut result = Ok(Dynamic::UNIT); for stmt in statements { let _mods_len = global.num_imports(); @@ -49,7 +49,11 @@ impl Engine { stmt, restore_orig_state, level, - )?; + ); + + if result.is_err() { + break; + } #[cfg(not(feature = "no_module"))] if matches!(stmt, Stmt::Import(_, _, _)) { @@ -89,7 +93,7 @@ impl Engine { state.always_search_scope = orig_always_search_scope; } - Ok(result) + result } /// Evaluate an op-assignment statement. diff --git a/tests/get_set.rs b/tests/get_set.rs index ee8e55f5..7ec97451 100644 --- a/tests/get_set.rs +++ b/tests/get_set.rs @@ -302,3 +302,68 @@ fn test_get_set_collection() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "no_index"))] +#[test] +fn test_get_set_indexer() -> Result<(), Box> { + type MyMap = std::collections::BTreeMap; + + let mut engine = Engine::new(); + + engine + .register_type_with_name::("MyMap") + .register_fn("new_map", || MyMap::new()) + .register_indexer_get_result(|map: &mut MyMap, index: &str| { + map.get(index) + .cloned() + .ok_or_else(|| format!("Index `{}` not found!", index).into()) + }) + .register_indexer_set(|map: &mut MyMap, index: &str, value: INT| { + map.insert(index.to_string(), value); + }) + .register_fn("to_string", |map: &mut MyMap| format!("{:?}", map)); + + assert_eq!( + engine.eval::( + r#" + let my_map = new_map(); + my_map["eggs"] = 42; + my_map["eggs"] + "#, + )?, + 42 + ); + + assert!(engine + .eval::( + r#" + let my_map = new_map(); + my_map["eggs"] = 42; + my_map["not_found"] + "#, + ) + .is_err()); + + assert_eq!( + engine.eval::( + r#" + let my_map = new_map(); + my_map["eggs"] = 42; + + try { + let eggs = my_map["eggs"]; + let eggs = my_map["not found"]; + } + catch(x) + { + print("Not found!"); + } + + my_map["eggs"] + "#, + )?, + 42 + ); + + Ok(()) +} diff --git a/tests/throw.rs b/tests/throw.rs index e0617559..79bd2424 100644 --- a/tests/throw.rs +++ b/tests/throw.rs @@ -29,6 +29,12 @@ fn test_try_catch() -> Result<(), Box> { 123 ); + #[cfg(not(feature = "unchecked"))] + assert_eq!( + engine.eval::("let x = 42; try { let y = 123; print(x/0); } catch { x = 0 } x")?, + 0 + ); + #[cfg(not(feature = "no_function"))] assert_eq!( engine.eval::(