fn passable_preconditions(cfg: &Cfg, node: Index) -> Dnf {
        match &cfg[node].expr {
            // Trivially, `Send`, `Recv`, and `Call(None)` nodes are passable. We also assume that
            // for any `Type` node, the external type it references is passable, and that for any
            // `Error` node, assuming it passable will give the most possible relevant errors
            // reported.
            Ir::Send(_) | Ir::Recv(_) | Ir::Type(_) | Ir::Error | Ir::Call(None) => {
                Dnf::trivially_true()
            }
            // Trivially, `Break` and `Continue` nodes are never passable, because they always jump
            // and never call their continuations.
            Ir::Break(_) | Ir::Continue(_) => Dnf::trivially_false(),
            // `Call` nodes are only passable if their continuations are haltable.
            Ir::Call(Some(callee)) => Dnf::only_if(vec![Constraint::Haltable(*callee)]),
            // Similarly to call, split nodes are only passable if both arms are haltable.
            Ir::Split { tx_only, rx_only } => {
                let arms = tx_only.iter().chain(rx_only);
                Dnf::only_if(arms.map(|&arm| Constraint::Haltable(arm)).collect())
            }
            // `Offer` and `Choose` nodes are passable if any arm is passable; however, the
            // passability of an `Offer` or `Choose` typically does not matter because as control
            // flow analysis must be run after scope resolution, they should not have an implicit
            // continuation.
            Ir::Offer(choices) | Ir::Choose(choices) => Dnf(choices
                .iter()
                .filter_map(Option::as_ref)
                .map(|&c| vec![Constraint::Passable(c)])
                .collect()),
            // The `Loop` case is the most complex case here. A `Loop` only has its continuation
            // called when a `Break` occurs targeting the loop in question, so it is only passable
            // if it is `BreakableTo` from some node inside it.
            Ir::Loop(body) => Dnf::only_if(vec![Constraint::BreakableTo {
                breaks_from: body
                    .expect("loop bodies should always be `Some` after scope resolution"),
                breaks_to: node,
            }]),
        }
    }
/// Compute the preconditions for a `Passable` constraint.
Compute the preconditions for a `Passable` constraint.
Compute the preconditions for a ` Passable ` constraint .
fn passable_preconditions(cfg: &Cfg, node: Index) -> Dnf {
        match &cfg[node].expr {
            // Trivially, `Send`, `Recv`, and `Call(None)` nodes are passable. We also assume that
            // for any `Type` node, the external type it references is passable, and that for any
            // `Error` node, assuming it passable will give the most possible relevant errors
            // reported.
            Ir::Send(_) | Ir::Recv(_) | Ir::Type(_) | Ir::Error | Ir::Call(None) => {
                Dnf::trivially_true()
            }
            // Trivially, `Break` and `Continue` nodes are never passable, because they always jump
            // and never call their continuations.
            Ir::Break(_) | Ir::Continue(_) => Dnf::trivially_false(),
            // `Call` nodes are only passable if their continuations are haltable.
            Ir::Call(Some(callee)) => Dnf::only_if(vec![Constraint::Haltable(*callee)]),
            // Similarly to call, split nodes are only passable if both arms are haltable.
            Ir::Split { tx_only, rx_only } => {
                let arms = tx_only.iter().chain(rx_only);
                Dnf::only_if(arms.map(|&arm| Constraint::Haltable(arm)).collect())
            }
            // `Offer` and `Choose` nodes are passable if any arm is passable; however, the
            // passability of an `Offer` or `Choose` typically does not matter because as control
            // flow analysis must be run after scope resolution, they should not have an implicit
            // continuation.
            Ir::Offer(choices) | Ir::Choose(choices) => Dnf(choices
                .iter()
                .filter_map(Option::as_ref)
                .map(|&c| vec![Constraint::Passable(c)])
                .collect()),
            // The `Loop` case is the most complex case here. A `Loop` only has its continuation
            // called when a `Break` occurs targeting the loop in question, so it is only passable
            // if it is `BreakableTo` from some node inside it.
            Ir::Loop(body) => Dnf::only_if(vec![Constraint::BreakableTo {
                breaks_from: body
                    .expect("loop bodies should always be `Some` after scope resolution"),
                breaks_to: node,
            }]),
        }
    }
fn passable_preconditions ( cfg : & Cfg , node : Index ) -> Dnf { match & cfg [ node ] . expr { // Trivially, `Send`, `Recv`, and `Call(None)` nodes are passable. We also assume that // for any `Type` node, the external type it references is passable, and that for any // `Error` node, assuming it passable will give the most possible relevant errors // reported. Ir :: Send ( _ ) | Ir :: Recv ( _ ) | Ir :: Type ( _ ) | Ir :: Error | Ir :: Call ( None ) => { Dnf :: trivially_true ( ) } // Trivially, `Break` and `Continue` nodes are never passable, because they always jump // and never call their continuations. Ir :: Break ( _ ) | Ir :: Continue ( _ ) => Dnf :: trivially_false ( ) , // `Call` nodes are only passable if their continuations are haltable. Ir :: Call ( Some ( callee ) ) => Dnf :: only_if ( vec ! [ Constraint Haltable ( callee ) ] ) , // Similarly to call, split nodes are only passable if both arms are haltable. Ir :: Split { tx_only , rx_only } => { let arms = tx_only . iter ( ) . chain ( rx_only ) ; Dnf :: only_if ( arms . map ( | & arm | Constraint :: Haltable ( arm ) ) . collect ( ) ) } // `Offer` and `Choose` nodes are passable if any arm is passable; however, the // passability of an `Offer` or `Choose` typically does not matter because as control // flow analysis must be run after scope resolution, they should not have an implicit // continuation. Ir :: Offer ( choices ) | Ir :: Choose ( choices ) => Dnf ( choices . iter ( ) . filter_map ( Option :: as_ref ) . map ( | & c | vec ! [ Constraint Passable ( c ) ] ) . collect ( ) ) , // The `Loop` case is the most complex case here. A `Loop` only has its continuation // called when a `Break` occurs targeting the loop in question, so it is only passable // if it is `BreakableTo` from some node inside it. Ir :: Loop ( body ) => Dnf :: only_if ( vec ! [ Constraint BreakableTo { breaks_from body expect ( " " ) breaks_to node } ] ) , } }
Compute the preconditions for a `Passable` constraint.
Compute the preconditions for a ` Passable ` constraint .
cfg
&Cfg
node
Index