-use crate::consts::{constant_context, constant_simple};
+use crate::consts::constant_simple;
use crate::source::snippet_opt;
use rustc_ast::ast::InlineAsmTemplatePiece;
use rustc_data_structures::fx::FxHasher;
use std::hash::{Hash, Hasher};
/// Type used to check whether two ast are the same. This is different from the
-/// operator
-/// `==` on ast types as this operator would compare true equality with ID and
-/// span.
+/// operator `==` on ast types as this operator would compare true equality with
+/// ID and span.
///
/// Note that some expressions kinds are not considered but could be added.
pub struct SpanlessEq<'a, 'tcx> {
/// Context used to evaluate constant expressions.
cx: &'a LateContext<'tcx>,
- maybe_typeck_results: Option<&'tcx TypeckResults<'tcx>>,
+ maybe_typeck_results: Option<(&'tcx TypeckResults<'tcx>, &'tcx TypeckResults<'tcx>)>,
allow_side_effects: bool,
expr_fallback: Option<Box<dyn FnMut(&Expr<'_>, &Expr<'_>) -> bool + 'a>>,
}
pub fn new(cx: &'a LateContext<'tcx>) -> Self {
Self {
cx,
- maybe_typeck_results: cx.maybe_typeck_results(),
+ maybe_typeck_results: cx.maybe_typeck_results().map(|x| (x, x)),
allow_side_effects: true,
expr_fallback: None,
}
(&StmtKind::Local(l), &StmtKind::Local(r)) => {
// This additional check ensures that the type of the locals are equivalent even if the init
// expression or type have some inferred parts.
- if let Some(typeck) = self.inner.maybe_typeck_results {
- let l_ty = typeck.pat_ty(l.pat);
- let r_ty = typeck.pat_ty(r.pat);
+ if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results {
+ let l_ty = typeck_lhs.pat_ty(l.pat);
+ let r_ty = typeck_rhs.pat_ty(r.pat);
if l_ty != r_ty {
return false;
}
}
pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool {
- let cx = self.inner.cx;
- let eval_const = |body| constant_context(cx, cx.tcx.typeck_body(body)).expr(&cx.tcx.hir().body(body).value);
- eval_const(left) == eval_const(right)
+ // swap out TypeckResults when hashing a body
+ let old_maybe_typeck_results = self.inner.maybe_typeck_results.replace((
+ self.inner.cx.tcx.typeck_body(left),
+ self.inner.cx.tcx.typeck_body(right),
+ ));
+ let res = self.eq_expr(
+ &self.inner.cx.tcx.hir().body(left).value,
+ &self.inner.cx.tcx.hir().body(right).value,
+ );
+ self.inner.maybe_typeck_results = old_maybe_typeck_results;
+ res
}
#[allow(clippy::similar_names)]
return false;
}
- if let Some(typeck_results) = self.inner.maybe_typeck_results {
+ if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results {
if let (Some(l), Some(r)) = (
- constant_simple(self.inner.cx, typeck_results, left),
- constant_simple(self.inner.cx, typeck_results, right),
+ constant_simple(self.inner.cx, typeck_lhs, left),
+ constant_simple(self.inner.cx, typeck_rhs, right),
) {
if l == r {
return true;
self.hash_expr(out_expr);
}
},
- InlineAsmOperand::Const { anon_const } => self.hash_body(anon_const.body),
- InlineAsmOperand::Sym { expr } => self.hash_expr(expr),
+ InlineAsmOperand::Const { anon_const } | InlineAsmOperand::SymFn { anon_const } => {
+ self.hash_body(anon_const.body);
+ },
+ InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path),
}
}
},