@@ -13,12 +13,10 @@ use rustc_middle::lint::in_external_macro;
1313use rustc_middle:: middle:: stability:: EvalResult ;
1414use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
1515use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
16- use rustc_middle:: ty:: fold:: TypeFolder ;
16+ use rustc_middle:: ty:: fold:: { BottomUpFolder , TypeFolder } ;
1717use rustc_middle:: ty:: print:: { with_forced_trimmed_paths, with_no_trimmed_paths} ;
1818use 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 } ;
2220use rustc_span:: symbol:: { sym, Symbol } ;
2321use rustc_span:: { BytePos , Span } ;
2422use rustc_trait_selection:: infer:: InferCtxtExt as _;
@@ -222,42 +220,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
222220 found : Ty < ' tcx > ,
223221 expected : Ty < ' tcx > ,
224222 ) -> bool {
225- let tcx = self . tcx ;
226223 let map = self . tcx . hir ( ) ;
227224
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-
261225 let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , p) ) = expr. kind else { return false ; } ;
262226 let [ hir:: PathSegment { ident, args : None , .. } ] = p. segments else { return false ; } ;
263227 let hir:: def:: Res :: Local ( hir_id) = p. res else { return false ; } ;
@@ -298,7 +262,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
298262 let Some ( body_id) = node. body_id ( ) else { return false ; } ;
299263 let body = map. body ( body_id) ;
300264 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+ } ;
302281 let mut prev = eraser. fold_ty ( ty) ;
303282 let mut prev_span = None ;
304283
0 commit comments