1- use crate :: consts:: { constant_context , constant_simple} ;
1+ use crate :: consts:: constant_simple;
22use crate :: source:: snippet_opt;
33use rustc_ast:: ast:: InlineAsmTemplatePiece ;
44use rustc_data_structures:: fx:: FxHasher ;
@@ -16,15 +16,14 @@ use rustc_span::Symbol;
1616use std:: hash:: { Hash , Hasher } ;
1717
1818/// Type used to check whether two ast are the same. This is different from the
19- /// operator
20- /// `==` on ast types as this operator would compare true equality with ID and
21- /// span.
19+ /// operator `==` on ast types as this operator would compare true equality with
20+ /// ID and span.
2221///
2322/// Note that some expressions kinds are not considered but could be added.
2423pub struct SpanlessEq < ' a , ' tcx > {
2524 /// Context used to evaluate constant expressions.
2625 cx : & ' a LateContext < ' tcx > ,
27- maybe_typeck_results : Option < & ' tcx TypeckResults < ' tcx > > ,
26+ maybe_typeck_results : Option < ( & ' tcx TypeckResults < ' tcx > , & ' tcx TypeckResults < ' tcx > ) > ,
2827 allow_side_effects : bool ,
2928 expr_fallback : Option < Box < dyn FnMut ( & Expr < ' _ > , & Expr < ' _ > ) -> bool + ' a > > ,
3029}
@@ -33,7 +32,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
3332 pub fn new ( cx : & ' a LateContext < ' tcx > ) -> Self {
3433 Self {
3534 cx,
36- maybe_typeck_results : cx. maybe_typeck_results ( ) ,
35+ maybe_typeck_results : cx. maybe_typeck_results ( ) . map ( |x| ( x , x ) ) ,
3736 allow_side_effects : true ,
3837 expr_fallback : None ,
3938 }
@@ -102,9 +101,9 @@ impl HirEqInterExpr<'_, '_, '_> {
102101 ( & StmtKind :: Local ( l) , & StmtKind :: Local ( r) ) => {
103102 // This additional check ensures that the type of the locals are equivalent even if the init
104103 // expression or type have some inferred parts.
105- if let Some ( typeck ) = self . inner . maybe_typeck_results {
106- let l_ty = typeck . pat_ty ( l. pat ) ;
107- let r_ty = typeck . pat_ty ( r. pat ) ;
104+ if let Some ( ( typeck_lhs , typeck_rhs ) ) = self . inner . maybe_typeck_results {
105+ let l_ty = typeck_lhs . pat_ty ( l. pat ) ;
106+ let r_ty = typeck_rhs . pat_ty ( r. pat ) ;
108107 if l_ty != r_ty {
109108 return false ;
110109 }
@@ -182,9 +181,17 @@ impl HirEqInterExpr<'_, '_, '_> {
182181 }
183182
184183 pub fn eq_body ( & mut self , left : BodyId , right : BodyId ) -> bool {
185- let cx = self . inner . cx ;
186- let eval_const = |body| constant_context ( cx, cx. tcx . typeck_body ( body) ) . expr ( & cx. tcx . hir ( ) . body ( body) . value ) ;
187- eval_const ( left) == eval_const ( right)
184+ // swap out TypeckResults when hashing a body
185+ let old_maybe_typeck_results = self . inner . maybe_typeck_results . replace ( (
186+ self . inner . cx . tcx . typeck_body ( left) ,
187+ self . inner . cx . tcx . typeck_body ( right) ,
188+ ) ) ;
189+ let res = self . eq_expr (
190+ & self . inner . cx . tcx . hir ( ) . body ( left) . value ,
191+ & self . inner . cx . tcx . hir ( ) . body ( right) . value ,
192+ ) ;
193+ self . inner . maybe_typeck_results = old_maybe_typeck_results;
194+ res
188195 }
189196
190197 #[ allow( clippy:: similar_names) ]
@@ -193,10 +200,10 @@ impl HirEqInterExpr<'_, '_, '_> {
193200 return false ;
194201 }
195202
196- if let Some ( typeck_results ) = self . inner . maybe_typeck_results {
203+ if let Some ( ( typeck_lhs , typeck_rhs ) ) = self . inner . maybe_typeck_results {
197204 if let ( Some ( l) , Some ( r) ) = (
198- constant_simple ( self . inner . cx , typeck_results , left) ,
199- constant_simple ( self . inner . cx , typeck_results , right) ,
205+ constant_simple ( self . inner . cx , typeck_lhs , left) ,
206+ constant_simple ( self . inner . cx , typeck_rhs , right) ,
200207 ) {
201208 if l == r {
202209 return true ;
0 commit comments