Skip to content

Commit fe15880

Browse files
committed
Revert "down to for-loops not comparing as equal"
This reverts commit cf1fa94.
1 parent 42fb11f commit fe15880

File tree

2 files changed

+60
-41
lines changed

2 files changed

+60
-41
lines changed

clippy_lints/src/utils/hir.rs

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use consts::constant;
22
use rustc::lint::*;
33
use rustc::hir::*;
4-
use rustc::hir::def::Def;
54
use std::hash::{Hash, Hasher};
65
use std::collections::hash_map::DefaultHasher;
76
use syntax::ast::{Name, NodeId};
@@ -104,8 +103,8 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
104103
(&ExprLoop(ref lb, ref ll, _), &ExprLoop(ref rb, ref rl, _)) => {
105104
self.eq_block(lb, rb) && both(ll, rl, |l, r| l.node.as_str() == r.node.as_str())
106105
}
107-
(&ExprMatch(ref le, ref la, _), &ExprMatch(ref re, ref ra, _)) => {
108-
self.eq_expr(le, re) &&
106+
(&ExprMatch(ref le, ref la, ref ls), &ExprMatch(ref re, ref ra, ref rs)) => {
107+
ls == rs && self.eq_expr(le, re) &&
109108
over(la, ra, |l, r| {
110109
self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r)) &&
111110
over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r))
@@ -119,10 +118,9 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
119118
}
120119
(&ExprRepeat(ref le, ref ll), &ExprRepeat(ref re, ref rl)) => self.eq_expr(le, re) && self.eq_expr(ll, rl),
121120
(&ExprRet(ref l), &ExprRet(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
122-
(&ExprPath(ref l), &ExprPath(ref r)) => self.eq_qpath(l, left.id, r, right.id),
121+
(&ExprPath(ref l), &ExprPath(ref r)) => self.eq_qpath(l, r),
123122
(&ExprStruct(ref l_path, ref lf, ref lo), &ExprStruct(ref r_path, ref rf, ref ro)) => {
124-
self.eq_qpath(l_path, left.id, r_path, right.id) &&
125-
both(lo, ro, |l, r| self.eq_expr(l, r)) &&
123+
self.eq_qpath(l_path, r_path) && both(lo, ro, |l, r| self.eq_expr(l, r)) &&
126124
over(lf, rf, |l, r| self.eq_field(l, r))
127125
}
128126
(&ExprTup(ref l_tup), &ExprTup(ref r_tup)) => self.eq_exprs(l_tup, r_tup),
@@ -144,17 +142,21 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
144142
left.name.node == right.name.node && self.eq_expr(&left.expr, &right.expr)
145143
}
146144

145+
fn eq_lifetime(&self, left: &Lifetime, right: &Lifetime) -> bool {
146+
left.name == right.name
147+
}
148+
147149
/// Check whether two patterns are the same.
148150
pub fn eq_pat(&self, left: &Pat, right: &Pat) -> bool {
149151
match (&left.node, &right.node) {
150152
(&PatKind::Box(ref l), &PatKind::Box(ref r)) => self.eq_pat(l, r),
151153
(&PatKind::TupleStruct(ref lp, ref la, ls), &PatKind::TupleStruct(ref rp, ref ra, rs)) => {
152-
self.eq_qpath(lp, left.id, rp, right.id) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs
154+
self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs
153155
}
154-
(&PatKind::Binding(ref lb, _, ref li, ref lp), &PatKind::Binding(ref rb, _, ref ri, ref rp)) => {
155-
lb == rb && li.node.as_str() == ri.node.as_str() && both(lp, rp, |l, r| self.eq_pat(l, r))
156+
(&PatKind::Binding(ref lb, ref ld, ref li, ref lp), &PatKind::Binding(ref rb, ref rd, ref ri, ref rp)) => {
157+
lb == rb && ld == rd && li.node.as_str() == ri.node.as_str() && both(lp, rp, |l, r| self.eq_pat(l, r))
156158
}
157-
(&PatKind::Path(ref l), &PatKind::Path(ref r)) => self.eq_qpath(l, left.id, r, right.id),
159+
(&PatKind::Path(ref l), &PatKind::Path(ref r)) => self.eq_qpath(l, r),
158160
(&PatKind::Lit(ref l), &PatKind::Lit(ref r)) => self.eq_expr(l, r),
159161
(&PatKind::Tuple(ref l, ls), &PatKind::Tuple(ref r, rs)) => {
160162
ls == rs && over(l, r, |l, r| self.eq_pat(l, r))
@@ -172,23 +174,48 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
172174
}
173175
}
174176

175-
fn eq_qpath(&self, left: &QPath, lid: NodeId, right: &QPath, rid: NodeId) -> bool {
176-
let l = self.cx.tcx.tables().qpath_def(left, lid);
177-
let r = self.cx.tcx.tables().qpath_def(right, rid);
177+
fn eq_qpath(&self, left: &QPath, right: &QPath) -> bool {
178+
match (left, right) {
179+
(&QPath::Resolved(ref lty, ref lpath), &QPath::Resolved(ref rty, ref rpath)) => {
180+
both(lty, rty, |l, r| self.eq_ty(l, r)) && self.eq_path(lpath, rpath)
181+
},
182+
(&QPath::TypeRelative(ref lty, ref lseg), &QPath::TypeRelative(ref rty, ref rseg)) => {
183+
self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg)
184+
},
185+
_ => false,
186+
}
187+
}
188+
189+
fn eq_path(&self, left: &Path, right: &Path) -> bool {
190+
left.global == right.global &&
191+
over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r))
192+
}
178193

179-
if let (Def::Local(_), Def::Local(_)) = (l, r) {
180-
if let (&QPath::Resolved(None, ref l), &QPath::Resolved(None, ref r)) = (left, right) {
181-
assert_eq!(l.segments.len(), 1);
182-
assert_eq!(r.segments.len(), 1);
183-
l.segments[0].name == r.segments[0].name
184-
} else {
185-
unreachable!();
194+
fn eq_path_parameters(&self, left: &PathParameters, right: &PathParameters) -> bool {
195+
match (left, right) {
196+
(&AngleBracketedParameters(ref left), &AngleBracketedParameters(ref right)) => {
197+
over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r)) &&
198+
over(&left.types, &right.types, |l, r| self.eq_ty(l, r)) &&
199+
over(&left.bindings, &right.bindings, |l, r| self.eq_type_binding(l, r))
200+
}
201+
(&ParenthesizedParameters(ref left), &ParenthesizedParameters(ref right)) => {
202+
over(&left.inputs, &right.inputs, |l, r| self.eq_ty(l, r)) &&
203+
both(&left.output, &right.output, |l, r| self.eq_ty(l, r))
204+
}
205+
(&AngleBracketedParameters(_), &ParenthesizedParameters(_)) |
206+
(&ParenthesizedParameters(_), &AngleBracketedParameters(_)) => {
207+
false
186208
}
187-
} else {
188-
l == r
189209
}
190210
}
191211

212+
fn eq_path_segment(&self, left: &PathSegment, right: &PathSegment) -> bool {
213+
// The == of idents doesn't work with different contexts,
214+
// we have to be explicit about hygiene
215+
left.name.as_str() == right.name.as_str() &&
216+
self.eq_path_parameters(&left.parameters, &right.parameters)
217+
}
218+
192219
fn eq_ty(&self, left: &Ty, right: &Ty) -> bool {
193220
match (&left.node, &right.node) {
194221
(&TySlice(ref l_vec), &TySlice(ref r_vec)) => self.eq_ty(l_vec, r_vec),
@@ -199,12 +226,16 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
199226
(&TyRptr(_, ref l_rmut), &TyRptr(_, ref r_rmut)) => {
200227
l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(&*l_rmut.ty, &*r_rmut.ty)
201228
}
202-
(&TyPath(ref l), &TyPath(ref r)) => self.eq_qpath(l, left.id, r, right.id),
229+
(&TyPath(ref l), &TyPath(ref r)) => self.eq_qpath(l, r),
203230
(&TyTup(ref l), &TyTup(ref r)) => over(l, r, |l, r| self.eq_ty(l, r)),
204231
(&TyInfer, &TyInfer) => true,
205232
_ => false,
206233
}
207234
}
235+
236+
fn eq_type_binding(&self, left: &TypeBinding, right: &TypeBinding) -> bool {
237+
left.name == right.name && self.eq_ty(&left.ty, &right.ty)
238+
}
208239
}
209240

