diff --git a/crates/compiler/can/src/desugar.rs b/crates/compiler/can/src/desugar.rs index 8f274d4c96..c0b0341182 100644 --- a/crates/compiler/can/src/desugar.rs +++ b/crates/compiler/can/src/desugar.rs @@ -164,11 +164,6 @@ fn desugar_defs_node_suffixed<'a>( "we have only one value_def and so it must be Suffixed " ); - dbg!( - "We have only one value_def and it must be Suffixed", - loc_expr.value - ); - // Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern( arena, @@ -212,11 +207,6 @@ fn desugar_defs_node_suffixed<'a>( "we know we have other Defs that will need to be considered" ); - dbg!( - "We have a Suffixed in first index, and also other nodes in Defs", - loc_expr.value - ); - // Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern( arena, @@ -270,17 +260,70 @@ fn desugar_defs_node_suffixed<'a>( )) } else { // The first Suffixed is in the middle of our Defs - // We will keep the value_defs before the Suffixed in our Defs node - // We take the value_defs after the Suffixed and create a new Defs node using the current loc_return + // We will keep the defs before the Suffixed in our Defs node + // We take the defs after the Suffixed and create a new Defs node using the current loc_return // Then recurse on the new Defs node, wrap the result in an Apply(Task.await) and Closure, // which will become the new loc_return - dbg!( - "The first Suffixed is in the middle of our Defs", - loc_expr.value + let (before, after) = defs.split_values_either_side_of(tag_index); + + // If there are no defs after, then just use loc_ret as we dont need a Defs node + let defs_after_suffixed_desugared = { + if after.len() > 0 { + desugar_defs_node_suffixed( + arena, + src, + line_info, + module_path, + arena.alloc(Loc::at( + loc_expr.region, + Defs(arena.alloc(after), loc_ret), + )), + ) + } else { + loc_ret + } + }; + + // Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await + let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern( + arena, + loc_expr.region, + defs.value_defs[value_index], ); - loc_expr + // Create Closure for the result of the recursion, + // use the pattern from our Suffixed Def as closure arument + let closure_expr = + Closure(arena.alloc([*pattern]), defs_after_suffixed_desugared); + + // Apply arguments to Task.await, first is the unwrapped Suffix expr second is the Closure + let mut task_await_apply_args: Vec<&'a Loc>> = Vec::new_in(arena); + + task_await_apply_args + .push(arena.alloc(Loc::at(loc_expr.region, suffixed_sub_apply_loc))); + task_await_apply_args + .push(arena.alloc(Loc::at(loc_expr.region, closure_expr))); + + let new_loc_return = arena.alloc(Loc::at( + loc_expr.region, + Apply( + arena.alloc(Loc { + region: loc_expr.region, + value: Var { + module_name: ModuleName::TASK, + ident: "await", + }, + }), + arena.alloc(task_await_apply_args), + CalledVia::Space, + ), + )); + + arena.alloc(Loc::at( + loc_expr.region, + Defs(arena.alloc(before), new_loc_return), + )) } } } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index f93aab38ce..8b8322beaf 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -503,38 +503,32 @@ impl<'a> Defs<'a> { .split() { Ok(type_index) => { - - let index = type_index.index(); + let index = type_index.index(); // remove from vec self.type_defs.remove(index); - // update all of the remaining indexes in type_defs + // update all of the remaining indexes in type_defs for (tag_index, tag) in self.tags.iter_mut().enumerate() { - // only update later indexes into type_defs if tag_index > index && tag.split().is_ok() { tag.decrement_index(); } } - } Err(value_index) => { - - let index: usize = value_index.index(); + let index: usize = value_index.index(); // remove from vec self.value_defs.remove(index); - // update all of the remaining indexes in value_defs + // update all of the remaining indexes in value_defs for (tag_index, tag) in self.tags.iter_mut().enumerate() { - // only update later indexes into value_defs if tag_index > index && tag.split().is_err() { tag.decrement_index(); } } - } } self.tags.remove(index); @@ -605,7 +599,7 @@ impl<'a> Defs<'a> { pub fn search_suffixed_defs(&self) -> Option<(usize, usize)> { for (tag_index, tag) in self.tags.iter().enumerate() { let index = match tag.split() { - Ok(_) => break, + Ok(_) => continue, Err(value_index) => value_index.index(), }; @@ -615,16 +609,33 @@ impl<'a> Defs<'a> { Expr::Suffixed(_) => { return Some((tag_index, index)); } - _ => break, + _ => continue, }, - _ => break, + _ => continue, }, - _ => break, + _ => continue, } } None } + + // For desugaring Suffixed Defs we need to split the defs around the Suffixed value + pub fn split_values_either_side_of(&self, index: usize) -> (Self, Self) { + let mut before = self.clone(); + let mut after = self.clone(); + + before.tags = self.tags[0..index].to_vec(); + + if index + 1 > self.tags.len() { + after.tags = self.tags.clone(); + after.tags.clear(); + } else { + after.tags = self.tags[(index + 1)..].to_vec(); + } + + (before, after) + } } /// Should always be a zero-argument `Apply`; we'll check this in canonicalization