diff --git a/src/any.rs b/src/any.rs index ac2d9f68..97f5bf57 100644 --- a/src/any.rs +++ b/src/any.rs @@ -1,9 +1,11 @@ -use std::any::{Any as StdAny, TypeId}; +use std::any::{type_name, Any as StdAny, TypeId}; use std::fmt; pub trait Any: StdAny { fn type_id(&self) -> TypeId; + fn type_name(&self) -> String; + fn box_clone(&self) -> Box; /// This type may only be implemented by `rhai`. @@ -20,6 +22,10 @@ where TypeId::of::() } + fn type_name(&self) -> String { + type_name::().to_string() + } + #[inline] fn box_clone(&self) -> Box { Box::new(self.clone()) diff --git a/src/engine.rs b/src/engine.rs index 1186afe1..f1e6b8a3 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -127,7 +127,6 @@ pub struct FnSpec { pub struct Engine { /// A hashmap containing all functions known to the engine pub fns: HashMap>, - pub type_names: HashMap, } pub enum FnIntExt { @@ -164,7 +163,7 @@ impl Engine { .and_then(|b| { b.downcast() .map(|b| *b) - .map_err(|a| EvalAltResult::ErrorMismatchOutputType(self.nice_type_name(a))) + .map_err(|a| EvalAltResult::ErrorMismatchOutputType((*a).type_name())) }) } @@ -202,7 +201,7 @@ impl Engine { .ok_or_else(|| { let typenames = args .iter() - .map(|x| self.nice_type_name((&**x).box_clone())) + .map(|x| (*(&**x).box_clone()).type_name()) .collect::>(); EvalAltResult::ErrorFunctionNotFound(format!("{} ({})", ident, typenames.join(","))) }) @@ -239,13 +238,6 @@ impl Engine { // currently a no-op, exists for future extensibility } - /// Register a type, providing a name for nice error messages. - pub fn register_type_name(&mut self, name: &str) { - self.register_type::(); - debug_println!("register type {}: {:?}", name, TypeId::of::()); - self.type_names.insert(TypeId::of::(), name.into()); - } - /// Register a get function for a member of a registered type pub fn register_get(&mut self, name: &str, get_fn: F) where @@ -632,15 +624,6 @@ impl Engine { } } - fn nice_type_name(&self, b: Box) -> String { - let tid = ::type_id(&*b); - if let Some(name) = self.type_names.get(&tid) { - name.to_string() - } else { - format!(" {:?}", b.type_id()) - } - } - /// Evaluate a file pub fn eval_file(&mut self, fname: &str) -> Result { use std::fs::File; @@ -704,9 +687,7 @@ impl Engine { match x.downcast::() { Ok(out) => Ok(*out), - Err(a) => Err(EvalAltResult::ErrorMismatchOutputType( - self.nice_type_name(a), - )), + Err(a) => Err(EvalAltResult::ErrorMismatchOutputType((*a).type_name())), } } Err(_) => Err(EvalAltResult::ErrorFunctionArgMismatch), @@ -789,18 +770,6 @@ impl Engine { /// Register the default library. That means, numberic types, char, bool /// String, arithmetics and string concatenations. pub fn register_default_lib(engine: &mut Engine) { - engine.register_type_name::("i32"); - engine.register_type_name::("u32"); - engine.register_type_name::("integer"); - engine.register_type_name::("u64"); - engine.register_type_name::("usize"); - engine.register_type_name::("f32"); - engine.register_type_name::("float"); - engine.register_type_name::("string"); - engine.register_type_name::("char"); - engine.register_type_name::("boolean"); - engine.register_type_name::>>("array"); - macro_rules! reg_op { ($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => ( $( @@ -943,7 +912,6 @@ impl Engine { pub fn new() -> Engine { let mut engine = Engine { fns: HashMap::new(), - type_names: HashMap::new(), }; Engine::register_default_lib(&mut engine); diff --git a/tests/mismatched_op.rs b/tests/mismatched_op.rs index 0c455d99..2d6ff5fa 100644 --- a/tests/mismatched_op.rs +++ b/tests/mismatched_op.rs @@ -1,4 +1,4 @@ -use rhai::{Engine, EvalAltResult}; +use rhai::{Engine, EvalAltResult, RegisterFn}; #[test] fn test_mismatched_op() { @@ -7,7 +7,32 @@ fn test_mismatched_op() { assert_eq!( engine.eval::("60 + \"hello\""), Err(EvalAltResult::ErrorFunctionNotFound( - "+ (integer,string)".into() + "+ (i64,alloc::string::String)".into() + )) + ); +} + +#[test] +fn test_mismatched_op_custom_type() { + #[derive(Clone)] + struct TestStruct { + x: i64, + } + + impl TestStruct { + fn new() -> TestStruct { + TestStruct { x: 1 } + } + } + + let mut engine = Engine::new(); + engine.register_type::(); + engine.register_fn("new_ts", TestStruct::new); + + assert_eq!( + engine.eval::("60 + new_ts()"), + Err(EvalAltResult::ErrorFunctionNotFound( + "+ (i64,mismatched_op::test_mismatched_op_custom_type::TestStruct)".into() )) ); }