a59236ffb4
[`map_unwrap_or`]: don't lint when referenced variable is moved Fixes #10579. The previous way of checking if changing `map(f).unwrap_or(a)` to `map_or(a, f)` is safe had a flaw when the argument to `unwrap_or` moves a binding and the `map` closure references that binding in some way. It used to simply check if any of the identifiers in the `unwrap_or` argument are referenced in the `map` closure, but it didn't consider the case where the moved binding is referred to through references, for example: ```rs let x = vec![1, 2]; let x_ref = &x; Some(()).map(|_| x_ref.clone()).unwrap_or(x); ``` This compiles as is, but we cannot change it to `map_or`. This lint however did suggest changing it, because the simple way of checking if `x` is referenced anywhere in the `map` closure fails here. The safest thing to do here imo (what this PR does) is check if the moved value `x` is referenced *anywhere* in the body (before the `unwrap_or` call). One can always create a reference to the value and smuggle them into the closure, without actually referring to `x`. The original, linked issue shows another one such example: ```rs let x = vec![1,2,3,0]; let y = x.strip_suffix(&[0]).map(|s| s.to_vec()).unwrap_or(x); ``` `x.strip_suffix(&[0])` creates a reference to `x` that is available through `s` inside of the `map` closure, so we can't change it to `map_or`. changelog: [`map_unwrap_or`]: don't lint when referenced variable is moved