diff options
| author | Oliver Schneider <oli-obk@users.noreply.github.com> | 2018-05-28 13:50:31 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-28 13:50:31 +0200 |
| commit | 0d1e06d638ccd369eb3fda74cc862de828877b4d (patch) | |
| tree | 9b457108cc996bf7acf7f6fb0775cb59ea3866b9 /clippy_lints/src | |
| parent | b979f62aab92b6ec242880e0dfa9c13161343881 (diff) | |
| parent | 8b679176fade98d8908f3950506f53b3a5b27910 (diff) | |
Merge pull request #2808 from Aaronepower/master
Added lint for unnecessary references.
Diffstat (limited to 'clippy_lints/src')
| -rw-r--r-- | clippy_lints/src/lib.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/reference.rs | 50 |
2 files changed, 52 insertions, 0 deletions
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index afbb3ba560a..05902614df7 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -388,6 +388,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box if_let_redundant_pattern_matching::Pass); reg.register_late_lint_pass(box partialeq_ne_impl::Pass); reg.register_early_lint_pass(box reference::Pass); + reg.register_early_lint_pass(box reference::DerefPass); reg.register_early_lint_pass(box double_parens::DoubleParens); reg.register_late_lint_pass(box unused_io_amount::UnusedIoAmount); reg.register_late_lint_pass(box large_enum_variant::LargeEnumVariant::new(conf.enum_variant_size_threshold)); @@ -809,6 +810,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { precedence::PRECEDENCE, ranges::RANGE_ZIP_WITH_LEN, reference::DEREF_ADDROF, + reference::REF_IN_DEREF, swap::MANUAL_SWAP, temporary_assignment::TEMPORARY_ASSIGNMENT, transmute::CROSSPOINTER_TRANSMUTE, diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index ffdb02216dc..4b173a58563 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -54,3 +54,53 @@ impl EarlyLintPass for Pass { } } } + +/// **What it does:** Checks for references in expressions that use +/// auto dereference. +/// +/// **Why is this bad?** The reference is a no-op and is automatically +/// dereferenced by the compiler and makes the code less clear. +/// +/// **Example:** +/// ```rust +/// struct Point(u32, u32); +/// let point = Foo(30, 20); +/// let x = (&point).x; +/// ``` +declare_clippy_lint! { + pub REF_IN_DEREF, + complexity, + "Use of reference in auto dereference expression." +} + +pub struct DerefPass; + +impl LintPass for DerefPass { + fn get_lints(&self) -> LintArray { + lint_array!(REF_IN_DEREF) + } +} + +impl EarlyLintPass for DerefPass { + fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) { + if_chain! { + if let ExprKind::Field(ref object, ref field_name) = e.node; + if let ExprKind::Paren(ref parened) = object.node; + if let ExprKind::AddrOf(_, ref inner) = parened.node; + then { + span_lint_and_sugg( + cx, + REF_IN_DEREF, + object.span, + "Creating a reference that is immediately dereferenced.", + "try this", + format!( + "{}.{}", + snippet(cx, inner.span, "_"), + snippet(cx, field_name.span, "_") + ) + ); + } + } + } +} |
