@@ -17,7 +17,7 @@ use rustc_errors::{
17
17
ErrorGuaranteed , MultiSpan , Style , SuggestionStyle ,
18
18
} ;
19
19
use rustc_hir as hir;
20
- use rustc_hir:: def:: DefKind ;
20
+ use rustc_hir:: def:: { DefKind , Res } ;
21
21
use rustc_hir:: def_id:: DefId ;
22
22
use rustc_hir:: intravisit:: Visitor ;
23
23
use rustc_hir:: is_range_literal;
@@ -36,7 +36,7 @@ use rustc_middle::ty::{
36
36
TypeSuperFoldable , TypeVisitableExt , TypeckResults ,
37
37
} ;
38
38
use rustc_span:: def_id:: LocalDefId ;
39
- use rustc_span:: symbol:: { sym, Ident , Symbol } ;
39
+ use rustc_span:: symbol:: { kw , sym, Ident , Symbol } ;
40
40
use rustc_span:: { BytePos , DesugaringKind , ExpnKind , MacroKind , Span , DUMMY_SP } ;
41
41
use rustc_target:: spec:: abi;
42
42
use std:: borrow:: Cow ;
@@ -1043,7 +1043,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1043
1043
let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = expr. kind else {
1044
1044
return ;
1045
1045
} ;
1046
- let hir :: def :: Res :: Local ( hir_id) = path. res else {
1046
+ let Res :: Local ( hir_id) = path. res else {
1047
1047
return ;
1048
1048
} ;
1049
1049
let Some ( hir:: Node :: Pat ( pat) ) = self . tcx . hir ( ) . find ( hir_id) else {
@@ -1627,7 +1627,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1627
1627
}
1628
1628
}
1629
1629
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
1631
1631
&& let Some ( hir:: Node :: Pat ( binding) ) = self . tcx . hir ( ) . find ( hir_id)
1632
1632
&& let Some ( hir:: Node :: Local ( local) ) = self . tcx . hir ( ) . find_parent ( binding. hir_id )
1633
1633
&& let None = local. ty
@@ -2047,39 +2047,34 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2047
2047
let hir:: ExprKind :: Path ( path) = arg. kind else {
2048
2048
return ;
2049
2049
} ;
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 ( ) ) ;
2053
2053
2054
2054
let arg_expr = |infcx : & InferCtxt < ' tcx > , name, expected : Ty < ' tcx > , found : Ty < ' tcx > | {
2055
2055
let ( expected_ty, expected_refs) = get_deref_type_and_refs ( expected) ;
2056
2056
let ( found_ty, found_refs) = get_deref_type_and_refs ( found) ;
2057
2057
2058
2058
if infcx. can_eq ( param_env, found_ty, expected_ty) {
2059
2059
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 ( ) )
2061
2061
{
2062
2062
name
2063
2063
} 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 ( ) ) {
2070
2066
format ! (
2071
- "{}*{name}" ,
2072
- found_refs[ ..found_refs. len( ) - expected_refs. len( ) ]
2073
- . iter( )
2067
+ "{}{name}" ,
2068
+ refs. iter( )
2074
2069
. map( |mutbl| format!( "&{}" , mutbl. prefix_str( ) ) )
2075
2070
. collect:: <Vec <_>>( )
2076
2071
. join( "" ) ,
2077
2072
)
2078
2073
} else {
2074
+ // The refs have different mutability.
2079
2075
format ! (
2080
- "{}{name}" ,
2081
- found_refs[ ..found_refs. len( ) - expected_refs. len( ) ]
2082
- . iter( )
2076
+ "{}*{name}" ,
2077
+ refs. iter( )
2083
2078
. map( |mutbl| format!( "&{}" , mutbl. prefix_str( ) ) )
2084
2079
. collect:: <Vec <_>>( )
2085
2080
. join( "" ) ,
@@ -2108,48 +2103,52 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2108
2103
format ! ( "/* {found} */" )
2109
2104
}
2110
2105
} ;
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
+ } ;
2153
2152
let closure_names: Vec < _ > = closure_names
2154
2153
. into_iter ( )
2155
2154
. zip ( expected_inputs. iter ( ) )
@@ -3790,7 +3789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
3790
3789
}
3791
3790
}
3792
3791
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
3794
3793
&& let Some ( hir:: Node :: Pat ( binding) ) = self . tcx . hir ( ) . find ( * hir_id)
3795
3794
&& let parent_hir_id = self . tcx . hir ( ) . parent_id ( binding. hir_id )
3796
3795
&& let Some ( hir:: Node :: Local ( local) ) = self . tcx . hir ( ) . find ( parent_hir_id)
@@ -4050,7 +4049,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
4050
4049
) ;
4051
4050
4052
4051
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
4054
4053
&& let Some ( hir:: Node :: Pat ( binding) ) = self . tcx . hir ( ) . find ( * hir_id)
4055
4054
&& let Some ( parent) = self . tcx . hir ( ) . find_parent ( binding. hir_id )
4056
4055
{
@@ -4664,7 +4663,7 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
4664
4663
fn visit_ty ( & mut self , t : & ' hir hir:: Ty < ' hir > ) {
4665
4664
if let hir:: TyKind :: Path ( hir:: QPath :: Resolved (
4666
4665
None ,
4667
- hir:: Path { res : hir :: def :: Res :: Def ( _, segment_did) , .. } ,
4666
+ hir:: Path { res : Res :: Def ( _, segment_did) , .. } ,
4668
4667
) ) = t. kind
4669
4668
{
4670
4669
if self . param_did == * segment_did {
0 commit comments