diff --git a/src/evaluator.rs b/src/evaluator.rs index 6b45263..ac7c0b1 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -289,6 +289,7 @@ impl<'a> Evaluator<'a> { Ok(Value::Function(Function::UserDefined { body: body.clone(), environment: self.environment.clone(), + identity: Rc::new(()), name: None, parameters: parameters.clone(), })) @@ -447,6 +448,7 @@ impl<'a> Evaluator<'a> { let function = Function::UserDefined { body: body.clone(), environment: self.environment.clone(), + identity: Rc::new(()), name: Some(name.clone()), parameters: params.clone(), }; diff --git a/src/function.rs b/src/function.rs index d1736da..a94d9fd 100644 --- a/src/function.rs +++ b/src/function.rs @@ -10,6 +10,7 @@ pub enum Function<'src> { UserDefined { body: Vec>, environment: Environment<'src>, + identity: Rc<()>, name: Option, parameters: Vec, }, @@ -37,6 +38,7 @@ impl<'src> Function<'src> { environment, name, parameters, + .. } => { let call_environment = Environment::with_parent(environment.clone()); @@ -98,9 +100,9 @@ impl PartialEq for Function<'_> { match (self, other) { (Self::Builtin { name: a, .. }, Self::Builtin { name: b, .. }) => a == b, ( - Self::UserDefined { name: Some(a), .. }, - Self::UserDefined { name: Some(b), .. }, - ) => a == b, + Self::UserDefined { identity: a, .. }, + Self::UserDefined { identity: b, .. }, + ) => Rc::ptr_eq(a, b), _ => false, } } diff --git a/tests/integration.rs b/tests/integration.rs index bc913d3..6b3841d 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1354,6 +1354,35 @@ fn function_calling_builtin() -> Result { .run() } +#[test] +fn function_equality_uses_identity() -> Result { + Test::new()? + .program(indoc! { + " + anonymous = fn() {} + alias = anonymous + + println(anonymous == anonymous) + println(anonymous == alias) + println(anonymous == fn() {}) + + fn foo() { + return 1 + } + + original = foo + + fn foo() { + return 2 + } + + println(original == foo) + " + }) + .expected_stdout(Exact("true\ntrue\nfalse\nfalse\n")) + .run() +} + #[test] fn function_modifying_outer_scope() -> Result { Test::new()?