@@ -827,6 +827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
827
827
}
828
828
hir:: FnRetTy :: Return ( hir_ty) => {
829
829
if let hir:: TyKind :: OpaqueDef ( item_id, ..) = hir_ty. kind
830
+ // FIXME: account for RPITIT.
830
831
&& let hir:: Node :: Item ( hir:: Item {
831
832
kind : hir:: ItemKind :: OpaqueTy ( op_ty) , ..
832
833
} ) = self . tcx . hir_node ( item_id. hir_id ( ) )
@@ -1038,33 +1039,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1038
1039
return ;
1039
1040
}
1040
1041
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
+ } )
1067
1083
}
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
+ ) ;
1068
1098
}
1069
1099
}
1070
1100
0 commit comments