From c9f6232304558cbdafb14e13e316e539f5bed72e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 27 Feb 2014 21:47:59 +0100 Subject: [PATCH] Correctly detect infinite recursion in function application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we're evaluating some application ‘v = f x’, we can't store ‘f’ temporarily in ‘v’, because if ‘f x’ refers to ‘v’, it will get ‘f’ rather than an infinite recursion error. Unfortunately, this breaks the tail call optimisation introduced in c897bac54954373f63511702731fe2cb23c0c98e. Fixes #217. --- src/libexpr/eval.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2087c7c43f..b8c623b1a4 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -779,8 +779,10 @@ void ExprLambda::eval(EvalState & state, Env & env, Value & v) void ExprApp::eval(EvalState & state, Env & env, Value & v) { - e1->eval(state, env, v); - state.callFunction(v, *(e2->maybeThunk(state, env)), v); + /* FIXME: vFun prevents GCC from doing tail call optimisation. */ + Value vFun; + e1->eval(state, env, vFun); + state.callFunction(vFun, *(e2->maybeThunk(state, env)), v); }