about summary refs log tree commit diff
path: root/clippy_lints/src/lib.rs
diff options
context:
space:
mode:
authorPhil Hansch <dev@phansch.net>2019-10-04 08:08:58 +0200
committerGitHub <noreply@github.com>2019-10-04 08:08:58 +0200
commit8d2912ec00a42698e44db924495bcc30a090ee2b (patch)
treef5fd4950c2ae59975eff323e6191578a74564e12 /clippy_lints/src/lib.rs
parentb824f021d61ddee59695f20c7128c39d80e9e5b6 (diff)
parent4cded6d9012bbfc77d13c7ef2a413402199a2a03 (diff)
downloadrust-8d2912ec00a42698e44db924495bcc30a090ee2b.tar.gz
rust-8d2912ec00a42698e44db924495bcc30a090ee2b.zip
Rollup merge of #4509 - sinkuu:redundant_clone_fix, r=llogiq
Fix false-positive of redundant_clone and move to clippy::perf

This PR introduces dataflow analysis to `redundant_clone` lint to filter out borrowed variables, which had been incorrectly detected.

Depends on https://github.com/rust-lang/rust/pull/64207.

changelog: Moved `redundant_clone` lint to `perf` group

# What this lint catches

## `clone`/`to_owned`

```rust
let s = String::new();
let t = s.clone();
```

```rust
// MIR
_1 = String::new();
_2 = &_1;
_3 = clone(_2); // (*)
```

We can turn this `clone` call into a move if

1. `_2` is the sole borrow of `_1` at the statement `(*)`
2. `_1` is not used hereafter

## `Deref` + type-specific `to_owned` method

```rust
let s = std::path::PathBuf::new();
let t = s.to_path_buf();
```

```rust
// MIR
_1 = PathBuf::new();
_2 = &1;
_3 = call deref(_2);
_4 = _3;                         // Copies borrow
StorageDead(_2);
_5 = Path::to_path_buf(_4); // (*)
```

We can turn this `to_path_buf` call into a move if

1. `_3` `_4` are the sole borrow of `_1` at `(*)`
2. `_1` is not used hereafter

# What this PR introduces

1. `MaybeStorageLive` that determines whether a local lives at a particular location
2. `PossibleBorrowerVisitor` that constructs [`TransitiveRelation`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/transitive_relation/struct.TransitiveRelation.html) of possible borrows, e.g. visiting `_2 = &1; _3 = &_2:` will result in `_3 -> _2 -> _1` relation. Then `_3` and `_2` will be counted as possible borrowers of `_1` in the sole-borrow analysis above.
Diffstat (limited to 'clippy_lints/src/lib.rs')
-rw-r--r--clippy_lints/src/lib.rs5
1 files changed, 4 insertions, 1 deletions
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 10a14f3b906..490f47424b1 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -27,6 +27,8 @@ extern crate rustc_driver;
 #[allow(unused_extern_crates)]
 extern crate rustc_errors;
 #[allow(unused_extern_crates)]
+extern crate rustc_index;
+#[allow(unused_extern_crates)]
 extern crate rustc_mir;
 #[allow(unused_extern_crates)]
 extern crate rustc_target;
@@ -864,6 +866,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
         ranges::RANGE_MINUS_ONE,
         ranges::RANGE_PLUS_ONE,
         ranges::RANGE_ZIP_WITH_LEN,
+        redundant_clone::REDUNDANT_CLONE,
         redundant_field_names::REDUNDANT_FIELD_NAMES,
         redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING,
         redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
@@ -1169,6 +1172,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
         methods::SINGLE_CHAR_PATTERN,
         misc::CMP_OWNED,
         mutex_atomic::MUTEX_ATOMIC,
+        redundant_clone::REDUNDANT_CLONE,
         slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
         trivially_copy_pass_by_ref::TRIVIALLY_COPY_PASS_BY_REF,
         types::BOX_VEC,
@@ -1188,7 +1192,6 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
         mutex_atomic::MUTEX_INTEGER,
         needless_borrow::NEEDLESS_BORROW,
         path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE,
-        redundant_clone::REDUNDANT_CLONE,
     ]);
 }