From 1f5aefb21655ee17d18e87c1be2304e72e7ebb7a Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Fri, 6 Mar 2026 12:45:08 +0100 Subject: [PATCH] Remove redundant tail call resolution The `resolve_tail_calls` function is being called twice in some execution paths, which is unnecessary and can lead to incorrect behavior. This commit removes the redundant calls and simplifies the execution flow. --- src/ast/environment.rs | 19 ++++++------------- src/ast/vm.rs | 8 ++++++-- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/ast/environment.rs b/src/ast/environment.rs index feda2db..7d124d3 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -497,11 +497,7 @@ impl Environment { purity: Purity::Impure, func: Rc::new(move |args| { let mut vm = VM::new(global_values.clone()); - let res = match vm.run_with_args(closure_obj.clone(), args) { - Ok(v) => v, - Err(e) => panic!("Myc Runtime Error: {}", e), - }; - match vm.resolve_tail_calls(&mut crate::ast::vm::NoOpObserver, Ok(res)) { + match vm.run_with_args(closure_obj.clone(), args) { Ok(v) => v, Err(e) => panic!("Myc Runtime Error: {}", e), } @@ -519,21 +515,18 @@ impl Environment { Err(e) => panic!("Myc Runtime Error: {}", e), }; - let mut final_res = res; - if let Value::Object(obj) = &final_res + if let Value::Object(obj) = &res && obj .as_any() .downcast_ref::() .is_some() { - final_res = match vm.run_with_args(obj.clone(), args) { + match vm.run_with_args(obj.clone(), args) { Ok(v) => v, Err(e) => panic!("Myc Runtime Error (Closure): {}", e), - }; - } - match vm.resolve_tail_calls(&mut crate::ast::vm::NoOpObserver, Ok(final_res)) { - Ok(v) => v, - Err(e) => panic!("Myc Runtime Error: {}", e), + } + } else { + res } }), }) diff --git a/src/ast/vm.rs b/src/ast/vm.rs index a17c289..457d011 100644 --- a/src/ast/vm.rs +++ b/src/ast/vm.rs @@ -229,7 +229,9 @@ impl VM { } else { self.unpack(&closure.parameter_node, args, &mut 0)?; } - self.eval(&closure.exec_node) + let result = self.eval(&closure.exec_node); + self.frames.pop(); + self.resolve_tail_calls(&mut NoOpObserver, result) } pub fn run_with_args_observed( @@ -252,7 +254,9 @@ impl VM { } else { self.unpack(&closure.parameter_node, args, &mut 0)?; } - self.eval_observed(observer, &closure.exec_node) + let result = self.eval_observed(observer, &closure.exec_node); + self.frames.pop(); + self.resolve_tail_calls(observer, result) } pub fn run_with_observer(