Skip to content

Commit bf8870e

Browse files
committed
further refactor of needless_return
1 parent d1dbdcf commit bf8870e

File tree

1 file changed

+22
-33
lines changed

1 file changed

+22
-33
lines changed

clippy_lints/src/returns.rs

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ impl RetReplacement {
7878
Self::Empty => "remove `return`",
7979
Self::Block => "replace `return` with an empty block",
8080
Self::Unit => "replace `return` with a unit value",
81-
8281
}
8382
}
8483
}
@@ -161,37 +160,33 @@ impl<'tcx> LateLintPass<'tcx> for Return {
161160
} else {
162161
RetReplacement::Empty
163162
};
164-
check_final_expr(cx, body.value, Some(body.value.span), replacement);
163+
check_final_expr(cx, body.value, body.value.span, replacement);
165164
},
166165
FnKind::ItemFn(..) | FnKind::Method(..) => {
167-
if let ExprKind::Block(block, _) = body.value.kind {
168-
check_block_return(cx, block);
169-
}
166+
check_block_return(cx, &body.value.kind);
170167
},
171168
}
172169
}
173170
}
174171

175-
fn check_block_return<'tcx>(cx: &LateContext<'tcx>, block: &Block<'tcx>) {
176-
if let Some(expr) = block.expr {
177-
check_final_expr(cx, expr, Some(expr.span), RetReplacement::Empty);
178-
} else if let Some(stmt) = block.stmts.iter().last() {
179-
match stmt.kind {
180-
StmtKind::Expr(expr) | StmtKind::Semi(expr) => {
181-
check_final_expr(cx, expr, Some(stmt.span), RetReplacement::Empty);
182-
},
183-
_ => (),
172+
// if `expr` is a block, check if there are needless returns in it
173+
fn check_block_return<'tcx>(cx: &LateContext<'tcx>, expr_kind: &ExprKind<'tcx>) {
174+
if let ExprKind::Block(block, _) = expr_kind {
175+
if let Some(block_expr) = block.expr {
176+
check_final_expr(cx, block_expr, block_expr.span, RetReplacement::Empty);
177+
} else if let Some(stmt) = block.stmts.iter().last() {
178+
match stmt.kind {
179+
StmtKind::Expr(expr) | StmtKind::Semi(expr) => {
180+
check_final_expr(cx, expr, stmt.span, RetReplacement::Empty);
181+
},
182+
_ => (),
183+
}
184184
}
185185
}
186186
}
187187

188-
fn check_final_expr<'tcx>(
189-
cx: &LateContext<'tcx>,
190-
expr: &'tcx Expr<'tcx>,
191-
span: Option<Span>,
192-
replacement: RetReplacement,
193-
) {
194-
match expr.kind {
188+
fn check_final_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, span: Span, replacement: RetReplacement) {
189+
match &expr.peel_drop_temps().kind {
195190
// simple return is always "bad"
196191
ExprKind::Ret(ref inner) => {
197192
if cx.tcx.hir().attrs(expr.hir_id).is_empty() {
@@ -200,23 +195,17 @@ fn check_final_expr<'tcx>(
200195
emit_return_lint(
201196
cx,
202197
inner.map_or(expr.hir_id, |inner| inner.hir_id),
203-
span.expect("`else return` is not possible"),
198+
span,
204199
inner.as_ref().map(|i| i.span),
205200
replacement,
206201
);
207202
}
208203
}
209204
},
210-
// a whole block? check it!
211-
ExprKind::Block(block, _) => {
212-
check_block_return(cx, block);
213-
},
214205
ExprKind::If(_, then, else_clause_opt) => {
215-
if let ExprKind::Block(ifblock, _) = then.kind {
216-
check_block_return(cx, ifblock);
217-
}
206+
check_block_return(cx, &then.kind);
218207
if let Some(else_clause) = else_clause_opt {
219-
check_final_expr(cx, else_clause, None, RetReplacement::Empty);
208+
check_block_return(cx, &else_clause.kind)
220209
}
221210
},
222211
// a match expr, check all arms
@@ -225,11 +214,11 @@ fn check_final_expr<'tcx>(
225214
// (except for unit type functions) so we don't match it
226215
ExprKind::Match(_, arms, MatchSource::Normal) => {
227216
for arm in arms.iter() {
228-
check_final_expr(cx, arm.body, Some(arm.body.span), RetReplacement::Unit);
217+
check_final_expr(cx, arm.body, arm.body.span, RetReplacement::Unit);
229218
}
230219
},
231-
ExprKind::DropTemps(expr) => check_final_expr(cx, expr, None, RetReplacement::Empty),
232-
_ => (),
220+
// if it's a whole block, check it
221+
other_expr_kind => check_block_return(cx, &other_expr_kind),
233222
}
234223
}
235224

0 commit comments

Comments
 (0)