pub fn can_move_expr_to_closure_no_visit<'tcx>(
    cx: &LateContext<'tcx>,
    expr: &'tcx Expr<'_>,
    loop_ids: &[HirId],
    ignore_locals: &HirIdSet
) -> bool
Expand description

Checks if the top level expression can be moved into a closure as is. Currently checks for:

  • Break/Continue outside the given loop HIR ids.
  • Yield/Return statements.
  • Inline assembly.
  • Usages of a field of a local where the type of the local can be partially moved.

For example, given the following function:

fn f<'a>(iter: &mut impl Iterator<Item = (usize, &'a mut String)>) {
    for item in iter {
        let s = item.1;
        if item.0 > 10 {
            continue;
        } else {
            s.clear();
        }
    }
}

When called on the expression item.0 this will return false unless the local item is in the ignore_locals set. The type (usize, &mut String) can have the second element moved, so it isn’t always safe to move into a closure when only a single field is needed.

When called on the continue expression this will return false unless the outer loop expression is in the loop_ids set.

Note that this check is not recursive, so passing the if expression will always return true even though sub-expressions might return false.