Fix bug on chaining function calls returning shared values.

This commit is contained in:
Stephen Chung 2022-06-07 11:31:46 +08:00
parent 005692ef78
commit 84e3296559
3 changed files with 38 additions and 2 deletions

View File

@ -12,6 +12,7 @@ Bug fixes
* Parsing of index expressions is relaxed and many cases no longer result in an index-type error to allow for custom indexers.
* Merging or combining a self-contained `AST` into another `AST` now works properly.
* Plugin modules/functions no longer generate errors under `#![deny(missing_docs)]`.
* Calling a property on a function call that returns a shared value no longer causes an error.
Deprecated API's
----------------

View File

@ -652,7 +652,9 @@ impl Engine {
_ if is_assignment => unreachable!("cannot assign to an expression"),
// {expr}.??? or {expr}[???]
expr => {
let value = self.eval_expr(scope, global, caches, lib, this_ptr, expr, level)?;
let value = self
.eval_expr(scope, global, caches, lib, this_ptr, expr, level)?
.flatten();
let obj_ptr = &mut value.into();
let root = ("", expr.start_position());
self.eval_dot_index_chain_helper(
@ -1043,6 +1045,11 @@ impl Engine {
})
}
#[cfg(not(feature = "no_closure"))]
Dynamic(Union::Shared(..)) => {
unreachable!("`get_indexed_mut` cannot handle shared values")
}
_ if use_indexers => self
.call_indexer_get(global, caches, lib, target, &mut idx, level)
.map(Into::into),

View File

@ -1,5 +1,5 @@
#![cfg(not(feature = "no_function"))]
use rhai::{Engine, EvalAltResult, FnPtr, ParseErrorType, Scope, INT};
use rhai::{Dynamic, Engine, EvalAltResult, FnPtr, ParseErrorType, Scope, INT};
use std::any::TypeId;
use std::cell::RefCell;
use std::mem::take;
@ -217,6 +217,34 @@ fn test_closures_sharing() -> Result<(), Box<EvalAltResult>> {
6
);
#[cfg(not(feature = "no_object"))]
{
let mut m = Map::new();
m.insert("hello".into(), "world".into());
let m = Dynamic::from(m).into_shared();
engine.register_fn("baz", move || m.clone());
assert!(!engine.eval::<bool>(
"
let m = baz();
m.is_shared()
"
)?);
assert_eq!(
engine.eval::<String>(
"
let m = baz();
m.hello
"
)?,
"world"
);
assert_eq!(engine.eval::<String>("baz().hello")?, "world");
}
Ok(())
}