Skip to content

Commit 849c2c0

Browse files
committed
Auto merge of #4066 - rust-lang:hash, r=Manishearth
Properly hash enums While I wrote this I was saved by a clippy lint... I accidentally fetched the discriminant of a reference to an enum and not of an enum. changelog: reduce hash collisions during clippy-internal hashing
2 parents 341c96a + b30c6dc commit 849c2c0

File tree

2 files changed

+12
-79
lines changed

2 files changed

+12
-79
lines changed

clippy_lints/src/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ impl Hash for Constant {
8282
where
8383
H: Hasher,
8484
{
85+
std::mem::discriminant(self).hash(state);
8586
match *self {
8687
Constant::Str(ref s) => {
8788
s.hash(state);

clippy_lints/src/utils/hir_utils.rs

Lines changed: 11 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -392,57 +392,49 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
392392

393393
#[allow(clippy::many_single_char_names, clippy::too_many_lines)]
394394
pub fn hash_expr(&mut self, e: &Expr) {
395-
if let Some(e) = constant_simple(self.cx, self.tables, e) {
395+
let simple_const = constant_simple(self.cx, self.tables, e);
396+
397+
// const hashing may result in the same hash as some unrelated node, so add a sort of
398+
// discriminant depending on which path we're choosing next
399+
simple_const.is_some().hash(&mut self.s);
400+
401+
if let Some(e) = simple_const {
396402
return e.hash(&mut self.s);
397403
}
398404

405+
std::mem::discriminant(&e.node).hash(&mut self.s);
406+
399407
match e.node {
400408
ExprKind::AddrOf(m, ref e) => {
401-
let c: fn(_, _) -> _ = ExprKind::AddrOf;
402-
c.hash(&mut self.s);
403409
m.hash(&mut self.s);
404410
self.hash_expr(e);
405411
},
406412
ExprKind::Continue(i) => {
407-
let c: fn(_) -> _ = ExprKind::Continue;
408-
c.hash(&mut self.s);
409413
if let Some(i) = i.label {
410414
self.hash_name(i.ident.name);
411415
}
412416
},
413417
ExprKind::Yield(ref e) => {
414-
let c: fn(_) -> _ = ExprKind::Yield;
415-
c.hash(&mut self.s);
416418
self.hash_expr(e);
417419
},
418420
ExprKind::Assign(ref l, ref r) => {
419-
let c: fn(_, _) -> _ = ExprKind::Assign;
420-
c.hash(&mut self.s);
421421
self.hash_expr(l);
422422
self.hash_expr(r);
423423
},
424424
ExprKind::AssignOp(ref o, ref l, ref r) => {
425-
let c: fn(_, _, _) -> _ = ExprKind::AssignOp;
426-
c.hash(&mut self.s);
427425
o.hash(&mut self.s);
428426
self.hash_expr(l);
429427
self.hash_expr(r);
430428
},
431429
ExprKind::Block(ref b, _) => {
432-
let c: fn(_, _) -> _ = ExprKind::Block;
433-
c.hash(&mut self.s);
434430
self.hash_block(b);
435431
},
436432
ExprKind::Binary(op, ref l, ref r) => {
437-
let c: fn(_, _, _) -> _ = ExprKind::Binary;
438-
c.hash(&mut self.s);
439433
op.node.hash(&mut self.s);
440434
self.hash_expr(l);
441435
self.hash_expr(r);
442436
},
443437
ExprKind::Break(i, ref j) => {
444-
let c: fn(_, _) -> _ = ExprKind::Break;
445-
c.hash(&mut self.s);
446438
if let Some(i) = i.label {
447439
self.hash_name(i.ident.name);
448440
}
@@ -451,25 +443,17 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
451443
}
452444
},
453445
ExprKind::Box(ref e) => {
454-
let c: fn(_) -> _ = ExprKind::Box;
455-
c.hash(&mut self.s);
456446
self.hash_expr(e);
457447
},
458448
ExprKind::Call(ref fun, ref args) => {
459-
let c: fn(_, _) -> _ = ExprKind::Call;
460-
c.hash(&mut self.s);
461449
self.hash_expr(fun);
462450
self.hash_exprs(args);
463451
},
464452
ExprKind::Cast(ref e, ref _ty) => {
465-
let c: fn(_, _) -> _ = ExprKind::Cast;
466-
c.hash(&mut self.s);
467453
self.hash_expr(e);
468454
// TODO: _ty
469455
},
470456
ExprKind::Closure(cap, _, eid, _, _) => {
471-
let c: fn(_, _, _, _, _) -> _ = ExprKind::Closure;
472-
c.hash(&mut self.s);
473457
match cap {
474458
CaptureClause::CaptureByValue => 0,
475459
CaptureClause::CaptureByRef => 1,
@@ -478,46 +462,31 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
478462
self.hash_expr(&self.cx.tcx.hir().body(eid).value);
479463
},
480464
ExprKind::Field(ref e, ref f) => {
481-
let c: fn(_, _) -> _ = ExprKind::Field;
482-
c.hash(&mut self.s);
483465
self.hash_expr(e);
484466
self.hash_name(f.name);
485467
},
486468
ExprKind::Index(ref a, ref i) => {
487-
let c: fn(_, _) -> _ = ExprKind::Index;
488-
c.hash(&mut self.s);
489469
self.hash_expr(a);
490470
self.hash_expr(i);
491471
},
492-
ExprKind::InlineAsm(..) => {
493-
let c: fn(_, _, _) -> _ = ExprKind::InlineAsm;
494-
c.hash(&mut self.s);
495-
},
472+
ExprKind::InlineAsm(..) => {},
496473
ExprKind::If(ref cond, ref t, ref e) => {
497-
let c: fn(_, _, _) -> _ = ExprKind::If;
498-
c.hash(&mut self.s);
499474
self.hash_expr(cond);
500475
self.hash_expr(&**t);
501476
if let Some(ref e) = *e {
502477
self.hash_expr(e);
503478
}
504479
},
505480
ExprKind::Lit(ref l) => {
506-
let c: fn(_) -> _ = ExprKind::Lit;
507-
c.hash(&mut self.s);
508481
l.hash(&mut self.s);
509482
},
510483
ExprKind::Loop(ref b, ref i, _) => {
511-
let c: fn(_, _, _) -> _ = ExprKind::Loop;
512-
c.hash(&mut self.s);
513484
self.hash_block(b);
514485
if let Some(i) = *i {
515486
self.hash_name(i.ident.name);
516487
}
517488
},
518489
ExprKind::Match(ref e, ref arms, ref s) => {
519-
let c: fn(_, _, _) -> _ = ExprKind::Match;
520-
c.hash(&mut self.s);
521490
self.hash_expr(e);
522491

523492
for arm in arms {
@@ -531,36 +500,25 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
531500
s.hash(&mut self.s);
532501
},
533502
ExprKind::MethodCall(ref path, ref _tys, ref args) => {
534-
let c: fn(_, _, _) -> _ = ExprKind::MethodCall;
535-
c.hash(&mut self.s);
536503
self.hash_name(path.ident.name);
537504
self.hash_exprs(args);
538505
},
539506
ExprKind::Repeat(ref e, ref l_id) => {
540-
let c: fn(_, _) -> _ = ExprKind::Repeat;
541-
c.hash(&mut self.s);
542507
self.hash_expr(e);
543508
let full_table = self.tables;
544509
self.tables = self.cx.tcx.body_tables(l_id.body);
545510
self.hash_expr(&self.cx.tcx.hir().body(l_id.body).value);
546511
self.tables = full_table;
547512
},
548513
ExprKind::Ret(ref e) => {
549-
let c: fn(_) -> _ = ExprKind::Ret;
550-
c.hash(&mut self.s);
551514
if let Some(ref e) = *e {
552515
self.hash_expr(e);
553516
}
554517
},
555518
ExprKind::Path(ref qpath) => {
556-
let c: fn(_) -> _ = ExprKind::Path;
557-
c.hash(&mut self.s);
558519
self.hash_qpath(qpath);
559520
},
560521
ExprKind::Struct(ref path, ref fields, ref expr) => {
561-
let c: fn(_, _, _) -> _ = ExprKind::Struct;
562-
c.hash(&mut self.s);
563-
564522
self.hash_qpath(path);
565523

566524
for f in fields {
@@ -573,33 +531,20 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
573531
}
574532
},
575533
ExprKind::Tup(ref tup) => {
576-
let c: fn(_) -> _ = ExprKind::Tup;
577-
c.hash(&mut self.s);
578534
self.hash_exprs(tup);
579535
},
580536
ExprKind::Type(ref e, ref _ty) => {
581-
let c: fn(_, _) -> _ = ExprKind::Type;
582-
c.hash(&mut self.s);
583537
self.hash_expr(e);
584538
// TODO: _ty
585539
},
586540
ExprKind::Unary(lop, ref le) => {
587-
let c: fn(_, _) -> _ = ExprKind::Unary;
588-
c.hash(&mut self.s);
589-
590541
lop.hash(&mut self.s);
591542
self.hash_expr(le);
592543
},
593544
ExprKind::Array(ref v) => {
594-
let c: fn(_) -> _ = ExprKind::Array;
595-
c.hash(&mut self.s);
596-
597545
self.hash_exprs(v);
598546
},
599547
ExprKind::While(ref cond, ref b, l) => {
600-
let c: fn(_, _, _) -> _ = ExprKind::While;
601-
c.hash(&mut self.s);
602-
603548
self.hash_expr(cond);
604549
self.hash_block(b);
605550
if let Some(l) = l {
@@ -608,8 +553,6 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
608553
},
609554
ExprKind::Err => {},
610555
ExprKind::DropTemps(ref e) => {
611-
let c: fn(_) -> _ = ExprKind::DropTemps;
612-
c.hash(&mut self.s);
613556
self.hash_expr(e);
614557
},
615558
}
@@ -647,24 +590,15 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
647590
pub fn hash_stmt(&mut self, b: &Stmt) {
648591
match b.node {
649592
StmtKind::Local(ref local) => {
650-
let c: fn(_) -> _ = StmtKind::Local;
651-
c.hash(&mut self.s);
652593
if let Some(ref init) = local.init {
653594
self.hash_expr(init);
654595
}
655596
},
656-
StmtKind::Item(..) => {
657-
let c: fn(_) -> _ = StmtKind::Item;
658-
c.hash(&mut self.s);
659-
},
597+
StmtKind::Item(..) => {},
660598
StmtKind::Expr(ref expr) => {
661-
let c: fn(_) -> _ = StmtKind::Expr;
662-
c.hash(&mut self.s);
663599
self.hash_expr(expr);
664600
},
665601
StmtKind::Semi(ref expr) => {
666-
let c: fn(_) -> _ = StmtKind::Semi;
667-
c.hash(&mut self.s);
668602
self.hash_expr(expr);
669603
},
670604
}
@@ -673,8 +607,6 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
673607
pub fn hash_guard(&mut self, g: &Guard) {
674608
match g {
675609
Guard::If(ref expr) => {
676-
let c: fn(_) -> _ = Guard::If;
677-
c.hash(&mut self.s);
678610
self.hash_expr(expr);
679611
},
680612
}

0 commit comments

Comments
 (0)