Repository: MystenLabs/sui
File: external-crates/move/crates/move-decompiler/src/structuring/mod.rs (Rust)

Code before:
    loop_nodes_iter.sort();

    let mut loop_body = vec![];

    let succ_node = succ_nodes.into_iter().next();
    for node in loop_nodes_iter.into_iter().rev() {
        let Some(node) = structured_blocks.remove(&node) else {
            continue;
        };
        let result = insert_breaks(&loop_nodes, loop_head, succ_node, node, graph);
        loop_body.push(result);
    }

    let loop_body = loop_body.into_iter().rev().collect::<Vec<_>>();
    let seq = D::Structured::Seq(loop_body);
    graph.update_loop_info(loop_head);
    let mut result = D::Structured::Loop(Box::new(seq));
    if let Some(succ_node) = succ_node
        && graph
            .dom_tree
            .get(loop_head)
            .all_children()
            .any(|child| child == succ_node)
        && let Some(succ_structured) = structured_blocks.remove(&succ_node)
    {
        result = D::Structured::Seq(vec![result, succ_structured]);
    }
    structured_blocks.insert(loop_head, result);
}

fn insert_breaks(
    loop_nodes: &HashSet<NodeIndex>,
    loop_head: NodeIndex,
    succ_node: Option<NodeIndex>,
    node: D::Structured,
    graph: &Graph,
) -> D::Structured {
    use D::Structured as DS;

    enum LatchKind {
        Continue,
        Break,
        InLoop,
        OtherLoop,
        Latch,
    }

    fn find_latch_kind(
        loop_nodes: &HashSet<NodeIndex>,
        loop_head: NodeIndex,
        succ_node: Option<NodeIndex>,

Review comment (bug):
Perhaps something like this?

```suggestion
{
        let Some(succ_structured) = structured_blocks.remove(&succ_node) else { 
             if config.debug_print.structuring {
                 println!("failed to find structure node {succ_node}");
             }
             continue;
        }
        result = D::Structured::Seq(vec![result, succ_structured]);
```

Code after:
    loop_nodes_iter.sort();

    let mut loop_body = vec![];

    let succ_node = succ_nodes.into_iter().next();
    for node in loop_nodes_iter.into_iter().rev() {
        let Some(node) = structured_blocks.remove(&node) else {
            continue;
        };
        let result = insert_breaks(&loop_nodes, loop_head, succ_node, node, graph);
        loop_body.push(result);
    }

    let loop_body = loop_body.into_iter().rev().collect::<Vec<_>>();
    let seq = D::Structured::Seq(loop_body);
    graph.update_loop_info(loop_head);
    let mut result = D::Structured::Loop(Box::new(seq));
    if let Some(succ_node) = succ_node
        && graph
            .dom_tree
            .get(loop_head)
            .all_children()
            .any(|child| child == succ_node)
    {
        if let Some(succ_structured) = structured_blocks.remove(&succ_node) {
            result = D::Structured::Seq(vec![result, succ_structured]);
        } else if config.debug_print.structuring {
            println!("  failed to find successor node {succ_node:?} in structured blocks");
        }
    }
    structured_blocks.insert(loop_head, result);
}

fn insert_breaks(
    loop_nodes: &HashSet<NodeIndex>,
    loop_head: NodeIndex,
    succ_node: Option<NodeIndex>,
    node: D::Structured,
    graph: &Graph,
) -> D::Structured {
    use D::Structured as DS;

    enum LatchKind {
        Continue,
        Break,
        InLoop,
        OtherLoop,
        Latch,
    }

    fn find_latch_kind(