@@ -1199,7 +1199,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
11991199 ( self . final_ty . unwrap_or ( self . expected_ty ) , expression_ty)
12001200 } ;
12011201
1202- let reason_label = "expected because of this statement" ;
12031202 let mut db;
12041203 match cause. code {
12051204 ObligationCauseCode :: ReturnNoExpression => {
@@ -1209,63 +1208,20 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
12091208 db. span_label ( cause. span , "return type is not `()`" ) ;
12101209 }
12111210 ObligationCauseCode :: BlockTailExpression ( blk_id) => {
1212- db = fcx. report_mismatched_types ( cause, expected, found, err) ;
1213-
1214- let expr = expression. unwrap_or_else ( || {
1215- span_bug ! ( cause. span,
1216- "supposed to be part of a block tail expression, but the \
1217- expression is empty") ;
1218- } ) ;
1219- let pointing_at_return_type = fcx. suggest_mismatched_types_on_tail (
1220- & mut db,
1221- expr,
1211+ let parent_id = fcx. tcx . hir ( ) . get_parent_node ( blk_id) ;
1212+ db = self . report_return_mismatched_types (
1213+ cause,
12221214 expected,
12231215 found,
1224- cause. span ,
1225- blk_id,
1216+ err,
1217+ fcx,
1218+ parent_id,
1219+ expression. map ( |expr| ( expr, blk_id) ) ,
12261220 ) ;
1227- // FIXME: replace with navigating up the chain until hitting an fn or
1228- // bailing if no "pass-through" Node is found, in order to provide a
1229- // suggestion when encountering something like:
1230- // ```
1231- // fn foo(a: bool) -> impl Debug {
1232- // if a {
1233- // bar()?;
1234- // }
1235- // {
1236- // let x = unsafe { bar() };
1237- // x
1238- // }
1239- // }
1240- // ```
1241- //
1242- // Verify that this is a tail expression of a function, otherwise the
1243- // label pointing out the cause for the type coercion will be wrong
1244- // as prior return coercions would not be relevant (#57664).
1245- let parent_id = fcx. tcx . hir ( ) . get_parent_node ( blk_id) ;
1246- let parent = fcx. tcx . hir ( ) . get ( fcx. tcx . hir ( ) . get_parent_node ( parent_id) ) ;
1247- if fcx. get_node_fn_decl ( parent) . is_some ( ) && !pointing_at_return_type {
1248- if let Some ( sp) = fcx. ret_coercion_span . borrow ( ) . as_ref ( ) {
1249- db. span_label ( * sp, reason_label) ;
1250- }
1251- }
12521221 }
1253- ObligationCauseCode :: ReturnType ( _id) => {
1254- db = fcx. report_mismatched_types ( cause, expected, found, err) ;
1255- let _id = fcx. tcx . hir ( ) . get_parent_node ( _id) ;
1256- let mut pointing_at_return_type = false ;
1257- if let Some ( ( fn_decl, can_suggest) ) = fcx. get_fn_decl ( _id) {
1258- pointing_at_return_type = fcx. suggest_missing_return_type (
1259- & mut db, & fn_decl, expected, found, can_suggest) ;
1260- }
1261- if let ( Some ( sp) , false ) = (
1262- fcx. ret_coercion_span . borrow ( ) . as_ref ( ) ,
1263- pointing_at_return_type,
1264- ) {
1265- if !sp. overlaps ( cause. span ) {
1266- db. span_label ( * sp, reason_label) ;
1267- }
1268- }
1222+ ObligationCauseCode :: ReturnType ( id) => {
1223+ db = self . report_return_mismatched_types (
1224+ cause, expected, found, err, fcx, id, None ) ;
12691225 }
12701226 _ => {
12711227 db = fcx. report_mismatched_types ( cause, expected, found, err) ;
@@ -1283,6 +1239,59 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
12831239 }
12841240 }
12851241
1242+ fn report_return_mismatched_types < ' a > (
1243+ & self ,
1244+ cause : & ObligationCause < ' tcx > ,
1245+ expected : Ty < ' tcx > ,
1246+ found : Ty < ' tcx > ,
1247+ err : TypeError < ' tcx > ,
1248+ fcx : & FnCtxt < ' a , ' gcx , ' tcx > ,
1249+ id : syntax:: ast:: NodeId ,
1250+ expression : Option < ( & ' gcx hir:: Expr , syntax:: ast:: NodeId ) > ,
1251+ ) -> DiagnosticBuilder < ' a > {
1252+ let mut db = fcx. report_mismatched_types ( cause, expected, found, err) ;
1253+
1254+ let mut pointing_at_return_type = false ;
1255+ let mut return_sp = None ;
1256+
1257+ // Verify that this is a tail expression of a function, otherwise the
1258+ // label pointing out the cause for the type coercion will be wrong
1259+ // as prior return coercions would not be relevant (#57664).
1260+ let parent_id = fcx. tcx . hir ( ) . get_parent_node ( id) ;
1261+ let fn_decl = if let Some ( ( expr, blk_id) ) = expression {
1262+ pointing_at_return_type = fcx. suggest_mismatched_types_on_tail (
1263+ & mut db,
1264+ expr,
1265+ expected,
1266+ found,
1267+ cause. span ,
1268+ blk_id,
1269+ ) ;
1270+ let parent = fcx. tcx . hir ( ) . get ( parent_id) ;
1271+ fcx. get_node_fn_decl ( parent) . map ( |( fn_decl, _, is_main) | ( fn_decl, is_main) )
1272+ } else {
1273+ fcx. get_fn_decl ( parent_id)
1274+ } ;
1275+
1276+ if let ( Some ( ( fn_decl, can_suggest) ) , _) = ( fn_decl, pointing_at_return_type) {
1277+ if expression. is_none ( ) {
1278+ pointing_at_return_type |= fcx. suggest_missing_return_type (
1279+ & mut db, & fn_decl, expected, found, can_suggest) ;
1280+ }
1281+ if !pointing_at_return_type {
1282+ return_sp = Some ( fn_decl. output . span ( ) ) ; // `impl Trait` return type
1283+ }
1284+ }
1285+ if let ( Some ( sp) , Some ( return_sp) ) = ( fcx. ret_coercion_span . borrow ( ) . as_ref ( ) , return_sp) {
1286+ db. span_label ( return_sp, "expected because this return type..." ) ;
1287+ db. span_label ( * sp, format ! (
1288+ "...is found to be `{}` here" ,
1289+ fcx. resolve_type_vars_with_obligations( expected) ,
1290+ ) ) ;
1291+ }
1292+ db
1293+ }
1294+
12861295 pub fn complete < ' a > ( self , fcx : & FnCtxt < ' a , ' gcx , ' tcx > ) -> Ty < ' tcx > {
12871296 if let Some ( final_ty) = self . final_ty {
12881297 final_ty
0 commit comments