Skip to content

Commit

Permalink
Added partial_eq implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
xd009642 committed Mar 9, 2019
1 parent 5910dd6 commit b2b7914
Showing 1 changed file with 55 additions and 15 deletions.
70 changes: 55 additions & 15 deletions clippy_lints/src/trait_bounds.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
use crate::utils::{in_macro, span_lint};
use syntax::ast::*;
use rustc::lint::{EarlyLintPass, EarlyContext, LintArray, LintPass};
use core::hash::{Hash, Hasher};
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
use rustc::{declare_tool_lint, lint_array};
use rustc_data_structures::fx::FxHashSet;
use core::hash::{Hash, Hasher};
use syntax::ast::*;

declare_clippy_lint! {
pub TYPE_REPETITION_IN_BOUNDS,
complexity,
"Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`"
}


#[derive(Copy, Clone)]
pub struct TraitBounds;

impl LintPass for TraitBounds {
fn get_lints(&self) -> LintArray {
lint_array!(
TYPE_REPETITION_IN_BOUNDS
)
lint_array!(TYPE_REPETITION_IN_BOUNDS)
}

fn name(&self) -> &'static str {
Expand Down Expand Up @@ -55,16 +52,17 @@ impl<'ast> Hash for HashTy<'ast> {
HashTy(ty).hash(h);
}
},
Tup(ps) => for p in ps {
HashTy(p).hash(h);
Tup(ps) => {
for p in ps {
HashTy(p).hash(h);
}
},
Path(qs, p) => {
if let Some(q) = qs {
HashTy(&q.ty).hash(h);
}
},
TraitObject(b, os) => {
},
TraitObject(b, os) => {},
ImplTrait(t, o) => {},
Paren(p) => HashTy(p).hash(h),
_ => {},
Expand All @@ -74,21 +72,63 @@ impl<'ast> Hash for HashTy<'ast> {

impl<'ast> PartialEq for HashTy<'ast> {
fn eq(&self, other: &Self) -> bool {
unimplemented!()
use TyKind::*;

if std::mem::discriminant(&self.0.node) != std::mem::discriminant(&other.0.node) {
return false;
}
match (&self.0.node, &other.0.node) {
(Slice(p), Slice(q)) => HashTy(p).eq(&HashTy(q)),
(Array(p, len1), Array(q, len2)) => HashTy(p).eq(&HashTy(q)),
(Ptr(mt), Ptr(mt2)) => (mt.mutbl == mt2.mutbl) && HashTy(&mt.ty).eq(&HashTy(&mt2.ty)),
(Rptr(l, mt), Rptr(l2, mt2)) => mt.mutbl == mt2.mutbl && HashTy(&mt.ty).eq(&HashTy(&mt2.ty)),
(BareFn(p), BareFn(p2)) => {
if p.decl.inputs.len() != p2.decl.inputs.len() {
false
} else {
let arg_not_match = p
.decl
.inputs
.iter()
.zip(p2.decl.inputs.iter())
.any(|(a, b)| !HashTy(&a.ty).eq(&HashTy(&b.ty)));

let ret_type_match = match (&p.decl.output, &p2.decl.output) {
(&FunctionRetTy::Default(_), &FunctionRetTy::Default(_)) => true,
(&FunctionRetTy::Ty(ref t1), &FunctionRetTy::Ty(ref t2)) => HashTy(t1).eq(&HashTy(t2)),
_ => false,
};
!arg_not_match && ret_type_match
}
},
(Tup(p1), Tup(p2)) => {
p1.len() == p2.len() && p1.iter().zip(p2.iter()).all(|(a, b)| HashTy(a).eq(&HashTy(b)))
},
(Path(q1, _), Path(q2, _)) => {
if let (Some(a), Some(b)) = (q1, q2) {
HashTy(&a.ty).eq(&HashTy(&b.ty))
} else {
false
}
},
(TraitObject(_, _), TraitObject(_, _)) => true,
(ImplTrait(_, _), ImplTrait(_, _)) => true,
(Paren(p), Paren(q)) => HashTy(p).eq(&HashTy(q)),
_ => false,
}
}

fn ne(&self, other: &Self) -> bool {
unimplemented!()
!self.eq(other)
}
}

impl<'ast> Eq for HashTy<'ast> {}


impl EarlyLintPass for TraitBounds {
fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) {
if in_macro(gen.span) {
return
return;
}
let mut set = FxHashSet::default();
for bound in &gen.where_clause.predicates {
Expand Down

0 comments on commit b2b7914

Please sign in to comment.