Trap &mut String parameters.
This commit is contained in:
parent
fe633ea7d3
commit
e14bef4b10
@ -10,6 +10,7 @@ Bug fixes
|
|||||||
* Panic when passing a shared string into a registered function as `&str` argument is fixed.
|
* Panic when passing a shared string into a registered function as `&str` argument is fixed.
|
||||||
* Panic when calling `switch` statements on custom types is fixed.
|
* Panic when calling `switch` statements on custom types is fixed.
|
||||||
* Potential overflow panics in `range(from, to, step)` is fixed.
|
* Potential overflow panics in `range(from, to, step)` is fixed.
|
||||||
|
* `&mut String` parameters in registered functions no longer panic when passed a string.
|
||||||
* Some expressions involving shared variables now work properly, for example `x in shared_value`, `return shared_value`, `obj.field = shared_value` etc. Previously, the resultant value is still shared which is counter-intuitive.
|
* Some expressions involving shared variables now work properly, for example `x in shared_value`, `return shared_value`, `obj.field = shared_value` etc. Previously, the resultant value is still shared which is counter-intuitive.
|
||||||
* Errors in native Rust functions now contain the correct function call positions.
|
* Errors in native Rust functions now contain the correct function call positions.
|
||||||
* Fixed error types in `EvalAltResult::ErrorMismatchDataType` which were swapped.
|
* Fixed error types in `EvalAltResult::ErrorMismatchDataType` which were swapped.
|
||||||
|
@ -161,15 +161,15 @@ pub fn map_result(data: RhaiResult) -> RhaiResult {
|
|||||||
|
|
||||||
/// Remap `&str` | `String` to `ImmutableString`.
|
/// Remap `&str` | `String` to `ImmutableString`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn map_type_id<T: 'static>() -> TypeId {
|
fn map_type_id<R: 'static, T: 'static>() -> TypeId {
|
||||||
let id = TypeId::of::<T>();
|
let ref_id = TypeId::of::<R>();
|
||||||
|
|
||||||
if id == TypeId::of::<&str>() {
|
if ref_id == TypeId::of::<&str>() {
|
||||||
TypeId::of::<ImmutableString>()
|
TypeId::of::<ImmutableString>()
|
||||||
} else if id == TypeId::of::<String>() {
|
} else if ref_id == TypeId::of::<String>() {
|
||||||
TypeId::of::<ImmutableString>()
|
TypeId::of::<ImmutableString>()
|
||||||
} else {
|
} else {
|
||||||
id
|
TypeId::of::<T>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ macro_rules! def_register {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
||||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||||
&[$(map_type_id::<$par>()),*],
|
&[$(map_type_id::<$param, $par>()),*],
|
||||||
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $let => $clone => $arg),*))
|
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $let => $clone => $arg),*))
|
||||||
);
|
);
|
||||||
self
|
self
|
||||||
@ -208,7 +208,7 @@ macro_rules! def_register {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
||||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||||
&[$(map_type_id::<$par>()),*],
|
&[$(map_type_id::<$param, $par>()),*],
|
||||||
CallableFunction::$abi(make_func!(f : map_result ; $($par => $let => $clone => $arg),*))
|
CallableFunction::$abi(make_func!(f : map_result ; $($par => $let => $clone => $arg),*))
|
||||||
);
|
);
|
||||||
self
|
self
|
||||||
|
@ -64,6 +64,25 @@ fn test_string_dynamic() -> Result<(), Box<EvalAltResult>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_string_mut() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
|
engine.register_fn("foo", |x: INT, s: &str| s.len() as INT + x);
|
||||||
|
engine.register_fn("bar", |x: INT, s: String| s.len() as INT + x);
|
||||||
|
engine.register_fn("baz", |s: &mut String| s.len());
|
||||||
|
|
||||||
|
assert_eq!(engine.eval::<INT>(r#"foo(1, "hello")"#)?, 6);
|
||||||
|
assert_eq!(engine.eval::<INT>(r#"bar(1, "hello")"#)?, 6);
|
||||||
|
assert!(
|
||||||
|
matches!(*engine.eval::<INT>(r#"baz("hello")"#).expect_err("should error"),
|
||||||
|
EvalAltResult::ErrorFunctionNotFound(f, _) if f == "baz (&str | ImmutableString | String)"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_string_substring() -> Result<(), Box<EvalAltResult>> {
|
fn test_string_substring() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user