diff --git a/compiler/can/src/def.rs b/compiler/can/src/def.rs index c69719372b..f3c7cc4698 100644 --- a/compiler/can/src/def.rs +++ b/compiler/can/src/def.rs @@ -399,7 +399,7 @@ pub fn sort_can_defs( ) -> (Result, RuntimeError>, Output) { let CanDefs { refs_by_symbol, - can_defs_by_symbol, + mut can_defs_by_symbol, aliases, } = defs; @@ -583,7 +583,7 @@ pub fn sort_can_defs( &group, &env.closures, &mut all_successors_with_self, - &can_defs_by_symbol, + &mut can_defs_by_symbol, &mut declarations, ); } @@ -717,7 +717,7 @@ pub fn sort_can_defs( group, &env.closures, &mut all_successors_with_self, - &can_defs_by_symbol, + &mut can_defs_by_symbol, &mut declarations, ); } @@ -739,7 +739,7 @@ fn group_to_declaration( group: &[Symbol], closures: &MutMap, successors: &mut dyn FnMut(&Symbol) -> ImSet, - can_defs_by_symbol: &MutMap, + can_defs_by_symbol: &mut MutMap, declarations: &mut Vec, ) { use Declaration::*; @@ -765,51 +765,54 @@ fn group_to_declaration( if cycle.len() == 1 { let symbol = &cycle[0]; - if let Some(can_def) = can_defs_by_symbol.get(symbol) { - let mut new_def = can_def.clone(); - - // Determine recursivity of closures that are not tail-recursive - if let Closure(ClosureData { - recursive: recursive @ Recursive::NotRecursive, - .. - }) = &mut new_def.loc_expr.value - { - *recursive = closure_recursivity(*symbol, closures); - } - - let is_recursive = successors(symbol).contains(symbol); - - if !seen_pattern_regions.contains(&new_def.loc_pattern.region) { - if is_recursive { - declarations.push(DeclareRec(vec![new_def.clone()])); - } else { - declarations.push(Declare(new_def.clone())); - } - seen_pattern_regions.insert(new_def.loc_pattern.region); - } - } - } else { - let mut can_defs = Vec::new(); - - // Topological sort gives us the reverse of the sorting we want! - for symbol in cycle.into_iter().rev() { - if let Some(can_def) = can_defs_by_symbol.get(&symbol) { - let mut new_def = can_def.clone(); - + match can_defs_by_symbol.remove(symbol) { + Some(mut new_def) => { // Determine recursivity of closures that are not tail-recursive if let Closure(ClosureData { recursive: recursive @ Recursive::NotRecursive, .. }) = &mut new_def.loc_expr.value { - *recursive = closure_recursivity(symbol, closures); + *recursive = closure_recursivity(*symbol, closures); } + let is_recursive = successors(symbol).contains(symbol); + if !seen_pattern_regions.contains(&new_def.loc_pattern.region) { - can_defs.push(new_def.clone()); - } + seen_pattern_regions.insert(new_def.loc_pattern.region); - seen_pattern_regions.insert(new_def.loc_pattern.region); + if is_recursive { + declarations.push(DeclareRec(vec![new_def])); + } else { + declarations.push(Declare(new_def)); + } + } + } + None => roc_error_macros::internal_error!("def not available {:?}", symbol), + } + } else { + let mut can_defs = Vec::new(); + + // Topological sort gives us the reverse of the sorting we want! + for symbol in cycle.into_iter().rev() { + match can_defs_by_symbol.remove(&symbol) { + Some(mut new_def) => { + // Determine recursivity of closures that are not tail-recursive + if let Closure(ClosureData { + recursive: recursive @ Recursive::NotRecursive, + .. + }) = &mut new_def.loc_expr.value + { + *recursive = closure_recursivity(symbol, closures); + } + + seen_pattern_regions.insert(new_def.loc_pattern.region); + + if !seen_pattern_regions.contains(&new_def.loc_pattern.region) { + can_defs.push(new_def); + } + } + None => roc_error_macros::internal_error!("def not available {:?}", symbol), } }