From: mcarton Date: Sat, 1 Oct 2016 20:18:17 +0000 (+0200) Subject: Implement more `hir` typed node comparison X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=3e009b9424d51997af0e7433404dc2f0381af76c;p=rust.git Implement more `hir` typed node comparison --- diff --git a/clippy_lints/src/utils/hir.rs b/clippy_lints/src/utils/hir.rs index 41b82f7203b..680994a6a23 100644 --- a/clippy_lints/src/utils/hir.rs +++ b/clippy_lints/src/utils/hir.rs @@ -37,8 +37,8 @@ pub fn eq_stmt(&self, left: &Stmt, right: &Stmt) -> bool { match (&left.node, &right.node) { (&StmtDecl(ref l, _), &StmtDecl(ref r, _)) => { if let (&DeclLocal(ref l), &DeclLocal(ref r)) = (&l.node, &r.node) { - // TODO: tys - l.ty.is_none() && r.ty.is_none() && both(&l.init, &r.init, |l, r| self.eq_expr(l, r)) + both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && + both(&l.init, &r.init, |l, r| self.eq_expr(l, r)) } else { false } @@ -106,8 +106,8 @@ pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool { } (&ExprMethodCall(ref l_name, ref l_tys, ref l_args), &ExprMethodCall(ref r_name, ref r_tys, ref r_args)) => { - // TODO: tys - !self.ignore_fn && l_name.node == r_name.node && l_tys.is_empty() && r_tys.is_empty() && + !self.ignore_fn && l_name.node == r_name.node && + over(l_tys, r_tys, |l, r| self.eq_ty(l, r)) && self.eq_exprs(l_args, r_args) } (&ExprRepeat(ref le, ref ll), &ExprRepeat(ref re, ref rl)) => self.eq_expr(le, re) && self.eq_expr(ll, rl), @@ -138,6 +138,10 @@ fn eq_field(&self, left: &Field, right: &Field) -> bool { left.name.node == right.name.node && self.eq_expr(&left.expr, &right.expr) } + fn eq_lifetime(&self, left: &Lifetime, right: &Lifetime) -> bool { + left.name == right.name + } + /// Check whether two patterns are the same. pub fn eq_pat(&self, left: &Pat, right: &Pat) -> bool { match (&left.node, &right.node) { @@ -169,12 +173,33 @@ pub fn eq_pat(&self, left: &Pat, right: &Pat) -> bool { } fn eq_path(&self, left: &Path, right: &Path) -> bool { + left.global == right.global && + over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r)) + } + + fn eq_path_parameters(&self, left: &PathParameters, right: &PathParameters) -> bool { + match (left, right) { + (&AngleBracketedParameters(ref left), &AngleBracketedParameters(ref right)) => { + over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r)) && + over(&left.types, &right.types, |l, r| self.eq_ty(l, r)) && + over(&left.bindings, &right.bindings, |l, r| self.eq_type_binding(l, r)) + } + (&ParenthesizedParameters(ref left), &ParenthesizedParameters(ref right)) => { + over(&left.inputs, &right.inputs, |l, r| self.eq_ty(l, r)) && + both(&left.output, &right.output, |l, r| self.eq_ty(l, r)) + } + (&AngleBracketedParameters(_), &ParenthesizedParameters(_)) | + (&ParenthesizedParameters(_), &AngleBracketedParameters(_)) => { + false + } + } + } + + fn eq_path_segment(&self, left: &PathSegment, right: &PathSegment) -> bool { // The == of idents doesn't work with different contexts, // we have to be explicit about hygiene - left.global == right.global && - over(&left.segments, - &right.segments, - |l, r| l.name.as_str() == r.name.as_str() && l.parameters == r.parameters) + left.name.as_str() == right.name.as_str() && + self.eq_path_parameters(&left.parameters, &right.parameters) } fn eq_qself(&self, left: &QSelf, right: &QSelf) -> bool { @@ -199,6 +224,10 @@ fn eq_ty(&self, left: &Ty, right: &Ty) -> bool { _ => false, } } + + fn eq_type_binding(&self, left: &TypeBinding, right: &TypeBinding) -> bool { + left.name == right.name && self.eq_ty(&left.ty, &right.ty) + } } fn swap_binop<'a>(binop: BinOp_, lhs: &'a Expr, rhs: &'a Expr) -> Option<(BinOp_, &'a Expr, &'a Expr)> {