210241
fn swap_binop<'a>(binop: BinOp_, lhs: &'a Expr, rhs: &'a Expr) -> Option<(BinOp_, &'a Expr, &'a Expr)> {
@@ -388,7 +419,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
388419
self.hash_name(&i.node);
389420
}
390421
}
391-
ExprMatch(ref e, ref arms, _) => {
422+
ExprMatch(ref e, ref arms, ref s) => {
392423
let c: fn(_, _, _) -> _ = ExprMatch;
393424
c.hash(&mut self.s);
394425
self.hash_expr(e);
@@ -400,6 +431,8 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
400431
}
401432
self.hash_expr(&arm.body);
402433
}
434+
435+
s.hash(&mut self.s);
403436
}
404437
ExprMethodCall(ref name, ref _tys, ref args) => {
405438
let c: fn(_, _, _) -> _ = ExprMethodCall;
@@ -495,19 +528,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
495528
}
496529

497530
pub fn hash_qpath(&mut self, p: &QPath, id: NodeId) {
498-
let def = self.cx.tcx.tables().qpath_def(p, id);
499-
if let Def::Local(_) = def {
500-
true.hash(&mut self.s);
501-
if let QPath::Resolved(None, ref seq) = *p {
502-
assert_eq!(seq.segments.len(), 1);
503-
self.hash_name(&seq.segments[0].name);
504-
} else {
505-
unreachable!();
506-
}
507-
} else {
508-
false.hash(&mut self.s);
509-
def.hash(&mut self.s);
510-
}
531+
self.cx.tcx.tables().qpath_def(p, id).hash(&mut self.s);
511532
}
512533

513534
pub fn hash_path(&mut self, p: &Path) {

tests/compile-fail/copies.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,18 +224,16 @@ fn if_same_then_else() -> Result<&'static str, ()> {
224224
}
225225

226226
if true {
227-
//~^NOTE same as this
228227
if let Some(42) = None {}
229228
}
230-
else { //~ERROR this `if` has identical blocks
229+
else {
231230
if let Option::Some(42) = None {}
232231
}
233232

234233
if true {
235-
//~^NOTE same as this
236234
if let Some(42) = None::<u8> {}
237235
}
238-
else { //~ERROR this `if` has identical blocks
236+
else {
239237
if let Some(42) = None {}
240238
}
241239

0 commit comments

Comments
 (0)