Better precedence case management + more tests
This commit is contained in:
parent
72b9ae2a10
commit
3c2bbcf00e
@ -1,6 +1,6 @@
|
|||||||
use crate::utils::{get_parent_expr, implements_trait, snippet, span_lint_and_sugg};
|
use crate::utils::{get_parent_expr, implements_trait, snippet, span_lint_and_sugg};
|
||||||
use if_chain::if_chain;
|
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_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind};
|
use rustc_hir::{Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
@ -51,9 +51,16 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
|
|||||||
if let ExprKind::MethodCall(..) = parent_expr.kind {
|
if let ExprKind::MethodCall(..) = parent_expr.kind {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Check for unary precedence
|
// Check for Expr that we don't want to be linted
|
||||||
if let ExprPrecedence::Unary = parent_expr.precedence() {
|
let precedence = parent_expr.precedence();
|
||||||
return;
|
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();
|
let name = method_name.ident.as_str();
|
||||||
|
@ -191,6 +191,7 @@ macro_rules! declare_clippy_lint {
|
|||||||
mod copy_iterator;
|
mod copy_iterator;
|
||||||
mod dbg_macro;
|
mod dbg_macro;
|
||||||
mod default_trait_access;
|
mod default_trait_access;
|
||||||
|
mod dereference;
|
||||||
mod derive;
|
mod derive;
|
||||||
mod doc;
|
mod doc;
|
||||||
mod double_comparison;
|
mod double_comparison;
|
||||||
|
@ -13,6 +13,15 @@ fn just_return(deref_str: &str) -> &str {
|
|||||||
deref_str
|
deref_str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CustomVec(Vec<u8>);
|
||||||
|
impl Deref for CustomVec {
|
||||||
|
type Target = Vec<u8>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Vec<u8> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a: &mut String = &mut String::from("foo");
|
let a: &mut String = &mut String::from("foo");
|
||||||
|
|
||||||
@ -45,6 +54,9 @@ fn main() {
|
|||||||
|
|
||||||
// following should not require linting
|
// following should not require linting
|
||||||
|
|
||||||
|
let cv = CustomVec(vec![0, 42]);
|
||||||
|
let c = cv.deref()[0];
|
||||||
|
|
||||||
let b: &str = &*a.deref();
|
let b: &str = &*a.deref();
|
||||||
|
|
||||||
let b: String = a.deref().clone();
|
let b: String = a.deref().clone();
|
||||||
|
@ -13,6 +13,15 @@ fn just_return(deref_str: &str) -> &str {
|
|||||||
deref_str
|
deref_str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CustomVec(Vec<u8>);
|
||||||
|
impl Deref for CustomVec {
|
||||||
|
type Target = Vec<u8>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Vec<u8> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a: &mut String = &mut String::from("foo");
|
let a: &mut String = &mut String::from("foo");
|
||||||
|
|
||||||
@ -45,6 +54,9 @@ fn main() {
|
|||||||
|
|
||||||
// following should not require linting
|
// following should not require linting
|
||||||
|
|
||||||
|
let cv = CustomVec(vec![0, 42]);
|
||||||
|
let c = cv.deref()[0];
|
||||||
|
|
||||||
let b: &str = &*a.deref();
|
let b: &str = &*a.deref();
|
||||||
|
|
||||||
let b: String = a.deref().clone();
|
let b: String = a.deref().clone();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:21:19
|
--> $DIR/dereference.rs:30:19
|
||||||
|
|
|
|
||||||
LL | let b: &str = a.deref();
|
LL | let b: &str = a.deref();
|
||||||
| ^^^^^^^^^ help: try this: `&*a`
|
| ^^^^^^^^^ help: try this: `&*a`
|
||||||
@ -7,61 +7,61 @@ LL | let b: &str = a.deref();
|
|||||||
= note: `-D clippy::explicit-deref-methods` implied by `-D warnings`
|
= note: `-D clippy::explicit-deref-methods` implied by `-D warnings`
|
||||||
|
|
||||||
error: explicit deref_mut method call
|
error: explicit deref_mut method call
|
||||||
--> $DIR/dereference.rs:23:23
|
--> $DIR/dereference.rs:32:23
|
||||||
|
|
|
|
||||||
LL | let b: &mut str = a.deref_mut();
|
LL | let b: &mut str = a.deref_mut();
|
||||||
| ^^^^^^^^^^^^^ help: try this: `&mut *a`
|
| ^^^^^^^^^^^^^ help: try this: `&mut *a`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:26:39
|
--> $DIR/dereference.rs:35:39
|
||||||
|
|
|
|
||||||
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
||||||
| ^^^^^^^^^ help: try this: `&*a`
|
| ^^^^^^^^^ help: try this: `&*a`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:26:50
|
--> $DIR/dereference.rs:35:50
|
||||||
|
|
|
|
||||||
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
||||||
| ^^^^^^^^^ help: try this: `&*a`
|
| ^^^^^^^^^ help: try this: `&*a`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:28:20
|
--> $DIR/dereference.rs:37:20
|
||||||
|
|
|
|
||||||
LL | println!("{}", a.deref());
|
LL | println!("{}", a.deref());
|
||||||
| ^^^^^^^^^ help: try this: `&*a`
|
| ^^^^^^^^^ help: try this: `&*a`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:31:11
|
--> $DIR/dereference.rs:40:11
|
||||||
|
|
|
|
||||||
LL | match a.deref() {
|
LL | match a.deref() {
|
||||||
| ^^^^^^^^^ help: try this: `&*a`
|
| ^^^^^^^^^ help: try this: `&*a`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:35:28
|
--> $DIR/dereference.rs:44:28
|
||||||
|
|
|
|
||||||
LL | let b: String = concat(a.deref());
|
LL | let b: String = concat(a.deref());
|
||||||
| ^^^^^^^^^ help: try this: `&*a`
|
| ^^^^^^^^^ help: try this: `&*a`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:37:13
|
--> $DIR/dereference.rs:46:13
|
||||||
|
|
|
|
||||||
LL | let b = just_return(a).deref();
|
LL | let b = just_return(a).deref();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*just_return(a)`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*just_return(a)`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:39:28
|
--> $DIR/dereference.rs:48:28
|
||||||
|
|
|
|
||||||
LL | let b: String = concat(just_return(a).deref());
|
LL | let b: String = concat(just_return(a).deref());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*just_return(a)`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*just_return(a)`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:41:19
|
--> $DIR/dereference.rs:50:19
|
||||||
|
|
|
|
||||||
LL | let b: &str = a.deref().deref();
|
LL | let b: &str = a.deref().deref();
|
||||||
| ^^^^^^^^^^^^^^^^^ help: try this: `&*a.deref()`
|
| ^^^^^^^^^^^^^^^^^ help: try this: `&*a.deref()`
|
||||||
|
|
||||||
error: explicit deref method call
|
error: explicit deref method call
|
||||||
--> $DIR/dereference.rs:44:13
|
--> $DIR/dereference.rs:53:13
|
||||||
|
|
|
|
||||||
LL | let b = opt_a.unwrap().deref();
|
LL | let b = opt_a.unwrap().deref();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*opt_a.unwrap()`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*opt_a.unwrap()`
|
||||||
|
Loading…
Reference in New Issue
Block a user