@@ -17,7 +17,7 @@ use rustc_errors::{
1717 ErrorGuaranteed , MultiSpan , Style , SuggestionStyle ,
1818} ;
1919use rustc_hir as hir;
20- use rustc_hir:: def:: DefKind ;
20+ use rustc_hir:: def:: { DefKind , Res } ;
2121use rustc_hir:: def_id:: DefId ;
2222use rustc_hir:: intravisit:: Visitor ;
2323use rustc_hir:: is_range_literal;
@@ -36,7 +36,7 @@ use rustc_middle::ty::{
3636 TypeSuperFoldable , TypeVisitableExt , TypeckResults ,
3737} ;
3838use rustc_span:: def_id:: LocalDefId ;
39- use rustc_span:: symbol:: { sym, Ident , Symbol } ;
39+ use rustc_span:: symbol:: { kw , sym, Ident , Symbol } ;
4040use rustc_span:: { BytePos , DesugaringKind , ExpnKind , MacroKind , Span , DUMMY_SP } ;
4141use rustc_target:: spec:: abi;
4242use std:: borrow:: Cow ;
@@ -1043,7 +1043,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
10431043 let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = expr. kind else {
10441044 return ;
10451045 } ;
1046- let hir :: def :: Res :: Local ( hir_id) = path. res else {
1046+ let Res :: Local ( hir_id) = path. res else {
10471047 return ;
10481048 } ;
10491049 let Some ( hir:: Node :: Pat ( pat) ) = self . tcx . hir ( ) . find ( hir_id) else {
@@ -1627,7 +1627,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16271627 }
16281628 }
16291629 if let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = expr. kind
1630- && let hir :: def :: Res :: Local ( hir_id) = path. res
1630+ && let Res :: Local ( hir_id) = path. res
16311631 && let Some ( hir:: Node :: Pat ( binding) ) = self . tcx . hir ( ) . find ( hir_id)
16321632 && let Some ( hir:: Node :: Local ( local) ) = self . tcx . hir ( ) . find_parent ( binding. hir_id )
16331633 && let None = local. ty
@@ -2047,39 +2047,34 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
20472047 let hir:: ExprKind :: Path ( path) = arg. kind else {
20482048 return ;
20492049 } ;
2050- let expected_inputs = self . tcx . erase_late_bound_regions ( * expected) . inputs ( ) ;
2051- let found_inputs = self . tcx . erase_late_bound_regions ( * found) . inputs ( ) ;
2052- let both_tys = expected_inputs. iter ( ) . cloned ( ) . zip ( found_inputs. iter ( ) . cloned ( ) ) ;
2050+ let expected_inputs = self . tcx . instantiate_bound_regions_with_erased ( * expected) . inputs ( ) ;
2051+ let found_inputs = self . tcx . instantiate_bound_regions_with_erased ( * found) . inputs ( ) ;
2052+ let both_tys = expected_inputs. iter ( ) . copied ( ) . zip ( found_inputs. iter ( ) . copied ( ) ) ;
20532053
20542054 let arg_expr = |infcx : & InferCtxt < ' tcx > , name, expected : Ty < ' tcx > , found : Ty < ' tcx > | {
20552055 let ( expected_ty, expected_refs) = get_deref_type_and_refs ( expected) ;
20562056 let ( found_ty, found_refs) = get_deref_type_and_refs ( found) ;
20572057
20582058 if infcx. can_eq ( param_env, found_ty, expected_ty) {
20592059 if found_refs. len ( ) == expected_refs. len ( )
2060- && found_refs. iter ( ) . zip ( expected_refs. iter ( ) ) . all ( | ( e , f ) | e == f )
2060+ && found_refs. iter ( ) . eq ( expected_refs. iter ( ) )
20612061 {
20622062 name
20632063 } else if found_refs. len ( ) > expected_refs. len ( ) {
2064- if found_refs[ ..found_refs. len ( ) - expected_refs. len ( ) ]
2065- . iter ( )
2066- . zip ( expected_refs. iter ( ) )
2067- . any ( |( e, f) | e != f)
2068- {
2069- // The refs have different mutability.
2064+ let refs = & found_refs[ ..found_refs. len ( ) - expected_refs. len ( ) ] ;
2065+ if found_refs[ ..expected_refs. len ( ) ] . iter ( ) . eq ( expected_refs. iter ( ) ) {
20702066 format ! (
2071- "{}*{name}" ,
2072- found_refs[ ..found_refs. len( ) - expected_refs. len( ) ]
2073- . iter( )
2067+ "{}{name}" ,
2068+ refs. iter( )
20742069 . map( |mutbl| format!( "&{}" , mutbl. prefix_str( ) ) )
20752070 . collect:: <Vec <_>>( )
20762071 . join( "" ) ,
20772072 )
20782073 } else {
2074+ // The refs have different mutability.
20792075 format ! (
2080- "{}{name}" ,
2081- found_refs[ ..found_refs. len( ) - expected_refs. len( ) ]
2082- . iter( )
2076+ "{}*{name}" ,
2077+ refs. iter( )
20832078 . map( |mutbl| format!( "&{}" , mutbl. prefix_str( ) ) )
20842079 . collect:: <Vec <_>>( )
20852080 . join( "" ) ,
@@ -2108,48 +2103,52 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
21082103 format ! ( "/* {found} */" )
21092104 }
21102105 } ;
2111- let ( closure_names, call_names) : ( Vec < _ > , Vec < _ > ) =
2112- if both_tys. clone ( ) . all ( |( expected, found) | {
2113- let ( expected_ty, _) = get_deref_type_and_refs ( expected) ;
2114- let ( found_ty, _) = get_deref_type_and_refs ( found) ;
2115- self . can_eq ( param_env, found_ty, expected_ty)
2116- } ) && !expected_inputs. is_empty ( )
2117- && expected_inputs. len ( ) == found_inputs. len ( )
2118- && let hir:: QPath :: Resolved ( _, path) = path
2119- && let hir:: def:: Res :: Def ( _, fn_def_id) = path. res
2120- && let Some ( node) = self . tcx . hir ( ) . get_if_local ( fn_def_id)
2121- && let Some ( body_id) = node. body_id ( )
2122- {
2123- let closure = self
2124- . tcx
2125- . hir ( )
2126- . body_param_names ( body_id)
2127- . map ( |name| format ! ( "{name}" ) )
2128- . collect ( ) ;
2129- let args = self
2130- . tcx
2131- . hir ( )
2132- . body_param_names ( body_id)
2133- . zip ( both_tys)
2134- . map ( |( name, ( expected, found) ) | {
2135- arg_expr ( self . infcx , format ! ( "{name}" ) , expected, found)
2136- } )
2137- . collect ( ) ;
2138- ( closure, args)
2139- } else {
2140- let closure_args = expected_inputs
2141- . iter ( )
2142- . enumerate ( )
2143- . map ( |( i, _) | format ! ( "arg{i}" ) )
2144- . collect :: < Vec < _ > > ( ) ;
2145- let call_args = both_tys
2146- . enumerate ( )
2147- . map ( |( i, ( expected, found) ) | {
2148- arg_expr ( self . infcx , format ! ( "arg{i}" ) , expected, found)
2149- } )
2150- . collect :: < Vec < _ > > ( ) ;
2151- ( closure_args, call_args)
2152- } ;
2106+ let args_have_same_underlying_type = both_tys. clone ( ) . all ( |( expected, found) | {
2107+ let ( expected_ty, _) = get_deref_type_and_refs ( expected) ;
2108+ let ( found_ty, _) = get_deref_type_and_refs ( found) ;
2109+ self . can_eq ( param_env, found_ty, expected_ty)
2110+ } ) ;
2111+ let ( closure_names, call_names) : ( Vec < _ > , Vec < _ > ) = if args_have_same_underlying_type
2112+ && !expected_inputs. is_empty ( )
2113+ && expected_inputs. len ( ) == found_inputs. len ( )
2114+ && let Some ( typeck) = & self . typeck_results
2115+ && let Res :: Def ( _, fn_def_id) = typeck. qpath_res ( & path, * arg_hir_id)
2116+ {
2117+ let closure: Vec < _ > = self
2118+ . tcx
2119+ . fn_arg_names ( fn_def_id)
2120+ . iter ( )
2121+ . enumerate ( )
2122+ . map ( |( i, ident) | {
2123+ if ident. name . is_empty ( ) || ident. name == kw:: SelfLower {
2124+ format ! ( "arg{i}" )
2125+ } else {
2126+ format ! ( "{ident}" )
2127+ }
2128+ } )
2129+ . collect ( ) ;
2130+ let args = closure
2131+ . iter ( )
2132+ . zip ( both_tys)
2133+ . map ( |( name, ( expected, found) ) | {
2134+ arg_expr ( self . infcx , name. to_owned ( ) , expected, found)
2135+ } )
2136+ . collect ( ) ;
2137+ ( closure, args)
2138+ } else {
2139+ let closure_args = expected_inputs
2140+ . iter ( )
2141+ . enumerate ( )
2142+ . map ( |( i, _) | format ! ( "arg{i}" ) )
2143+ . collect :: < Vec < _ > > ( ) ;
2144+ let call_args = both_tys
2145+ . enumerate ( )
2146+ . map ( |( i, ( expected, found) ) | {
2147+ arg_expr ( self . infcx , format ! ( "arg{i}" ) , expected, found)
2148+ } )
2149+ . collect :: < Vec < _ > > ( ) ;
2150+ ( closure_args, call_args)
2151+ } ;
21532152 let closure_names: Vec < _ > = closure_names
21542153 . into_iter ( )
21552154 . zip ( expected_inputs. iter ( ) )
@@ -3790,7 +3789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
37903789 }
37913790 }
37923791 if let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = expr. kind
3793- && let hir:: Path { res : hir :: def :: Res :: Local ( hir_id) , .. } = path
3792+ && let hir:: Path { res : Res :: Local ( hir_id) , .. } = path
37943793 && let Some ( hir:: Node :: Pat ( binding) ) = self . tcx . hir ( ) . find ( * hir_id)
37953794 && let parent_hir_id = self . tcx . hir ( ) . parent_id ( binding. hir_id )
37963795 && let Some ( hir:: Node :: Local ( local) ) = self . tcx . hir ( ) . find ( parent_hir_id)
@@ -4050,7 +4049,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
40504049 ) ;
40514050
40524051 if let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = expr. kind
4053- && let hir:: Path { res : hir :: def :: Res :: Local ( hir_id) , .. } = path
4052+ && let hir:: Path { res : Res :: Local ( hir_id) , .. } = path
40544053 && let Some ( hir:: Node :: Pat ( binding) ) = self . tcx . hir ( ) . find ( * hir_id)
40554054 && let Some ( parent) = self . tcx . hir ( ) . find_parent ( binding. hir_id )
40564055 {
@@ -4664,7 +4663,7 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
46644663 fn visit_ty ( & mut self , t : & ' hir hir:: Ty < ' hir > ) {
46654664 if let hir:: TyKind :: Path ( hir:: QPath :: Resolved (
46664665 None ,
4667- hir:: Path { res : hir :: def :: Res :: Def ( _, segment_did) , .. } ,
4666+ hir:: Path { res : Res :: Def ( _, segment_did) , .. } ,
46684667 ) ) = t. kind
46694668 {
46704669 if self . param_did == * segment_did {
0 commit comments