@@ -1208,83 +1208,20 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
1208
1208
db. span_label ( cause. span , "return type is not `()`" ) ;
1209
1209
}
1210
1210
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,
1221
1214
expected,
1222
1215
found,
1223
- cause. span ,
1224
- blk_id,
1216
+ err,
1217
+ fcx,
1218
+ parent_id,
1219
+ expression. map ( |expr| ( expr, blk_id) ) ,
1225
1220
) ;
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
- }
1261
1221
}
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 ) ;
1288
1225
}
1289
1226
_ => {
1290
1227
db = fcx. report_mismatched_types ( cause, expected, found, err) ;
@@ -1302,6 +1239,59 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
1302
1239
}
1303
1240
}
1304
1241
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
+
1305
1295
pub fn complete < ' a > ( self , fcx : & FnCtxt < ' a , ' gcx , ' tcx > ) -> Ty < ' tcx > {
1306
1296
if let Some ( final_ty) = self . final_ty {
1307
1297
final_ty
0 commit comments