1
1
use super :: FnCtxt ;
2
2
3
- use crate :: coercion:: CollectRetsVisitor ;
4
3
use crate :: errors;
5
4
use crate :: fluent_generated as fluent;
6
5
use crate :: fn_ctxt:: rustc_span:: BytePos ;
@@ -17,7 +16,6 @@ use rustc_errors::{Applicability, Diagnostic, MultiSpan};
17
16
use rustc_hir as hir;
18
17
use rustc_hir:: def:: Res ;
19
18
use rustc_hir:: def:: { CtorKind , CtorOf , DefKind } ;
20
- use rustc_hir:: intravisit:: { Map , Visitor } ;
21
19
use rustc_hir:: lang_items:: LangItem ;
22
20
use rustc_hir:: {
23
21
CoroutineDesugaring , CoroutineKind , CoroutineSource , Expr , ExprKind , GenericBound , HirId , Node ,
@@ -1042,22 +1040,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1042
1040
return ;
1043
1041
}
1044
1042
1045
- let in_closure = matches ! (
1046
- self . tcx
1047
- . hir( )
1048
- . parent_iter( id)
1049
- . filter( |( _, node) | {
1050
- matches!(
1051
- node,
1052
- Node :: Expr ( Expr { kind: ExprKind :: Closure ( ..) , .. } )
1053
- | Node :: Item ( _)
1054
- | Node :: TraitItem ( _)
1055
- | Node :: ImplItem ( _)
1056
- )
1057
- } )
1058
- . next( ) ,
1059
- Some ( ( _ , Node :: Expr ( Expr { kind : ExprKind :: Closure ( .. ) , .. } ) ) )
1060
- ) ;
1043
+ let scope = self
1044
+ . tcx
1045
+ . hir ( )
1046
+ . parent_iter ( id)
1047
+ . filter ( |( _, node) | {
1048
+ matches ! (
1049
+ node,
1050
+ Node :: Expr ( Expr { kind: ExprKind :: Closure ( ..) , .. } )
1051
+ | Node :: Item ( _)
1052
+ | Node :: TraitItem ( _)
1053
+ | Node :: ImplItem ( _)
1054
+ )
1055
+ } )
1056
+ . next ( ) ;
1057
+ let in_closure =
1058
+ matches ! ( scope , Some ( ( _ , Node :: Expr ( Expr { kind : ExprKind :: Closure ( .. ) , .. } ) ) ) ) ;
1061
1059
1062
1060
let can_return = match fn_decl. output {
1063
1061
hir:: FnRetTy :: Return ( ty) => {
@@ -1079,35 +1077,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1079
1077
self . can_coerce ( found, ty)
1080
1078
}
1081
1079
hir:: FnRetTy :: DefaultReturn ( _) if in_closure => {
1082
- let mut rets = vec ! [ ] ;
1083
- if let Some ( ret_coercion) = self . ret_coercion . as_ref ( ) {
1084
- let ret_ty = ret_coercion. borrow ( ) . expected_ty ( ) ;
1085
- rets. push ( ret_ty) ;
1086
- }
1087
- let mut visitor = CollectRetsVisitor { ret_exprs : vec ! [ ] } ;
1088
- if let Some ( item) = self . tcx . hir ( ) . find ( id)
1089
- && let Node :: Expr ( expr) = item
1090
- {
1091
- visitor. visit_expr ( expr) ;
1092
- for expr in visitor. ret_exprs {
1093
- if let Some ( ty) = self . typeck_results . borrow ( ) . node_type_opt ( expr. hir_id ) {
1094
- rets. push ( ty) ;
1095
- }
1096
- }
1097
- if let hir:: ExprKind :: Block ( hir:: Block { expr : Some ( expr) , .. } , _) = expr. kind
1098
- {
1099
- if let Some ( ty) = self . typeck_results . borrow ( ) . node_type_opt ( expr. hir_id ) {
1100
- rets. push ( ty) ;
1101
- }
1102
- }
1103
- }
1104
- rets. into_iter ( ) . all ( |ty| self . can_coerce ( found, ty) )
1080
+ self . ret_coercion . as_ref ( ) . map_or ( false , |ret| {
1081
+ let ret_ty = ret. borrow ( ) . expected_ty ( ) ;
1082
+ self . can_coerce ( found, ret_ty)
1083
+ } )
1105
1084
}
1106
1085
_ => false ,
1107
1086
} ;
1108
1087
if can_return
1109
1088
&& let Some ( owner_node) = self . tcx . hir_node ( fn_id) . as_owner ( )
1110
- && let Some ( span) = expr. span . find_ancestor_inside ( owner_node. span ( ) )
1089
+ && let Some ( span) = expr. span . find_ancestor_inside ( * owner_node. span ( ) )
1111
1090
{
1112
1091
err. multipart_suggestion (
1113
1092
"you might have meant to return this value" ,
0 commit comments