From d171506fc7fc5e2add3daee7de0a5ddaaa43c8f1 Mon Sep 17 00:00:00 2001 From: Folkert Date: Thu, 28 Nov 2019 13:04:15 +0100 Subject: [PATCH] Only count a tail-call if it actually is one in e.g. case x of 0 -> 0 _ -> f ( x - 1) The old code would look at the first branch. it is not a tail call, so it concluded that the whole expression isn't. But the second branch is. --- src/can/mod.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/can/mod.rs b/src/can/mod.rs index 54e7262042..ec91e7cf15 100644 --- a/src/can/mod.rs +++ b/src/can/mod.rs @@ -841,9 +841,14 @@ fn canonicalize_case_branch<'a>( // If all branches are tail calling the same symbol, then so is the conditional as a whole. if !*recorded_tail_call { - // If we haven't recorded output.tail_call yet, record it. - output.tail_call = branch_output.tail_call; - *recorded_tail_call = true; + match branch_output.tail_call { + Some(call) => { + // If we haven't recorded output.tail_call yet, record it. + output.tail_call = Some(call); + *recorded_tail_call = true; + } + None => output.tail_call = None, + }; } else if branch_output.tail_call != output.tail_call { // If we recorded output.tail_call, but what we recorded differs from what we just saw, // then game over. This can't possibly be a self tail call! @@ -1506,7 +1511,7 @@ fn can_defs<'a>( ret_constraint: can_output.constraint.clone(), }))); - // see below: a closure needs a fresh References! + // see below: a closure needs a fresh References! let mut is_closure = false; match ( @@ -1532,7 +1537,11 @@ fn can_defs<'a>( let references = env.closures.remove(&symbol).unwrap_or_else(|| panic!("Tried to remove symbol {:?} from procedures, but it was not found: {:?}", symbol, env.closures)); - dbg!(loc_can_expr.clone(), can_output.tail_call.clone(), defined_symbol.clone()); + dbg!( + loc_can_expr.clone(), + can_output.tail_call.clone(), + defined_symbol.clone() + ); // The closure is self tail recursive iff it tail calls itself (by defined name). let is_recursive = if let Some(ref symbol) = can_output.tail_call { if symbol == defined_symbol { @@ -1578,7 +1587,6 @@ fn can_defs<'a>( // Functions' references don't count in defs. // See 3d5a2560057d7f25813112dfa5309956c0f9e6a9 and its // parent commit for the bug this fixed! - if is_closure { References::new() } else {