(
txn: &T,
inode: Inode,
start: GraphNode<NodeId>,
target: GraphNode<NodeId>,
is_dead_in_view: &dyn Fn(GraphNode<NodeId>) -> bool,
)
| 789 | }; |
| 790 | |
| 791 | fn alive_reaches<T: GraphTxnT + InodeGraphOps>( |
| 792 | txn: &T, |
| 793 | inode: Inode, |
| 794 | start: GraphNode<NodeId>, |
| 795 | target: GraphNode<NodeId>, |
| 796 | is_dead_in_view: &dyn Fn(GraphNode<NodeId>) -> bool, |
| 797 | ) -> bool { |
| 798 | if start == target { |
| 799 | return true; |
| 800 | } |
| 801 | |
| 802 | let mut stack = vec![start]; |
| 803 | let mut seen = std::collections::HashSet::new(); |
| 804 | |
| 805 | while let Some(current) = stack.pop() { |
| 806 | if !seen.insert(current) { |
| 807 | continue; |
| 808 | } |
| 809 | |
| 810 | let edges = match txn.iter_forward(current, false) { |
| 811 | Ok(edges) => edges, |
| 812 | Err(_) => continue, |
| 813 | }; |
| 814 | |
| 815 | for edge in edges { |
| 816 | if edge.kind.is_pseudo() { |
| 817 | continue; |
| 818 | } |
| 819 | let dest = txn |
| 820 | .find_block_in_inode(inode, edge.dest) |
| 821 | .ok() |
| 822 | .flatten() |
| 823 | .or_else(|| txn.find_block(edge.dest).ok()); |
| 824 | let Some(dest) = dest else { |
| 825 | continue; |
| 826 | }; |
| 827 | if is_dead_in_view(dest) { |
| 828 | continue; |
| 829 | } |
| 830 | if dest == target { |
| 831 | return true; |
| 832 | } |
| 833 | stack.push(dest); |
| 834 | } |
| 835 | } |
| 836 | |
| 837 | false |
| 838 | } |
| 839 | |
| 840 | loop { |
| 841 | if !visited.insert(current) { |
no test coverage detected