about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThibsG <Thibs@debian.com>2020-03-21 19:34:56 +0100
committerThibsG <Thibs@debian.com>2020-04-15 17:18:12 +0200
commit3c2bbcf00e3b97ab1fb03665b4afc7b7df0cd25e (patch)
tree6ead91ce99eb41874c9d38f155e29110f1d6691a
parent72b9ae2a10b13a209f09c5ace0a7b9763b740e62 (diff)
downloadrust-3c2bbcf00e3b97ab1fb03665b4afc7b7df0cd25e.tar.gz
rust-3c2bbcf00e3b97ab1fb03665b4afc7b7df0cd25e.zip
Better precedence case management + more tests
-rw-r--r--clippy_lints/src/dereference.rs15
-rw-r--r--clippy_lints/src/lib.rs1
-rw-r--r--tests/ui/dereference.fixed12
-rw-r--r--tests/ui/dereference.rs12
-rw-r--r--tests/ui/dereference.stderr22
5 files changed, 47 insertions, 15 deletions
diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs
index f5d82c54916..68ec07e2bcb 100644
--- a/clippy_lints/src/dereference.rs
+++ b/clippy_lints/src/dereference.rs
@@ -1,6 +1,6 @@
 use crate::utils::{get_parent_expr, implements_trait, snippet, span_lint_and_sugg};
 use if_chain::if_chain;
-use rustc_ast::util::parser::ExprPrecedence;
+use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX, PREC_PREFIX};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -51,9 +51,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Dereferencing {
                     if let ExprKind::MethodCall(..) = parent_expr.kind {
                         return;
                     }
-                    // Check for unary precedence
-                    if let ExprPrecedence::Unary = parent_expr.precedence() {
-                        return;
+                    // Check for Expr that we don't want to be linted
+                    let precedence = parent_expr.precedence();
+                    match precedence {
+                        // Lint a Call is ok though
+                        ExprPrecedence::Call | ExprPrecedence::AddrOf => (),
+                        _ => {
+                            if precedence.order() >= PREC_PREFIX && precedence.order() <= PREC_POSTFIX {
+                                return;
+                            }
+                        }
                     }
                 }
                 let name = method_name.ident.as_str();
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index b6b6a0e7d21..de1bab3a0b9 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -191,6 +191,7 @@ mod copies;
 mod copy_iterator;
 mod dbg_macro;
 mod default_trait_access;
+mod dereference;
 mod derive;
 mod doc;
 mod double_comparison;
diff --git a/tests/ui/dereference.fixed b/tests/ui/dereference.fixed
index 51e3d512cdb..459ca91b93b 100644
--- a/tests/ui/dereference.fixed
+++ b/tests/ui/dereference.fixed
@@ -13,6 +13,15 @@ fn just_return(deref_str: &str) -> &str {
     deref_str
 }
 
+struct CustomVec(Vec<u8>);
+impl Deref for CustomVec {
+    type Target = Vec<u8>;
+
+    fn deref(&self) -> &Vec<u8> {
+        &self.0
+    }
+}
+
 fn main() {
     let a: &mut String = &mut String::from("foo");
 
@@ -45,6 +54,9 @@ fn main() {
 
     // following should not require linting
 
+    let cv = CustomVec(vec![0, 42]);
+    let c = cv.deref()[0];
+
     let b: &str = &*a.deref();
 
     let b: String = a.deref().clone();
diff --git a/tests/ui/dereference.rs b/tests/ui/dereference.rs
index 3a595337411..8dc5272e67f 100644
--- a/tests/ui/dereference.rs
+++ b/tests/ui/dereference.rs
@@ -13,6 +13,15 @@ fn just_return(deref_str: &str) -> &str {
     deref_str
 }
 
+struct CustomVec(Vec<u8>);
+impl Deref for CustomVec {
+    type Target = Vec<u8>;
+
+    fn deref(&self) -> &Vec<u8> {
+        &self.0
+    }
+}
+
 fn main() {
     let a: &mut String = &mut String::from("foo");
 
@@ -45,6 +54,9 @@ fn main() {
 
     // following should not require linting
 
+    let cv = CustomVec(vec![0, 42]);
+    let c = cv.deref()[0];
+
     let b: &str = &*a.deref();
 
     let b: String = a.deref().clone();
diff --git a/tests/ui/dereference.stderr b/tests/ui/dereference.stderr
index d159214db2f..d26b462a433 100644
--- a/tests/ui/dereference.stderr
+++ b/tests/ui/dereference.stderr
@@ -1,5 +1,5 @@
 error: explicit deref method call
-  --> $DIR/dereference.rs:21:19
+  --> $DIR/dereference.rs:30:19
    |
 LL |     let b: &str = a.deref();
    |                   ^^^^^^^^^ help: try this: `&*a`
@@ -7,61 +7,61 @@ LL |     let b: &str = a.deref();
    = note: `-D clippy::explicit-deref-methods` implied by `-D warnings`
 
 error: explicit deref_mut method call
-  --> $DIR/dereference.rs:23:23
+  --> $DIR/dereference.rs:32:23
    |
 LL |     let b: &mut str = a.deref_mut();
    |                       ^^^^^^^^^^^^^ help: try this: `&mut *a`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:26:39
+  --> $DIR/dereference.rs:35:39
    |
 LL |     let b: String = format!("{}, {}", a.deref(), a.deref());
    |                                       ^^^^^^^^^ help: try this: `&*a`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:26:50
+  --> $DIR/dereference.rs:35:50
    |
 LL |     let b: String = format!("{}, {}", a.deref(), a.deref());
    |                                                  ^^^^^^^^^ help: try this: `&*a`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:28:20
+  --> $DIR/dereference.rs:37:20
    |
 LL |     println!("{}", a.deref());
    |                    ^^^^^^^^^ help: try this: `&*a`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:31:11
+  --> $DIR/dereference.rs:40:11
    |
 LL |     match a.deref() {
    |           ^^^^^^^^^ help: try this: `&*a`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:35:28
+  --> $DIR/dereference.rs:44:28
    |
 LL |     let b: String = concat(a.deref());
    |                            ^^^^^^^^^ help: try this: `&*a`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:37:13
+  --> $DIR/dereference.rs:46:13
    |
 LL |     let b = just_return(a).deref();
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*just_return(a)`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:39:28
+  --> $DIR/dereference.rs:48:28
    |
 LL |     let b: String = concat(just_return(a).deref());
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*just_return(a)`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:41:19
+  --> $DIR/dereference.rs:50:19
    |
 LL |     let b: &str = a.deref().deref();
    |                   ^^^^^^^^^^^^^^^^^ help: try this: `&*a.deref()`
 
 error: explicit deref method call
-  --> $DIR/dereference.rs:44:13
+  --> $DIR/dereference.rs:53:13
    |
 LL |     let b = opt_a.unwrap().deref();
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*opt_a.unwrap()`