Skip to content

Commit 8b93eb8

Browse files
committed
add some adjustment regarding review suggestion
1 parent 8e96ade commit 8b93eb8

File tree

4 files changed

+61
-35
lines changed

4 files changed

+61
-35
lines changed

clippy_lints/src/returns.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
1414
use rustc_span::def_id::LocalDefId;
1515
use rustc_span::source_map::Span;
1616
use rustc_span::{BytePos, Pos};
17+
use std::borrow::Cow;
1718

1819
declare_clippy_lint! {
1920
/// ### What it does
@@ -70,33 +71,39 @@ declare_clippy_lint! {
7071
}
7172

7273
#[derive(PartialEq, Eq, Clone)]
73-
enum RetReplacement {
74+
enum RetReplacement<'tcx> {
7475
Empty,
7576
Block,
7677
Unit,
77-
IfSequence(String),
78-
Expr(String),
78+
IfSequence(Cow<'tcx, str>, Applicability),
79+
Expr(Cow<'tcx, str>, Applicability),
7980
}
8081

81-
impl RetReplacement {
82+
impl<'tcx> RetReplacement<'tcx> {
8283
fn sugg_help(self) -> &'static str {
8384
match self {
84-
Self::Empty | Self::Expr(_) => "remove `return`",
85+
Self::Empty | Self::Expr(..) => "remove `return`",
8586
Self::Block => "replace `return` with an empty block",
8687
Self::Unit => "replace `return` with a unit value",
87-
Self::IfSequence(_) => "remove `return` and wrap the sequence with parentheses",
88+
Self::IfSequence(..) => "remove `return` and wrap the sequence with parentheses",
89+
}
90+
}
91+
fn applicability(&self) -> Option<Applicability> {
92+
match self {
93+
Self::Expr(_, ap) | Self::IfSequence(_, ap) => Some(*ap),
94+
_ => None,
8895
}
8996
}
9097
}
9198

92-
impl ToString for RetReplacement {
99+
impl<'tcx> ToString for RetReplacement<'tcx> {
93100
fn to_string(&self) -> String {
94101
match self {
95102
Self::Empty => String::new(),
96103
Self::Block => "{}".to_string(),
97104
Self::Unit => "()".to_string(),
98-
Self::IfSequence(inner) => format!("({inner})"),
99-
Self::Expr(inner) => inner.clone(),
105+
Self::IfSequence(inner, _) => format!("({inner})"),
106+
Self::Expr(inner, _) => inner.to_string(),
100107
}
101108
}
102109
}
@@ -208,7 +215,7 @@ fn check_final_expr<'tcx>(
208215
expr: &'tcx Expr<'tcx>,
209216
semi_spans: Vec<Span>, /* containing all the places where we would need to remove semicolons if finding an
210217
* needless return */
211-
replacement: RetReplacement,
218+
replacement: RetReplacement<'tcx>,
212219
) {
213220
let peeled_drop_expr = expr.peel_drop_temps();
214221
match &peeled_drop_expr.kind {
@@ -229,17 +236,12 @@ fn check_final_expr<'tcx>(
229236
return;
230237
}
231238

232-
let (snippet, _) = snippet_with_context(
233-
cx,
234-
inner_expr.span,
235-
ret_span.ctxt(),
236-
"..",
237-
&mut Applicability::MachineApplicable,
238-
);
239-
if expr_contains_if(inner_expr) {
240-
RetReplacement::IfSequence(snippet.to_string())
239+
let mut applicability = Applicability::MachineApplicable;
240+
let (snippet, _) = snippet_with_context(cx, inner_expr.span, ret_span.ctxt(), "..", &mut applicability);
241+
if expr_contains_conjunctive_ifs(inner_expr) {
242+
RetReplacement::IfSequence(snippet, applicability)
241243
} else {
242-
RetReplacement::Expr(snippet.to_string())
244+
RetReplacement::Expr(snippet, applicability)
243245
}
244246
} else {
245247
replacement
@@ -275,19 +277,23 @@ fn check_final_expr<'tcx>(
275277
}
276278
}
277279

278-
fn expr_contains_if<'tcx>(expr: &'tcx Expr<'tcx>) -> bool {
279-
match expr.kind {
280-
ExprKind::If(..) => true,
281-
ExprKind::Binary(_, left, right) => expr_contains_if(left) || expr_contains_if(right),
282-
_ => false,
280+
fn expr_contains_conjunctive_ifs<'tcx>(expr: &'tcx Expr<'tcx>) -> bool {
281+
fn contains_if(expr: &Expr<'_>, on_if: bool) -> bool {
282+
match expr.kind {
283+
ExprKind::If(..) => on_if,
284+
ExprKind::Binary(_, left, right) => contains_if(left, true) || contains_if(right, true),
285+
_ => false,
286+
}
283287
}
288+
289+
contains_if(expr, false)
284290
}
285291

286-
fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, semi_spans: Vec<Span>, replacement: RetReplacement) {
292+
fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, semi_spans: Vec<Span>, replacement: RetReplacement<'_>) {
287293
if ret_span.from_expansion() {
288294
return;
289295
}
290-
let applicability = Applicability::MachineApplicable;
296+
let applicability = replacement.applicability().unwrap_or(Applicability::MachineApplicable);
291297
let return_replacement = replacement.to_string();
292298
let sugg_help = replacement.sugg_help();
293299
span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded `return` statement", |diag| {

tests/ui/needless_return.fixed

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,14 @@ fn issue10051() -> Result<String, String> {
297297
}
298298
}
299299

300-
fn issue10049(b1: bool, b2: bool, b3: bool) -> u32 {
301-
(if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 })
300+
mod issue10049 {
301+
fn single() -> u32 {
302+
if true { 1 } else { 2 }
303+
}
304+
305+
fn multiple(b1: bool, b2: bool, b3: bool) -> u32 {
306+
(if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 })
307+
}
302308
}
303309

304310
fn main() {}

tests/ui/needless_return.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,14 @@ fn issue10051() -> Result<String, String> {
307307
}
308308
}
309309

310-
fn issue10049(b1: bool, b2: bool, b3: bool) -> u32 {
311-
return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };
310+
mod issue10049 {
311+
fn single() -> u32 {
312+
return if true { 1 } else { 2 };
313+
}
314+
315+
fn multiple(b1: bool, b2: bool, b3: bool) -> u32 {
316+
return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };
317+
}
312318
}
313319

314320
fn main() {}

tests/ui/needless_return.stderr

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,20 @@ LL | return Err(format!("err!"));
419419
= help: remove `return`
420420

421421
error: unneeded `return` statement
422-
--> $DIR/needless_return.rs:311:5
422+
--> $DIR/needless_return.rs:312:9
423423
|
424-
LL | return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };
425-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
424+
LL | return if true { 1 } else { 2 };
425+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
426+
|
427+
= help: remove `return`
428+
429+
error: unneeded `return` statement
430+
--> $DIR/needless_return.rs:316:9
431+
|
432+
LL | return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };
433+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
426434
|
427435
= help: remove `return` and wrap the sequence with parentheses
428436

429-
error: aborting due to 51 previous errors
437+
error: aborting due to 52 previous errors
430438

0 commit comments

Comments
 (0)