diff --git a/src/engine.rs b/src/engine.rs index 9be3c04c..4ad31b36 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -708,7 +708,11 @@ impl Engine { "{} ({})", fn_name, args.iter() - .map(|name| self.map_type_name(name.type_name())) + .map(|name| if name.is::() { + "&str | ImmutableString" + } else { + self.map_type_name(name.type_name()) + }) .collect::>() .join(", ") ), diff --git a/src/fn_register.rs b/src/fn_register.rs index 1384f666..1285c119 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -101,10 +101,10 @@ pub fn by_ref(data: &mut Dynamic) -> &mut T { #[inline(always)] pub fn by_value(data: &mut Dynamic) -> T { if TypeId::of::() == TypeId::of::<&str>() { - // &str parameters are mapped to the underlying ImmutableString - let r = data.as_str().unwrap(); - let x = unsafe { mem::transmute::<_, &T>(&r) }; - x.clone() + // If T is &str, data must be ImmutableString, so map directly to it + let ref_str = data.as_str().unwrap(); + let ref_T = unsafe { mem::transmute::<_, &T>(&ref_str) }; + ref_T.clone() } else { // We consume the argument and then replace it with () - the argument is not supposed to be used again. // This way, we avoid having to clone the argument again, because it is already a clone when passed here. diff --git a/tests/string.rs b/tests/string.rs index 27854629..c93278de 100644 --- a/tests/string.rs +++ b/tests/string.rs @@ -168,7 +168,7 @@ fn test_string_fn() -> Result<(), Box> { assert!(matches!( *engine.eval::(r#"foo3("hello")"#).expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(ref x, _) if x == "foo3 (string)" + EvalAltResult::ErrorFunctionNotFound(ref x, _) if x == "foo3 (&str | ImmutableString)" )); Ok(())