Skip to content

Commit ea977a9

Browse files
committed
implement 'Re-implementing PartialEq::ne' lint
closes #86
1 parent 307abd7 commit ea977a9

File tree

5 files changed

+76
-1
lines changed

5 files changed

+76
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ All notable changes to this project will be documented in this file.
318318
[`out_of_bounds_indexing`]: https://github.com/Manishearth/rust-clippy/wiki#out_of_bounds_indexing
319319
[`overflow_check_conditional`]: https://github.com/Manishearth/rust-clippy/wiki#overflow_check_conditional
320320
[`panic_params`]: https://github.com/Manishearth/rust-clippy/wiki#panic_params
321+
[`partialeq_ne_impl`]: https://github.com/Manishearth/rust-clippy/wiki#partialeq_ne_impl
321322
[`precedence`]: https://github.com/Manishearth/rust-clippy/wiki#precedence
322323
[`print_stdout`]: https://github.com/Manishearth/rust-clippy/wiki#print_stdout
323324
[`print_with_newline`]: https://github.com/Manishearth/rust-clippy/wiki#print_with_newline

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ You can check out this great service at [clippy.bashy.io](https://clippy.bashy.i
174174

175175
## Lints
176176

177-
There are 174 lints included in this crate:
177+
There are 175 lints included in this crate:
178178

179179
name | default | triggers on
180180
---------------------------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------
@@ -292,6 +292,7 @@ name
292292
[out_of_bounds_indexing](https://github.com/Manishearth/rust-clippy/wiki#out_of_bounds_indexing) | deny | out of bounds constant indexing
293293
[overflow_check_conditional](https://github.com/Manishearth/rust-clippy/wiki#overflow_check_conditional) | warn | overflow checks inspired by C which are likely to panic
294294
[panic_params](https://github.com/Manishearth/rust-clippy/wiki#panic_params) | warn | missing parameters in `panic!` calls
295+
[partialeq_ne_impl](https://github.com/Manishearth/rust-clippy/wiki#partialeq_ne_impl) | warn | re-implementing PartialEq::ne
295296
[precedence](https://github.com/Manishearth/rust-clippy/wiki#precedence) | warn | operations where precedence may be unclear
296297
[print_stdout](https://github.com/Manishearth/rust-clippy/wiki#print_stdout) | allow | printing on stdout
297298
[print_with_newline](https://github.com/Manishearth/rust-clippy/wiki#print_with_newline) | warn | using `print!()` with a format string that ends in a newline

clippy_lints/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub mod ok_if_let;
110110
pub mod open_options;
111111
pub mod overflow_check_conditional;
112112
pub mod panic;
113+
pub mod partialeq_ne_impl;
113114
pub mod precedence;
114115
pub mod print;
115116
pub mod ptr;
@@ -257,6 +258,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
257258
reg.register_late_lint_pass(box eval_order_dependence::EvalOrderDependence);
258259
reg.register_late_lint_pass(box missing_doc::MissingDoc::new());
259260
reg.register_late_lint_pass(box ok_if_let::Pass);
261+
reg.register_late_lint_pass(box partialeq_ne_impl::Pass);
260262

261263
reg.register_lint_group("clippy_restrictions", vec![
262264
arithmetic::FLOAT_ARITHMETIC,
@@ -412,6 +414,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
412414
open_options::NONSENSICAL_OPEN_OPTIONS,
413415
overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
414416
panic::PANIC_PARAMS,
417+
partialeq_ne_impl::PARTIALEQ_NE_IMPL,
415418
precedence::PRECEDENCE,
416419
print::PRINT_WITH_NEWLINE,
417420
ptr::CMP_NULL,

clippy_lints/src/partialeq_ne_impl.rs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use rustc::lint::*;
2+
use rustc::hir::*;
3+
use utils::{is_automatically_derived, span_lint};
4+
5+
/// **What it does:** Checks for manual re-implementations of `PartialEq::ne`.
6+
///
7+
/// **Why is this bad?** `PartialEq::ne` is required to always return the
8+
/// negated result of `PartialEq::eq`, which is exactly what the default
9+
/// implementation does. Therefore, there should never be any need to
10+
/// re-implement it.
11+
///
12+
/// **Known problems:** None.
13+
///
14+
/// **Example:**
15+
/// ```rust
16+
/// struct Foo;
17+
///
18+
/// impl PartialEq for Foo {
19+
/// fn eq(&self, other: &Foo) -> bool { ... }
20+
/// fn ne(&self, other: &Foo) -> bool { !(self == other) }
21+
/// }
22+
/// ```
23+
declare_lint! {
24+
pub PARTIALEQ_NE_IMPL,
25+
Warn,
26+
"re-implementing PartialEq::ne"
27+
}
28+
29+
#[derive(Clone, Copy)]
30+
pub struct Pass;
31+
32+
impl LintPass for Pass {
33+
fn get_lints(&self) -> LintArray {
34+
lint_array!(PARTIALEQ_NE_IMPL)
35+
}
36+
}
37+
38+
impl LateLintPass for Pass {
39+
fn check_item(&mut self, cx: &LateContext, item: &Item) {
40+
if_let_chain! {[
41+
let ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) = item.node,
42+
!is_automatically_derived(&*item.attrs),
43+
cx.tcx.expect_def(trait_ref.ref_id).def_id() == cx.tcx.lang_items.eq_trait().unwrap(),
44+
], {
45+
for impl_item in impl_items {
46+
if &*impl_item.name.as_str() == "ne" {
47+
span_lint(cx,
48+
PARTIALEQ_NE_IMPL,
49+
impl_item.span,
50+
"Re-implementing `PartialEq::ne`")
51+
}
52+
}
53+
}};
54+
}
55+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(plugin)]
2+
#![plugin(clippy)]
3+
4+
#![deny(warnings)]
5+
#![allow(dead_code)]
6+
7+
struct Foo;
8+
9+
impl PartialEq for Foo {
10+
fn eq(&self, _: &Foo) -> bool { true }
11+
fn ne(&self, _: &Foo) -> bool { false }
12+
//~^ ERROR Re-implementing `PartialEq::ne`
13+
}
14+
15+
fn main() {}

0 commit comments

Comments
 (0)