@@ -82,7 +82,8 @@ use crate::infer::relate::{self, RelateResult, TypeRelation};
8282use crate :: infer:: { InferCtxt , InferCtxtExt as _, TypeTrace , ValuePairs } ;
8383use crate :: solve:: deeply_normalize_for_diagnostics;
8484use crate :: traits:: {
85- MatchExpressionArmCause , Obligation , ObligationCause , ObligationCauseCode , specialization_graph,
85+ MatchExpressionArmCause , Obligation , ObligationCause , ObligationCauseCode , ObligationCtxt ,
86+ specialization_graph,
8687} ;
8788
8889mod note_and_explain;
@@ -115,6 +116,31 @@ fn escape_literal(s: &str) -> String {
115116}
116117
117118impl < ' a , ' tcx > TypeErrCtxt < ' a , ' tcx > {
119+ fn normalize_fn_sig (
120+ & self ,
121+ fn_sig : Unnormalized < ' tcx , ty:: PolyFnSig < ' tcx > > ,
122+ ) -> ty:: PolyFnSig < ' tcx > {
123+ let Some ( param_env) = self . param_env else {
124+ return fn_sig. skip_normalization ( ) ;
125+ } ;
126+
127+ if fn_sig. skip_normalization ( ) . has_escaping_bound_vars ( ) {
128+ return fn_sig. skip_normalization ( ) ;
129+ }
130+
131+ self . probe ( |_| {
132+ let ocx = ObligationCtxt :: new ( self ) ;
133+ let normalized_fn_sig = ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, fn_sig) ;
134+ if ocx. evaluate_obligations_error_on_ambiguity ( ) . is_empty ( ) {
135+ let normalized_fn_sig = self . resolve_vars_if_possible ( normalized_fn_sig) ;
136+ if !normalized_fn_sig. has_infer ( ) {
137+ return normalized_fn_sig;
138+ }
139+ }
140+ fn_sig. skip_normalization ( )
141+ } )
142+ }
143+
118144 // [Note-Type-error-reporting]
119145 // An invariant is that anytime the expected or actual type is Error (the special
120146 // error type, meaning that an error occurred when typechecking this expression),
@@ -760,18 +786,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
760786 /// Given two `fn` signatures highlight only sub-parts that are different.
761787 fn cmp_fn_sig (
762788 & self ,
763- sig1 : & ty:: PolyFnSig < ' tcx > ,
789+ sig1 : ty:: PolyFnSig < ' tcx > ,
764790 fn_def1 : Option < ( DefId , Option < & ' tcx [ ty:: GenericArg < ' tcx > ] > ) > ,
765- sig2 : & ty:: PolyFnSig < ' tcx > ,
791+ sig2 : ty:: PolyFnSig < ' tcx > ,
766792 fn_def2 : Option < ( DefId , Option < & ' tcx [ ty:: GenericArg < ' tcx > ] > ) > ,
767793 ) -> ( DiagStyledString , DiagStyledString ) {
768- let sig1 = & ( self . normalize_fn_sig ) ( Unnormalized :: new_wip ( * sig1) ) ;
769- let sig2 = & ( self . normalize_fn_sig ) ( Unnormalized :: new_wip ( * sig2) ) ;
794+ let sig1 = self . normalize_fn_sig ( Unnormalized :: new_wip ( sig1) ) ;
795+ let sig2 = self . normalize_fn_sig ( Unnormalized :: new_wip ( sig2) ) ;
770796
771797 let get_lifetimes = |sig| {
772798 use rustc_hir:: def:: Namespace ;
773799 let ( sig, reg) = ty:: print:: FmtPrinter :: new ( self . tcx , Namespace :: TypeNS )
774- . name_all_regions ( sig, WrapBinderMode :: ForAll )
800+ . name_all_regions ( & sig, WrapBinderMode :: ForAll )
775801 . unwrap ( ) ;
776802 let lts: Vec < String > =
777803 reg. into_items ( ) . map ( |( _, kind) | kind. to_string ( ) ) . into_sorted_stable_ord ( ) ;
@@ -1284,26 +1310,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
12841310 ( ty:: FnDef ( did1, args1) , ty:: FnDef ( did2, args2) ) => {
12851311 let sig1 = self . tcx . fn_sig ( * did1) . instantiate ( self . tcx , args1) . skip_norm_wip ( ) ;
12861312 let sig2 = self . tcx . fn_sig ( * did2) . instantiate ( self . tcx , args2) . skip_norm_wip ( ) ;
1287- self . cmp_fn_sig (
1288- & sig1,
1289- Some ( ( * did1, Some ( args1) ) ) ,
1290- & sig2,
1291- Some ( ( * did2, Some ( args2) ) ) ,
1292- )
1313+ self . cmp_fn_sig ( sig1, Some ( ( * did1, Some ( args1) ) ) , sig2, Some ( ( * did2, Some ( args2) ) ) )
12931314 }
12941315
12951316 ( ty:: FnDef ( did1, args1) , ty:: FnPtr ( sig_tys2, hdr2) ) => {
12961317 let sig1 = self . tcx . fn_sig ( * did1) . instantiate ( self . tcx , args1) . skip_norm_wip ( ) ;
1297- self . cmp_fn_sig ( & sig1, Some ( ( * did1, Some ( args1) ) ) , & sig_tys2. with ( * hdr2) , None )
1318+ self . cmp_fn_sig ( sig1, Some ( ( * did1, Some ( args1) ) ) , sig_tys2. with ( * hdr2) , None )
12981319 }
12991320
13001321 ( ty:: FnPtr ( sig_tys1, hdr1) , ty:: FnDef ( did2, args2) ) => {
13011322 let sig2 = self . tcx . fn_sig ( * did2) . instantiate ( self . tcx , args2) . skip_norm_wip ( ) ;
1302- self . cmp_fn_sig ( & sig_tys1. with ( * hdr1) , None , & sig2, Some ( ( * did2, Some ( args2) ) ) )
1323+ self . cmp_fn_sig ( sig_tys1. with ( * hdr1) , None , sig2, Some ( ( * did2, Some ( args2) ) ) )
13031324 }
13041325
13051326 ( ty:: FnPtr ( sig_tys1, hdr1) , ty:: FnPtr ( sig_tys2, hdr2) ) => {
1306- self . cmp_fn_sig ( & sig_tys1. with ( * hdr1) , None , & sig_tys2. with ( * hdr2) , None )
1327+ self . cmp_fn_sig ( sig_tys1. with ( * hdr1) , None , sig_tys2. with ( * hdr2) , None )
13071328 }
13081329
13091330 _ => {
@@ -2190,7 +2211,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21902211 ( None , None )
21912212 } ;
21922213
2193- Some ( self . cmp_fn_sig ( & exp_found. expected , fn_def1, & exp_found. found , fn_def2) )
2214+ Some ( self . cmp_fn_sig ( exp_found. expected , fn_def1, exp_found. found , fn_def2) )
21942215 }
21952216 }
21962217 }
0 commit comments