use crate::differing_macro_contexts;
use crate::source::snippet_opt;
use rustc_ast::ast::InlineAsmTemplatePiece;
-use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def::Res;
+use rustc_hir::HirIdMap;
use rustc_hir::{
- BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FieldPat, FnRetTy,
- GenericArg, GenericArgs, Guard, HirId, InlineAsmOperand, Lifetime, LifetimeName, ParamName, Pat, PatKind, Path,
+ BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
+ GenericArgs, Guard, HirId, InlineAsmOperand, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path,
PathSegment, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
};
use rustc_lexer::{tokenize, TokenKind};
fn inter_expr(&mut self) -> HirEqInterExpr<'_, 'a, 'tcx> {
HirEqInterExpr {
inner: self,
- locals: FxHashMap::default(),
+ locals: HirIdMap::default(),
}
}
pub fn eq_path_segments(&mut self, left: &[PathSegment<'_>], right: &[PathSegment<'_>]) -> bool {
self.inter_expr().eq_path_segments(left, right)
}
-
- pub fn eq_ty_kind(&mut self, left: &TyKind<'_>, right: &TyKind<'_>) -> bool {
- self.inter_expr().eq_ty_kind(left, right)
- }
}
struct HirEqInterExpr<'a, 'b, 'tcx> {
// When binding are declared, the binding ID in the left expression is mapped to the one on the
// right. For example, when comparing `{ let x = 1; x + 2 }` and `{ let y = 1; y + 2 }`,
// these blocks are considered equal since `x` is mapped to `y`.
- locals: FxHashMap<HirId, HirId>,
+ locals: HirIdMap<HirId>,
}
impl HirEqInterExpr<'_, '_, '_> {
(&ExprKind::Struct(ref l_path, ref lf, ref lo), &ExprKind::Struct(ref r_path, ref rf, ref ro)) => {
self.eq_qpath(l_path, r_path)
&& both(lo, ro, |l, r| self.eq_expr(l, r))
- && over(lf, rf, |l, r| self.eq_field(l, r))
+ && over(lf, rf, |l, r| self.eq_expr_field(l, r))
},
(&ExprKind::Tup(l_tup), &ExprKind::Tup(r_tup)) => self.eq_exprs(l_tup, r_tup),
(&ExprKind::Unary(l_op, ref le), &ExprKind::Unary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re),
over(left, right, |l, r| self.eq_expr(l, r))
}
- fn eq_field(&mut self, left: &Field<'_>, right: &Field<'_>) -> bool {
+ fn eq_expr_field(&mut self, left: &ExprField<'_>, right: &ExprField<'_>) -> bool {
left.ident.name == right.ident.name && self.eq_expr(&left.expr, &right.expr)
}
left.name == right.name
}
- fn eq_fieldpat(&mut self, left: &FieldPat<'_>, right: &FieldPat<'_>) -> bool {
- let (FieldPat { ident: li, pat: lp, .. }, FieldPat { ident: ri, pat: rp, .. }) = (&left, &right);
+ fn eq_pat_field(&mut self, left: &PatField<'_>, right: &PatField<'_>) -> bool {
+ let (PatField { ident: li, pat: lp, .. }, PatField { ident: ri, pat: rp, .. }) = (&left, &right);
li.name == ri.name && self.eq_pat(lp, rp)
}
match (&left.kind, &right.kind) {
(&PatKind::Box(ref l), &PatKind::Box(ref r)) => self.eq_pat(l, r),
(&PatKind::Struct(ref lp, ref la, ..), &PatKind::Struct(ref rp, ref ra, ..)) => {
- self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_fieldpat(l, r))
+ self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat_field(l, r))
},
(&PatKind::TupleStruct(ref lp, ref la, ls), &PatKind::TupleStruct(ref rp, ref ra, rs)) => {
self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs
left.ident.name == right.ident.name && both(&left.args, &right.args, |l, r| self.eq_path_parameters(l, r))
}
- fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {
- self.eq_ty_kind(&left.kind, &right.kind)
- }
-
#[allow(clippy::similar_names)]
- fn eq_ty_kind(&mut self, left: &TyKind<'_>, right: &TyKind<'_>) -> bool {
- match (left, right) {
+ fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {
+ match (&left.kind, &right.kind) {
(&TyKind::Slice(ref l_vec), &TyKind::Slice(ref r_vec)) => self.eq_ty(l_vec, r_vec),
(&TyKind::Array(ref lt, ref ll_id), &TyKind::Array(ref rt, ref rl_id)) => {
let cx = self.inner.cx;
left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y))
}
+/// Counts how many elements of the slices are equal as per `eq_fn`.
+pub fn count_eq<X: Sized>(
+ left: &mut dyn Iterator<Item = X>,
+ right: &mut dyn Iterator<Item = X>,
+ mut eq_fn: impl FnMut(&X, &X) -> bool,
+) -> usize {
+ left.zip(right).take_while(|(l, r)| eq_fn(l, r)).count()
+}
+
/// Checks if two expressions evaluate to the same value, and don't contain any side effects.
pub fn eq_expr_value(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>) -> bool {
SpanlessEq::new(cx).deny_side_effects().eq_expr(left, right)
TyKind::OpaqueDef(_, arg_list) => {
self.hash_generic_args(arg_list);
},
- TyKind::TraitObject(_, lifetime) => {
+ TyKind::TraitObject(_, lifetime, _) => {
self.hash_lifetime(lifetime);
},
TyKind::Typeof(anon_const) => {