}
}
- match (&left.kind, &right.kind) {
+ match (&reduce_exprkind(&left.kind), &reduce_exprkind(&right.kind)) {
(&ExprKind::AddrOf(lb, l_mut, ref le), &ExprKind::AddrOf(rb, r_mut, ref re)) => {
lb == rb && l_mut == r_mut && self.eq_expr(le, re)
},
pub fn eq_path_segment(&mut self, left: &PathSegment<'_>, right: &PathSegment<'_>) -> bool {
// The == of idents doesn't work with different contexts,
// we have to be explicit about hygiene
- if left.ident.as_str() != right.ident.as_str() {
- return false;
- }
- match (&left.args, &right.args) {
- (&None, &None) => true,
- (&Some(ref l), &Some(ref r)) => self.eq_path_parameters(l, r),
- _ => false,
- }
+ left.ident.as_str() == right.ident.as_str()
+ && both(&left.args, &right.args, |l, r| self.eq_path_parameters(l, r))
}
pub fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {
}
}
+/// Some simple reductions like `{ return }` => `return`
+fn reduce_exprkind<'hir>(kind: &'hir ExprKind<'hir>) -> &ExprKind<'hir> {
+ if let ExprKind::Block(block, _) = kind {
+ match (block.stmts, block.expr) {
+ // `{}` => `()`
+ ([], None) => &ExprKind::Tup(&[]),
+ ([], Some(expr)) => match expr.kind {
+ // `{ return .. }` => `return ..`
+ ExprKind::Ret(..) => &expr.kind,
+ _ => kind,
+ },
+ ([stmt], None) => match stmt.kind {
+ StmtKind::Expr(expr) | StmtKind::Semi(expr) => match expr.kind {
+ // `{ return ..; }` => `return ..`
+ ExprKind::Ret(..) => &expr.kind,
+ _ => kind,
+ },
+ _ => kind,
+ },
+ _ => kind,
+ }
+ } else {
+ kind
+ }
+}
+
fn swap_binop<'a>(
binop: BinOpKind,
lhs: &'a Expr<'a>,
}
}
asm.options.hash(&mut self.s);
- for op in asm.operands {
+ for (op, _op_sp) in asm.operands {
match op {
InlineAsmOperand::In { reg, expr } => {
reg.hash(&mut self.s);