Skip to content

Commit

Permalink
Better precedence case management + more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibsG committed Mar 31, 2020
1 parent 165ea0b commit b79ddac
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.

[There are 363 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
[There are 364 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)

We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:

Expand Down
16 changes: 12 additions & 4 deletions clippy_lints/src/dereference.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -51,9 +51,17 @@ 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 => (), // | ExprPrecedence::MethodCall
_ => {
if precedence.order() >= PREC_PREFIX && precedence.order() <= PREC_POSTFIX {
// println!("Sup:\nexpr: {:#?}\nparent_expr: {:#?}\nprec: {:#?}", expr.span, parent_expr, precedence);
return;
}
}
}
}
let name = method_name.ident.as_str();
Expand Down
2 changes: 1 addition & 1 deletion src/lintlist/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use lint::Lint;
pub use lint::LINT_LEVELS;

// begin lint list, do not remove this comment, it’s used in `update_lints`
pub const ALL_LINTS: [Lint; 363] = [
pub const ALL_LINTS: [Lint; 364] = [
Lint {
name: "absurd_extreme_comparisons",
group: "correctness",
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/dereference.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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();
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/dereference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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();
Expand Down
22 changes: 11 additions & 11 deletions tests/ui/dereference.stderr
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
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`
|
= 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()`
Expand Down

0 comments on commit b79ddac

Please sign in to comment.