@@ -42,6 +42,9 @@ declare_clippy_lint! {
4242
4343declare_lint_pass ! ( ImplicitReturn => [ IMPLICIT_RETURN ] ) ;
4444
45+ static LINT_BREAK : & str = "change `break` to `return` as shown" ;
46+ static LINT_RETURN : & str = "add `return` as shown" ;
47+
4548fn lint ( cx : & LateContext < ' _ , ' _ > , outer_span : Span , inner_span : Span , msg : & str ) {
4649 let outer_span = span_to_outer_expn ( outer_span) ;
4750 let inner_span = span_to_outer_expn ( inner_span) ;
@@ -66,12 +69,12 @@ fn span_to_outer_expn(span: Span) -> Span {
6669 }
6770}
6871
69- fn expr_match ( cx : & LateContext < ' _ , ' _ > , expr : & Expr , ret_ty_is_never : bool ) {
72+ fn expr_match ( cx : & LateContext < ' _ , ' _ > , expr : & Expr ) {
7073 match & expr. node {
7174 // loops could be using `break` instead of `return`
7275 ExprKind :: Block ( block, ..) | ExprKind :: Loop ( block, ..) => {
7376 if let Some ( expr) = & block. expr {
74- expr_match ( cx, expr, ret_ty_is_never ) ;
77+ expr_match ( cx, expr) ;
7578 }
7679 // only needed in the case of `break` with `;` at the end
7780 else if let Some ( stmt) = block. stmts . last ( ) {
@@ -81,15 +84,15 @@ fn expr_match(cx: &LateContext<'_, '_>, expr: &Expr, ret_ty_is_never: bool) {
8184 if let ExprKind :: Break ( .., break_expr) = & expr. node;
8285 if let Some ( break_expr) = break_expr;
8386 then {
84- lint( cx, expr. span, break_expr. span, "change `break` to `return` as shown" ) ;
87+ lint( cx, expr. span, break_expr. span, LINT_BREAK ) ;
8588 }
8689 }
8790 }
8891 } ,
8992 // use `return` instead of `break`
9093 ExprKind :: Break ( .., break_expr) => {
9194 if let Some ( break_expr) = break_expr {
92- lint ( cx, expr. span , break_expr. span , "change `break` to `return` as shown" ) ;
95+ lint ( cx, expr. span , break_expr. span , LINT_BREAK ) ;
9396 }
9497 } ,
9598 ExprKind :: Match ( .., arms, source) => {
@@ -102,38 +105,29 @@ fn expr_match(cx: &LateContext<'_, '_>, expr: &Expr, ret_ty_is_never: bool) {
102105
103106 if check_all_arms {
104107 for arm in arms {
105- expr_match ( cx, & arm. body , ret_ty_is_never ) ;
108+ expr_match ( cx, & arm. body ) ;
106109 }
107110 } else {
108- expr_match (
109- cx,
110- & arms. first ( ) . expect ( "if let doesn't have a single arm" ) . body ,
111- ret_ty_is_never,
112- ) ;
111+ expr_match ( cx, & arms. first ( ) . expect ( "if let doesn't have a single arm" ) . body ) ;
113112 }
114113 } ,
115114 // skip if it already has a return statement
116115 ExprKind :: Ret ( ..) => ( ) ,
117- // make sure it's not a call that panics unless we intend to return a panic
116+ // make sure it's not a call that panics
118117 ExprKind :: Call ( expr, ..) => {
119118 if_chain ! {
120119 if let ExprKind :: Path ( qpath) = & expr. node;
121120 if let Some ( path_def_id) = resolve_node( cx, qpath, expr. hir_id) . opt_def_id( ) ;
122121 if match_def_path( cx, path_def_id, & BEGIN_PANIC ) ||
123122 match_def_path( cx, path_def_id, & BEGIN_PANIC_FMT ) ;
124- then {
125- // only put `return` on panics if the return type of the function/closure is a panic
126- if ret_ty_is_never {
127- lint( cx, expr. span, expr. span, "add `return` as shown" )
128- }
129- }
123+ then { }
130124 else {
131- lint( cx, expr. span, expr. span, "add `return` as shown" )
125+ lint( cx, expr. span, expr. span, LINT_RETURN )
132126 }
133127 }
134128 } ,
135129 // everything else is missing `return`
136- _ => lint ( cx, expr. span , expr. span , "add `return` as shown" ) ,
130+ _ => lint ( cx, expr. span , expr. span , LINT_RETURN ) ,
137131 }
138132}
139133
@@ -149,12 +143,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitReturn {
149143 ) {
150144 let def_id = cx. tcx . hir ( ) . body_owner_def_id ( body. id ( ) ) ;
151145 let mir = cx. tcx . optimized_mir ( def_id) ;
152- let ret_ty = mir. return_ty ( ) ;
153146
154147 // checking return type through MIR, HIR is not able to determine inferred closure return types
155148 // make sure it's not a macro
156- if !ret_ty . is_unit ( ) && !in_macro_or_desugar ( span) {
157- expr_match ( cx, & body. value , ret_ty . is_never ( ) ) ;
149+ if !mir . return_ty ( ) . is_unit ( ) && !in_macro_or_desugar ( span) {
150+ expr_match ( cx, & body. value ) ;
158151 }
159152 }
160153}
0 commit comments