1
- use crate :: consts:: { constant_context , constant_simple} ;
1
+ use crate :: consts:: constant_simple;
2
2
use crate :: source:: snippet_opt;
3
3
use rustc_ast:: ast:: InlineAsmTemplatePiece ;
4
4
use rustc_data_structures:: fx:: FxHasher ;
@@ -16,15 +16,14 @@ use rustc_span::Symbol;
16
16
use std:: hash:: { Hash , Hasher } ;
17
17
18
18
/// 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.
22
21
///
23
22
/// Note that some expressions kinds are not considered but could be added.
24
23
pub struct SpanlessEq < ' a , ' tcx > {
25
24
/// Context used to evaluate constant expressions.
26
25
cx : & ' a LateContext < ' tcx > ,
27
- maybe_typeck_results : Option < & ' tcx TypeckResults < ' tcx > > ,
26
+ maybe_typeck_results : Option < ( & ' tcx TypeckResults < ' tcx > , & ' tcx TypeckResults < ' tcx > ) > ,
28
27
allow_side_effects : bool ,
29
28
expr_fallback : Option < Box < dyn FnMut ( & Expr < ' _ > , & Expr < ' _ > ) -> bool + ' a > > ,
30
29
}
@@ -33,7 +32,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
33
32
pub fn new ( cx : & ' a LateContext < ' tcx > ) -> Self {
34
33
Self {
35
34
cx,
36
- maybe_typeck_results : cx. maybe_typeck_results ( ) ,
35
+ maybe_typeck_results : cx. maybe_typeck_results ( ) . map ( |x| ( x , x ) ) ,
37
36
allow_side_effects : true ,
38
37
expr_fallback : None ,
39
38
}
@@ -102,9 +101,9 @@ impl HirEqInterExpr<'_, '_, '_> {
102
101
( & StmtKind :: Local ( l) , & StmtKind :: Local ( r) ) => {
103
102
// This additional check ensures that the type of the locals are equivalent even if the init
104
103
// 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 ) ;
108
107
if l_ty != r_ty {
109
108
return false ;
110
109
}
@@ -182,9 +181,17 @@ impl HirEqInterExpr<'_, '_, '_> {
182
181
}
183
182
184
183
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
188
195
}
189
196
190
197
#[ allow( clippy:: similar_names) ]
@@ -193,10 +200,10 @@ impl HirEqInterExpr<'_, '_, '_> {
193
200
return false ;
194
201
}
195
202
196
- if let Some ( typeck_results ) = self . inner . maybe_typeck_results {
203
+ if let Some ( ( typeck_lhs , typeck_rhs ) ) = self . inner . maybe_typeck_results {
197
204
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) ,
200
207
) {
201
208
if l == r {
202
209
return true ;
0 commit comments