@@ -13,12 +13,10 @@ use rustc_middle::lint::in_external_macro;
13
13
use rustc_middle:: middle:: stability:: EvalResult ;
14
14
use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
15
15
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
16
- use rustc_middle:: ty:: fold:: TypeFolder ;
16
+ use rustc_middle:: ty:: fold:: { BottomUpFolder , TypeFolder } ;
17
17
use rustc_middle:: ty:: print:: { with_forced_trimmed_paths, with_no_trimmed_paths} ;
18
18
use rustc_middle:: ty:: relate:: TypeRelation ;
19
- use rustc_middle:: ty:: {
20
- self , Article , AssocItem , Ty , TyCtxt , TypeAndMut , TypeSuperFoldable , TypeVisitable ,
21
- } ;
19
+ use rustc_middle:: ty:: { self , Article , AssocItem , Ty , TypeAndMut , TypeVisitable } ;
22
20
use rustc_span:: symbol:: { sym, Symbol } ;
23
21
use rustc_span:: { BytePos , Span } ;
24
22
use rustc_trait_selection:: infer:: InferCtxtExt as _;
@@ -222,42 +220,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
222
220
found : Ty < ' tcx > ,
223
221
expected : Ty < ' tcx > ,
224
222
) -> bool {
225
- let tcx = self . tcx ;
226
223
let map = self . tcx . hir ( ) ;
227
224
228
- // Hack to make equality checks on types with inference variables and regions useful.
229
- struct TypeEraser < ' tcx > {
230
- tcx : TyCtxt < ' tcx > ,
231
- }
232
- impl < ' tcx > TypeFolder < ' tcx > for TypeEraser < ' tcx > {
233
- fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' tcx > {
234
- self . tcx
235
- }
236
- fn fold_region ( & mut self , _r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
237
- self . tcx ( ) . lifetimes . re_erased
238
- }
239
- fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
240
- if !t. needs_infer ( ) && !t. has_erasable_regions ( ) {
241
- return t;
242
- }
243
- match * t. kind ( ) {
244
- ty:: Infer ( ty:: TyVar ( _) | ty:: FreshTy ( _) ) => {
245
- self . tcx . mk_ty_infer ( ty:: TyVar ( ty:: TyVid :: from_u32 ( 0 ) ) )
246
- }
247
- ty:: Infer ( ty:: IntVar ( _) | ty:: FreshIntTy ( _) ) => {
248
- self . tcx . mk_ty_infer ( ty:: IntVar ( ty:: IntVid { index : 0 } ) )
249
- }
250
- ty:: Infer ( ty:: FloatVar ( _) | ty:: FreshFloatTy ( _) ) => {
251
- self . tcx . mk_ty_infer ( ty:: FloatVar ( ty:: FloatVid { index : 0 } ) )
252
- }
253
- _ => t. super_fold_with ( self ) ,
254
- }
255
- }
256
- fn fold_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
257
- ct. super_fold_with ( self )
258
- }
259
- }
260
-
261
225
let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , p) ) = expr. kind else { return false ; } ;
262
226
let [ hir:: PathSegment { ident, args : None , .. } ] = p. segments else { return false ; } ;
263
227
let hir:: def:: Res :: Local ( hir_id) = p. res else { return false ; } ;
@@ -298,7 +262,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
298
262
let Some ( body_id) = node. body_id ( ) else { return false ; } ;
299
263
let body = map. body ( body_id) ;
300
264
expr_finder. visit_expr ( body. value ) ;
301
- let mut eraser = TypeEraser { tcx } ;
265
+ // Hack to make equality checks on types with inference variables and regions useful.
266
+ let mut eraser = BottomUpFolder {
267
+ tcx : self . tcx ,
268
+ lt_op : |_| self . tcx . lifetimes . re_erased ,
269
+ ct_op : |c| c,
270
+ ty_op : |t| match * t. kind ( ) {
271
+ ty:: Infer ( ty:: TyVar ( vid) ) => self . tcx . mk_ty_infer ( ty:: TyVar ( self . root_var ( vid) ) ) ,
272
+ ty:: Infer ( ty:: IntVar ( _) ) => {
273
+ self . tcx . mk_ty_infer ( ty:: IntVar ( ty:: IntVid { index : 0 } ) )
274
+ }
275
+ ty:: Infer ( ty:: FloatVar ( _) ) => {
276
+ self . tcx . mk_ty_infer ( ty:: FloatVar ( ty:: FloatVid { index : 0 } ) )
277
+ }
278
+ _ => t,
279
+ } ,
280
+ } ;
302
281
let mut prev = eraser. fold_ty ( ty) ;
303
282
let mut prev_span = None ;
304
283
0 commit comments