bool_to_int_with_if inverse case patch

This commit is contained in:
Jacob Kiesel 2022-09-13 23:50:47 -06:00 committed by Jacob Kiesel
parent 2ddbc86bef
commit 1eb41804a2
4 changed files with 73 additions and 12 deletions

View File

@ -55,15 +55,28 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
if let ExprKind::If(check, then, Some(else_)) = expr.kind
&& let Some(then_lit) = int_literal(then)
&& let Some(else_lit) = int_literal(else_)
&& check_int_literal_equals_val(then_lit, 1)
&& check_int_literal_equals_val(else_lit, 0)
{
let inverted = if
check_int_literal_equals_val(then_lit, 1)
&& check_int_literal_equals_val(else_lit, 0) {
false
} else if
check_int_literal_equals_val(then_lit, 0)
&& check_int_literal_equals_val(else_lit, 1) {
true
} else {
// Expression isn't boolean, exit
return;
};
let mut applicability = Applicability::MachineApplicable;
let snippet = snippet_block_with_applicability(ctx, check.span, "..", None, &mut applicability);
let snippet_with_braces = {
let invert = if inverted { "!" } else { "" };
let need_parens = should_have_parentheses(check);
let snippet_with_braces = {
let (left_paren, right_paren) = if need_parens {("(", ")")} else {("", "")};
format!("{left_paren}{snippet}{right_paren}")
format!("{invert}{left_paren}{snippet}{right_paren}")
};
let ty = ctx.typeck_results().expr_ty(then_lit); // then and else must be of same type
@ -71,11 +84,14 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
let suggestion = {
let wrap_in_curly = is_else_clause(ctx.tcx, expr);
let (left_curly, right_curly) = if wrap_in_curly {("{", "}")} else {("", "")};
let (left_paren, right_paren) = if inverted && need_parens {("(", ")")} else {("", "")};
format!(
"{left_curly}{ty}::from({snippet}){right_curly}"
"{left_curly}{ty}::from({invert}{left_paren}{snippet}{right_paren}){right_curly}"
)
}; // when used in else clause if statement should be wrapped in curly braces
let (inverted_left_paren, inverted_right_paren) = if inverted {("(", ")")} else {("", "")};
span_lint_and_then(ctx,
BOOL_TO_INT_WITH_IF,
expr.span,
@ -87,7 +103,7 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
suggestion,
applicability,
);
diag.note(format!("`{snippet_with_braces} as {ty}` or `{snippet_with_braces}.into()` can also be valid options"));
diag.note(format!("`{snippet_with_braces} as {ty}` or `{inverted_left_paren}{snippet_with_braces}{inverted_right_paren}.into()` can also be valid options"));
});
};
}

View File

@ -14,6 +14,7 @@ fn main() {
// precedence
i32::from(a);
i32::from(!a);
i32::from(!a);
i32::from(a || b);
i32::from(cond(a, b));
i32::from(x + y < 4);
@ -23,6 +24,11 @@ fn main() {
123
} else {i32::from(b)};
// if else if inverted
if a {
123
} else {i32::from(!b)};
// Shouldn't lint
if a {

View File

@ -17,6 +17,11 @@ fn main() {
} else {
0
};
if a {
0
} else {
1
};
if !a {
1
} else {
@ -47,6 +52,15 @@ fn main() {
0
};
// if else if inverted
if a {
123
} else if b {
0
} else {
1
};
// Shouldn't lint
if a {

View File

@ -14,6 +14,18 @@ LL | | };
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:20:5
|
LL | / if a {
LL | | 0
LL | | } else {
LL | | 1
LL | | };
| |_____^ help: replace with from: `i32::from(!a)`
|
= note: `!a as i32` or `(!a).into()` can also be valid options
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:25:5
|
LL | / if !a {
LL | | 1
LL | | } else {
@ -24,7 +36,7 @@ LL | | };
= note: `!a as i32` or `!a.into()` can also be valid options
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:25:5
--> $DIR/bool_to_int_with_if.rs:30:5
|
LL | / if a || b {
LL | | 1
@ -36,7 +48,7 @@ LL | | };
= note: `(a || b) as i32` or `(a || b).into()` can also be valid options
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:30:5
--> $DIR/bool_to_int_with_if.rs:35:5
|
LL | / if cond(a, b) {
LL | | 1
@ -48,7 +60,7 @@ LL | | };
= note: `cond(a, b) as i32` or `cond(a, b).into()` can also be valid options
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:35:5
--> $DIR/bool_to_int_with_if.rs:40:5
|
LL | / if x + y < 4 {
LL | | 1
@ -60,7 +72,7 @@ LL | | };
= note: `(x + y < 4) as i32` or `(x + y < 4).into()` can also be valid options
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:44:12
--> $DIR/bool_to_int_with_if.rs:49:12
|
LL | } else if b {
| ____________^
@ -73,12 +85,25 @@ LL | | };
= note: `b as i32` or `b.into()` can also be valid options
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:102:5
--> $DIR/bool_to_int_with_if.rs:58:12
|
LL | } else if b {
| ____________^
LL | | 0
LL | | } else {
LL | | 1
LL | | };
| |_____^ help: replace with from: `{i32::from(!b)}`
|
= note: `!b as i32` or `(!b).into()` can also be valid options
error: boolean to int conversion using if
--> $DIR/bool_to_int_with_if.rs:116:5
|
LL | if a { 1 } else { 0 }
| ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)`
|
= note: `a as u8` or `a.into()` can also be valid options
error: aborting due to 7 previous errors
error: aborting due to 9 previous errors