Auto merge of #7095 - Y-Nak:match_single_binding, r=giraffate

match_single_binding: Fix invalid suggestion when match scrutinee has side effects

fixes #7094

changelog: `match_single_binding`: Fix invalid suggestion when match scrutinee has side effects

---
`Expr::can_have_side_effects` is used to determine the scrutinee has side effects, while this method is a little bit conservative for our use case. But I'd like to use it to avoid reimplementation of the method and too much heuristics. If you think this is problematic, then I'll implement a custom visitor to address it.
This commit is contained in:
bors 2021-05-13 13:55:47 +00:00
commit 1fd9975249
7 changed files with 100 additions and 35 deletions

View file

@ -1478,15 +1478,34 @@ fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[A
); );
}, },
PatKind::Wild => { PatKind::Wild => {
span_lint_and_sugg( if ex.can_have_side_effects() {
cx, let indent = " ".repeat(indent_of(cx, expr.span).unwrap_or(0));
MATCH_SINGLE_BINDING, let sugg = format!(
expr.span, "{};\n{}{}",
"this match could be replaced by its body itself", snippet_with_applicability(cx, ex.span, "..", &mut applicability),
"consider using the match body instead", indent,
snippet_body, snippet_body
Applicability::MachineApplicable, );
); span_lint_and_sugg(
cx,
MATCH_SINGLE_BINDING,
expr.span,
"this match could be replaced by its scrutinee and body",
"consider using the scrutinee and body instead",
sugg,
applicability,
)
} else {
span_lint_and_sugg(
cx,
MATCH_SINGLE_BINDING,
expr.span,
"this match could be replaced by its body itself",
"consider using the match body instead",
snippet_body,
Applicability::MachineApplicable,
);
}
}, },
_ => (), _ => (),
} }

View file

@ -94,10 +94,7 @@ fn main() {
0 => println!("Disabled branch"), 0 => println!("Disabled branch"),
_ => println!("Enabled branch"), _ => println!("Enabled branch"),
} }
// Lint
let x = 1;
let y = 1;
println!("Single branch");
// Ok // Ok
let x = 1; let x = 1;
let y = 1; let y = 1;

View file

@ -106,15 +106,7 @@ fn main() {
0 => println!("Disabled branch"), 0 => println!("Disabled branch"),
_ => println!("Enabled branch"), _ => println!("Enabled branch"),
} }
// Lint
let x = 1;
let y = 1;
match match y {
0 => 1,
_ => 2,
} {
_ => println!("Single branch"),
}
// Ok // Ok
let x = 1; let x = 1;
let y = 1; let y = 1;

View file

@ -167,16 +167,5 @@ LL | unwrapped
LL | }) LL | })
| |
error: this match could be replaced by its body itself error: aborting due to 11 previous errors
--> $DIR/match_single_binding.rs:112:5
|
LL | / match match y {
LL | | 0 => 1,
LL | | _ => 2,
LL | | } {
LL | | _ => println!("Single branch"),
LL | | }
| |_____^ help: consider using the match body instead: `println!("Single branch");`
error: aborting due to 12 previous errors

View file

@ -34,4 +34,20 @@ fn main() {
}, },
None => println!("nothing"), None => println!("nothing"),
} }
fn side_effects() {}
// Lint (scrutinee has side effects)
// issue #7094
side_effects();
println!("Side effects");
// Lint (scrutinee has side effects)
// issue #7094
let x = 1;
match x {
0 => 1,
_ => 2,
};
println!("Single branch");
} }

View file

@ -34,4 +34,22 @@ fn main() {
}, },
None => println!("nothing"), None => println!("nothing"),
} }
fn side_effects() {}
// Lint (scrutinee has side effects)
// issue #7094
match side_effects() {
_ => println!("Side effects"),
}
// Lint (scrutinee has side effects)
// issue #7094
let x = 1;
match match x {
0 => 1,
_ => 2,
} {
_ => println!("Single branch"),
}
} }

View file

@ -30,5 +30,39 @@ LL | let (a, b) = get_tup();
LL | println!("a {:?} and b {:?}", a, b); LL | println!("a {:?} and b {:?}", a, b);
| |
error: aborting due to 2 previous errors error: this match could be replaced by its scrutinee and body
--> $DIR/match_single_binding2.rs:42:5
|
LL | / match side_effects() {
LL | | _ => println!("Side effects"),
LL | | }
| |_____^
|
help: consider using the scrutinee and body instead
|
LL | side_effects();
LL | println!("Side effects");
|
error: this match could be replaced by its scrutinee and body
--> $DIR/match_single_binding2.rs:49:5
|
LL | / match match x {
LL | | 0 => 1,
LL | | _ => 2,
LL | | } {
LL | | _ => println!("Single branch"),
LL | | }
| |_____^
|
help: consider using the scrutinee and body instead
|
LL | match x {
LL | 0 => 1,
LL | _ => 2,
LL | };
LL | println!("Single branch");
|
error: aborting due to 4 previous errors