@@ -1208,83 +1208,20 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
12081208 db. span_label ( cause. span , "return type is not `()`" ) ;
12091209 }
12101210 ObligationCauseCode :: BlockTailExpression ( blk_id) => {
1211- db = fcx. report_mismatched_types ( cause, expected, found, err) ;
1212-
1213- let expr = expression. unwrap_or_else ( || {
1214- span_bug ! ( cause. span,
1215- "supposed to be part of a block tail expression, but the \
1216- expression is empty") ;
1217- } ) ;
1218- let pointing_at_return_type = fcx. suggest_mismatched_types_on_tail (
1219- & mut db,
1220- expr,
1211+ let parent_id = fcx. tcx . hir ( ) . get_parent_node ( blk_id) ;
1212+ db = self . report_return_mismatched_types (
1213+ cause,
12211214 expected,
12221215 found,
1223- cause. span ,
1224- blk_id,
1216+ err,
1217+ fcx,
1218+ parent_id,
1219+ expression. map ( |expr| ( expr, blk_id) ) ,
12251220 ) ;
1226- // FIXME: replace with navigating up the chain until hitting an fn or
1227- // bailing if no "pass-through" Node is found, in order to provide a
1228- // suggestion when encountering something like:
1229- // ```
1230- // fn foo(a: bool) -> impl Debug {
1231- // if a {
1232- // bar()?;
1233- // }
1234- // {
1235- // let x = unsafe { bar() };
1236- // x
1237- // }
1238- // }
1239- // ```
1240- //
1241- // Verify that this is a tail expression of a function, otherwise the
1242- // label pointing out the cause for the type coercion will be wrong
1243- // as prior return coercions would not be relevant (#57664).
1244- let parent_id = fcx. tcx . hir ( ) . get_parent_node ( blk_id) ;
1245- let parent = fcx. tcx . hir ( ) . get ( fcx. tcx . hir ( ) . get_parent_node ( parent_id) ) ;
1246- if let ( Some ( ( fn_decl, _, _) ) , false ) = (
1247- fcx. get_node_fn_decl ( parent) ,
1248- pointing_at_return_type,
1249- ) {
1250- if let Some ( sp) = fcx. ret_coercion_span . borrow ( ) . as_ref ( ) {
1251- db. span_label (
1252- fn_decl. output . span ( ) ,
1253- "expected because this return type..." ,
1254- ) ;
1255- db. span_label ( * sp, format ! (
1256- "...is found to be `{}` here" ,
1257- fcx. resolve_type_vars_with_obligations( expected) ,
1258- ) ) ;
1259- }
1260- }
12611221 }
1262- ObligationCauseCode :: ReturnType ( _id) => {
1263- db = fcx. report_mismatched_types ( cause, expected, found, err) ;
1264- let _id = fcx. tcx . hir ( ) . get_parent_node ( _id) ;
1265- let mut pointing_at_return_type = false ;
1266- let mut return_sp = None ;
1267- if let Some ( ( fn_decl, can_suggest) ) = fcx. get_fn_decl ( _id) {
1268- pointing_at_return_type = fcx. suggest_missing_return_type (
1269- & mut db, & fn_decl, expected, found, can_suggest) ;
1270- if !pointing_at_return_type {
1271- return_sp = Some ( fn_decl. output . span ( ) ) ; // `impl Trait` return type
1272- }
1273- }
1274- if let ( Some ( sp) , false ) = (
1275- fcx. ret_coercion_span . borrow ( ) . as_ref ( ) ,
1276- pointing_at_return_type,
1277- ) {
1278- if let Some ( return_sp) = return_sp {
1279- db. span_label ( return_sp, "expected because this return type..." ) ;
1280- db. span_label ( * sp, format ! (
1281- "...is found to be `{}` here" ,
1282- fcx. resolve_type_vars_with_obligations( expected) ,
1283- ) ) ;
1284- } else if !sp. overlaps ( cause. span ) {
1285- db. span_label ( * sp, "expected because of this statement" ) ;
1286- }
1287- }
1222+ ObligationCauseCode :: ReturnType ( id) => {
1223+ db = self . report_return_mismatched_types (
1224+ cause, expected, found, err, fcx, id, None ) ;
12881225 }
12891226 _ => {
12901227 db = fcx. report_mismatched_types ( cause, expected, found, err) ;
@@ -1302,6 +1239,59 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
13021239 }
13031240 }
13041241
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+
13051295 pub fn complete < ' a > ( self , fcx : & FnCtxt < ' a , ' gcx , ' tcx > ) -> Ty < ' tcx > {
13061296 if let Some ( final_ty) = self . final_ty {
13071297 final_ty
0 commit comments