@@ -827,6 +827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
827827 }
828828 hir:: FnRetTy :: Return ( hir_ty) => {
829829 if let hir:: TyKind :: OpaqueDef ( item_id, ..) = hir_ty. kind
830+ // FIXME: account for RPITIT.
830831 && let hir:: Node :: Item ( hir:: Item {
831832 kind : hir:: ItemKind :: OpaqueTy ( op_ty) , ..
832833 } ) = self . tcx . hir_node ( item_id. hir_id ( ) )
@@ -1038,33 +1039,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10381039 return ;
10391040 }
10401041
1041- if let hir:: FnRetTy :: Return ( ty) = fn_decl. output {
1042- let ty = self . astconv ( ) . ast_ty_to_ty ( ty) ;
1043- let bound_vars = self . tcx . late_bound_vars ( fn_id) ;
1044- let ty = self
1045- . tcx
1046- . instantiate_bound_regions_with_erased ( Binder :: bind_with_vars ( ty, bound_vars) ) ;
1047- let ty = match self . tcx . asyncness ( fn_id. owner ) {
1048- ty:: Asyncness :: Yes => self . get_impl_future_output_ty ( ty) . unwrap_or_else ( || {
1049- span_bug ! ( fn_decl. output. span( ) , "failed to get output type of async function" )
1050- } ) ,
1051- ty:: Asyncness :: No => ty,
1052- } ;
1053- let ty = self . normalize ( expr. span , ty) ;
1054- if self . can_coerce ( found, ty) {
1055- if let Some ( owner_node) = self . tcx . hir_node ( fn_id) . as_owner ( )
1056- && let Some ( span) = expr. span . find_ancestor_inside ( * owner_node. span ( ) )
1057- {
1058- err. multipart_suggestion (
1059- "you might have meant to return this value" ,
1060- vec ! [
1061- ( span. shrink_to_lo( ) , "return " . to_string( ) ) ,
1062- ( span. shrink_to_hi( ) , ";" . to_string( ) ) ,
1063- ] ,
1064- Applicability :: MaybeIncorrect ,
1065- ) ;
1066- }
1042+ let scope = self
1043+ . tcx
1044+ . hir ( )
1045+ . parent_iter ( id)
1046+ . filter ( |( _, node) | {
1047+ matches ! (
1048+ node,
1049+ Node :: Expr ( Expr { kind: ExprKind :: Closure ( ..) , .. } )
1050+ | Node :: Item ( _)
1051+ | Node :: TraitItem ( _)
1052+ | Node :: ImplItem ( _)
1053+ )
1054+ } )
1055+ . next ( ) ;
1056+ let in_closure =
1057+ matches ! ( scope, Some ( ( _, Node :: Expr ( Expr { kind: ExprKind :: Closure ( ..) , .. } ) ) ) ) ;
1058+
1059+ let can_return = match fn_decl. output {
1060+ hir:: FnRetTy :: Return ( ty) => {
1061+ let ty = self . astconv ( ) . ast_ty_to_ty ( ty) ;
1062+ let bound_vars = self . tcx . late_bound_vars ( fn_id) ;
1063+ let ty = self
1064+ . tcx
1065+ . instantiate_bound_regions_with_erased ( Binder :: bind_with_vars ( ty, bound_vars) ) ;
1066+ let ty = match self . tcx . asyncness ( fn_id. owner ) {
1067+ ty:: Asyncness :: Yes => self . get_impl_future_output_ty ( ty) . unwrap_or_else ( || {
1068+ span_bug ! (
1069+ fn_decl. output. span( ) ,
1070+ "failed to get output type of async function"
1071+ )
1072+ } ) ,
1073+ ty:: Asyncness :: No => ty,
1074+ } ;
1075+ let ty = self . normalize ( expr. span , ty) ;
1076+ self . can_coerce ( found, ty)
1077+ }
1078+ hir:: FnRetTy :: DefaultReturn ( _) if in_closure => {
1079+ self . ret_coercion . as_ref ( ) . map_or ( false , |ret| {
1080+ let ret_ty = ret. borrow ( ) . expected_ty ( ) ;
1081+ self . can_coerce ( found, ret_ty)
1082+ } )
10671083 }
1084+ _ => false ,
1085+ } ;
1086+ if can_return
1087+ && let Some ( owner_node) = self . tcx . hir_node ( fn_id) . as_owner ( )
1088+ && let Some ( span) = expr. span . find_ancestor_inside ( * owner_node. span ( ) )
1089+ {
1090+ err. multipart_suggestion (
1091+ "you might have meant to return this value" ,
1092+ vec ! [
1093+ ( span. shrink_to_lo( ) , "return " . to_string( ) ) ,
1094+ ( span. shrink_to_hi( ) , ";" . to_string( ) ) ,
1095+ ] ,
1096+ Applicability :: MaybeIncorrect ,
1097+ ) ;
10681098 }
10691099 }
10701100
0 commit comments