@@ -847,7 +847,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
847847 match b. kind ( ) {
848848 ty:: FnPtr ( _, hdr) => {
849849 let safety = hdr. safety ;
850- let closure_sig = self . sig_for_closure_coercion ( a, Some ( hdr. safety ) ) ?;
850+ let closure_sig = self . sig_for_closure_coercion ( a, Some ( hdr. safety ) , b ) ?;
851851 let pointer_ty = Ty :: new_fn_ptr ( self . tcx , closure_sig) ;
852852 debug ! ( "coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})" , a, b, pointer_ty) ;
853853
@@ -1014,10 +1014,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10141014 } )
10151015 }
10161016
1017- fn sig_for_coerce_lub ( & self , ty : Ty < ' tcx > ) -> Result < ty:: PolyFnSig < ' tcx > , TypeError < ' tcx > > {
1017+ fn sig_for_coerce_lub (
1018+ & self ,
1019+ ty : Ty < ' tcx > ,
1020+ coerce_target_for_diag : Ty < ' tcx > ,
1021+ ) -> Result < ty:: PolyFnSig < ' tcx > , TypeError < ' tcx > > {
10181022 match ty. kind ( ) {
10191023 ty:: FnDef ( ..) => self . sig_for_fn_def_coercion ( ty, None ) ,
1020- ty:: Closure ( ..) => self . sig_for_closure_coercion ( ty, None ) ,
1024+ ty:: Closure ( ..) => self . sig_for_closure_coercion ( ty, None , coerce_target_for_diag ) ,
10211025 _ => unreachable ! ( "`sig_for_fn_def_closure_coerce_lub` called with wrong ty: {:?}" , ty) ,
10221026 }
10231027 }
@@ -1069,6 +1073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10691073 & self ,
10701074 closure : Ty < ' tcx > ,
10711075 expected_safety : Option < hir:: Safety > ,
1076+ coerce_target_for_diag : Ty < ' tcx > ,
10721077 ) -> Result < ty:: PolyFnSig < ' tcx > , TypeError < ' tcx > > {
10731078 let tcx = self . tcx ;
10741079
@@ -1083,7 +1088,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10831088 // All we care here is if any variable is being captured and not the exact paths,
10841089 // so we check `upvars_mentioned` for root variables being captured.
10851090 if !tcx. upvars_mentioned ( closure_def. expect_local ( ) ) . is_none_or ( |u| u. is_empty ( ) ) {
1086- return Err ( TypeError :: Mismatch ) ;
1091+ return Err ( TypeError :: Sorts ( ty:: error:: ExpectedFound :: new (
1092+ closure,
1093+ coerce_target_for_diag,
1094+ ) ) ) ;
10871095 }
10881096
10891097 // We coerce the closure, which has fn type
@@ -1153,15 +1161,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11531161 match lubbed_ty {
11541162 Ok ( ok) => return Ok ( self . register_infer_ok_obligations ( ok) ) ,
11551163 Err ( _) => {
1156- let a_sig = self . sig_for_coerce_lub ( prev_ty) ?;
1157- let b_sig = self . sig_for_coerce_lub ( new_ty) ?;
1164+ let a_sig = self . sig_for_coerce_lub ( prev_ty, new_ty ) ?;
1165+ let b_sig = self . sig_for_coerce_lub ( new_ty, prev_ty ) ?;
11581166 Some ( ( a_sig, b_sig) )
11591167 }
11601168 }
11611169 }
11621170 ( ty:: Closure ( ..) , ty:: FnDef ( ..) ) | ( ty:: FnDef ( ..) , ty:: Closure ( ..) ) => {
1163- let a_sig = self . sig_for_coerce_lub ( prev_ty) ?;
1164- let b_sig = self . sig_for_coerce_lub ( new_ty) ?;
1171+ let a_sig = self . sig_for_coerce_lub ( prev_ty, new_ty ) ?;
1172+ let b_sig = self . sig_for_coerce_lub ( new_ty, prev_ty ) ?;
11651173 Some ( ( a_sig, b_sig) )
11661174 }
11671175 // ty::FnPtr x ty::FnPtr is fine to just be handled through a normal `unify`
0 commit comments