about summary refs log tree commit diff
path: root/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-14 09:48:22 +0000
committerbors <bors@rust-lang.org>2023-06-14 09:48:22 +0000
commita59236ffb433b292bcd4c7721f820280ccdbbcf6 (patch)
tree58666036e5c6b992dbdaf5bd56c80b28bde41673 /compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
parentb9b453748d5ee0c0c5f53f52d749dff1a8cd38da (diff)
parent9d58a426230b5b4200791b9bedee1b14cb971197 (diff)
downloadrust-a59236ffb433b292bcd4c7721f820280ccdbbcf6.tar.gz
rust-a59236ffb433b292bcd4c7721f820280ccdbbcf6.zip
Auto merge of #10919 - y21:issue10579, r=blyxyas,xFrednet
[`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
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp')
0 files changed, 0 insertions, 0 deletions