diff --git a/src/ast.rs b/src/ast.rs index c21439b7..d12c8d14 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -5,8 +5,7 @@ use crate::module::NamespaceRef; use crate::token::Token; use crate::utils::calc_fn_hash; use crate::{ - Dynamic, FnNamespace, FnPtr, Identifier, ImmutableString, Module, Position, Shared, StaticVec, - INT, + Dynamic, FnNamespace, Identifier, ImmutableString, Module, Position, Shared, StaticVec, INT, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -1613,8 +1612,6 @@ pub enum Expr { CharConstant(char, Position), /// [String][ImmutableString] constant. StringConstant(ImmutableString, Position), - /// [`FnPtr`] constant. - FnPointer(Box, Position), /// An interpolated [string][ImmutableString]. InterpolatedString(Box>), /// [ expr, ... ] @@ -1675,7 +1672,6 @@ impl fmt::Debug for Expr { Self::FloatConstant(value, pos) => write!(f, "{:?} @ {:?}", value, pos), Self::CharConstant(value, pos) => write!(f, "{:?} @ {:?}", value, pos), Self::StringConstant(value, pos) => write!(f, "{:?} @ {:?}", value, pos), - Self::FnPointer(value, pos) => write!(f, "Fn({:?}) @ {:?}", value, pos), Self::Unit(pos) => write!(f, "() @ {:?}", pos), Self::InterpolatedString(x) => { f.write_str("InterpolatedString")?; @@ -1765,9 +1761,6 @@ impl Expr { Self::FloatConstant(x, _) => (*x).into(), Self::CharConstant(x, _) => (*x).into(), Self::StringConstant(x, _) => x.clone().into(), - Self::FnPointer(x, _) => { - FnPtr::new_unchecked(x.as_ref().clone(), Default::default()).into() - } Self::BoolConstant(x, _) => (*x).into(), Self::Unit(_) => Dynamic::UNIT, @@ -1819,7 +1812,6 @@ impl Expr { Self::CharConstant(_, pos) => *pos, Self::StringConstant(_, pos) => *pos, Self::InterpolatedString(x) => x.first().unwrap().position(), - Self::FnPointer(_, pos) => *pos, Self::Array(_, pos) => *pos, Self::Map(_, pos) => *pos, Self::Property(x) => (x.2).pos, @@ -1851,7 +1843,6 @@ impl Expr { Self::InterpolatedString(x) => { x.first_mut().unwrap().set_position(new_pos); } - Self::FnPointer(_, pos) => *pos = new_pos, Self::Array(_, pos) => *pos = new_pos, Self::Map(_, pos) => *pos = new_pos, Self::Variable(_, pos, _) => *pos = new_pos, @@ -1907,7 +1898,6 @@ impl Expr { | Self::IntegerConstant(_, _) | Self::CharConstant(_, _) | Self::StringConstant(_, _) - | Self::FnPointer(_, _) | Self::Unit(_) => true, Self::InterpolatedString(x) | Self::Array(x, _) => x.iter().all(Self::is_constant), @@ -1934,7 +1924,6 @@ impl Expr { | Self::BoolConstant(_, _) | Self::IntegerConstant(_, _) | Self::CharConstant(_, _) - | Self::FnPointer(_, _) | Self::And(_, _) | Self::Or(_, _) | Self::Unit(_) => false, diff --git a/src/dynamic.rs b/src/dynamic.rs index c17db24e..19b71823 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -407,6 +407,13 @@ impl Hash for Dynamic { value.hash(state); }) } + Union::FnPtr(f, _) if f.is_curried() => { + unimplemented!( + "{} with curried arguments cannot be hashed", + self.type_name() + ) + } + Union::FnPtr(f, _) => f.fn_name().hash(state), #[cfg(not(feature = "no_closure"))] Union::Shared(cell, _) => { diff --git a/src/engine.rs b/src/engine.rs index a21af6be..541353c8 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -13,8 +13,8 @@ use crate::r#unsafe::unsafe_cast_var_name_to_lifetime; use crate::syntax::CustomSyntax; use crate::utils::get_hasher; use crate::{ - Dynamic, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, Position, RhaiResult, - Scope, Shared, StaticVec, + Dynamic, EvalAltResult, Identifier, ImmutableString, Module, Position, RhaiResult, Scope, + Shared, StaticVec, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -1749,9 +1749,6 @@ impl Engine { Expr::FloatConstant(x, _) => Ok((*x).into()), Expr::StringConstant(x, _) => Ok(x.clone().into()), Expr::CharConstant(x, _) => Ok((*x).into()), - Expr::FnPointer(x, _) => { - Ok(FnPtr::new_unchecked(x.as_ref().clone(), Default::default()).into()) - } Expr::Variable(None, var_pos, x) if x.0.is_none() && x.2 == KEYWORD_THIS => this_ptr .as_deref() diff --git a/src/optimize.rs b/src/optimize.rs index 94ebd31e..3ddde12c 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -7,8 +7,8 @@ use crate::fn_builtin::get_builtin_binary_op_fn; use crate::parser::map_dynamic_to_expr; use crate::utils::get_hasher; use crate::{ - calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, ImmutableString, Module, - Position, Scope, StaticVec, AST, + calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, ImmutableString, + Module, Position, Scope, StaticVec, AST, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -870,7 +870,8 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) { && x.name == KEYWORD_FN_PTR => { state.set_dirty(); - *expr = Expr::FnPointer(Box::new(mem::take(&mut x.constant_args[0].0).as_str_ref().unwrap().into()), *pos); + let fn_ptr = FnPtr::new_unchecked(mem::take(&mut x.constant_args[0].0).as_str_ref().unwrap().into(), Default::default()); + *expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), *pos); } // Do not call some special keywords diff --git a/src/parser.rs b/src/parser.rs index 56841dfa..7bb42b49 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -15,8 +15,8 @@ use crate::token::{ }; use crate::utils::{get_hasher, IdentifierBuilder}; use crate::{ - calc_fn_hash, Dynamic, Engine, Identifier, LexError, ParseError, ParseErrorType, Position, - Scope, Shared, StaticVec, AST, + calc_fn_hash, Dynamic, Engine, FnPtr, Identifier, LexError, ParseError, ParseErrorType, + Position, Scope, Shared, StaticVec, AST, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -3018,7 +3018,8 @@ fn parse_anon_fn( comments: Default::default(), }; - let expr = Expr::FnPointer(fn_name.into(), settings.pos); + let fn_ptr = FnPtr::new_unchecked(fn_name.into(), Default::default()); + let expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), settings.pos); #[cfg(not(feature = "no_closure"))] let expr = make_curry_from_externals(state, expr, externals, settings.pos);