feat(zero_repeat_side_effects): don't suggest unnecessary braces around stmts (#15826)
changelog: [`(zero_repeat_side_effects`]: don't suggest unnecessary braces around stmts r? @samueltardieu
This commit is contained in:
commit
7c7bd6ea8a
6 changed files with 89 additions and 51 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::higher::VecArgs;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::source::{snippet, snippet_indent};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -77,24 +77,36 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr:
|
|||
let return_type = cx.typeck_results().expr_ty(expr);
|
||||
|
||||
let inner_expr = snippet(cx, inner_expr.span.source_callsite(), "..");
|
||||
let indent = snippet_indent(cx, expr.span).unwrap_or_default();
|
||||
let vec = if is_vec { "vec!" } else { "" };
|
||||
|
||||
let (span, sugg) = match parent_hir_node {
|
||||
Node::LetStmt(l) => (
|
||||
l.span,
|
||||
format!(
|
||||
"{inner_expr}; let {var_name}: {return_type} = {vec}[];",
|
||||
"{inner_expr};\n{indent}let {var_name}: {return_type} = {vec}[];",
|
||||
var_name = snippet(cx, l.pat.span.source_callsite(), "..")
|
||||
),
|
||||
),
|
||||
Node::Expr(x) if let ExprKind::Assign(l, _, _) = x.kind => (
|
||||
x.span,
|
||||
format!(
|
||||
"{inner_expr}; {var_name} = {vec}[] as {return_type}",
|
||||
"{inner_expr};\n{indent}{var_name} = {vec}[] as {return_type}",
|
||||
var_name = snippet(cx, l.span.source_callsite(), "..")
|
||||
),
|
||||
),
|
||||
_ => (expr.span, format!("{{ {inner_expr}; {vec}[] as {return_type} }}")),
|
||||
// NOTE: don't use the stmt span to avoid touching the trailing semicolon
|
||||
Node::Stmt(_) => (expr.span, format!("{inner_expr};\n{indent}{vec}[] as {return_type}")),
|
||||
_ => (
|
||||
expr.span,
|
||||
format!(
|
||||
"\
|
||||
{{
|
||||
{indent} {inner_expr};
|
||||
{indent} {vec}[] as {return_type}
|
||||
{indent}}}"
|
||||
),
|
||||
),
|
||||
};
|
||||
let span = span.source_callsite();
|
||||
span_lint_and_then(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#![warn(clippy::zero_repeat_side_effects)]
|
||||
#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)]
|
||||
#![allow(clippy::no_effect)] // only fires _after_ the fix
|
||||
|
||||
fn f() -> i32 {
|
||||
println!("side effect");
|
||||
|
|
@ -13,36 +14,47 @@ fn main() {
|
|||
// should trigger
|
||||
|
||||
// on arrays
|
||||
f(); let a: [i32; 0] = [];
|
||||
f();
|
||||
let a: [i32; 0] = [];
|
||||
//~^ zero_repeat_side_effects
|
||||
let mut b;
|
||||
f(); b = [] as [i32; 0];
|
||||
f();
|
||||
b = [] as [i32; 0];
|
||||
//~^ zero_repeat_side_effects
|
||||
|
||||
// on vecs
|
||||
// vecs dont support inferring value of consts
|
||||
f(); let c: std::vec::Vec<i32> = vec![];
|
||||
f();
|
||||
let c: std::vec::Vec<i32> = vec![];
|
||||
//~^ zero_repeat_side_effects
|
||||
let d;
|
||||
f(); d = vec![] as std::vec::Vec<i32>;
|
||||
f();
|
||||
d = vec![] as std::vec::Vec<i32>;
|
||||
//~^ zero_repeat_side_effects
|
||||
|
||||
// for macros
|
||||
println!("side effect"); let e: [(); 0] = [];
|
||||
println!("side effect");
|
||||
let e: [(); 0] = [];
|
||||
//~^ zero_repeat_side_effects
|
||||
|
||||
// for nested calls
|
||||
{ f() }; let g: [i32; 0] = [];
|
||||
{ f() };
|
||||
let g: [i32; 0] = [];
|
||||
//~^ zero_repeat_side_effects
|
||||
|
||||
// as function param
|
||||
drop({ f(); vec![] as std::vec::Vec<i32> });
|
||||
drop({
|
||||
f();
|
||||
vec![] as std::vec::Vec<i32>
|
||||
});
|
||||
//~^ zero_repeat_side_effects
|
||||
|
||||
// when singled out/not part of assignment/local
|
||||
{ f(); vec![] as std::vec::Vec<i32> };
|
||||
f();
|
||||
vec![] as std::vec::Vec<i32>;
|
||||
//~^ zero_repeat_side_effects
|
||||
{ f(); [] as [i32; 0] };
|
||||
f();
|
||||
[] as [i32; 0];
|
||||
//~^ zero_repeat_side_effects
|
||||
|
||||
// should not trigger
|
||||
|
|
@ -96,8 +108,14 @@ fn issue_14681() {
|
|||
|
||||
foo(&[Some(0i64); 0]);
|
||||
foo(&[Some(Some(0i64)); 0]);
|
||||
foo(&{ Some(f()); [] as [std::option::Option<i32>; 0] });
|
||||
foo(&{
|
||||
Some(f());
|
||||
[] as [std::option::Option<i32>; 0]
|
||||
});
|
||||
//~^ zero_repeat_side_effects
|
||||
foo(&{ Some(Some(S::new())); [] as [std::option::Option<std::option::Option<S>>; 0] });
|
||||
foo(&{
|
||||
Some(Some(S::new()));
|
||||
[] as [std::option::Option<std::option::Option<S>>; 0]
|
||||
});
|
||||
//~^ zero_repeat_side_effects
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#![warn(clippy::zero_repeat_side_effects)]
|
||||
#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)]
|
||||
#![allow(clippy::no_effect)] // only fires _after_ the fix
|
||||
|
||||
fn f() -> i32 {
|
||||
println!("side effect");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:16:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:17:5
|
||||
|
|
||||
LL | let a = [f(); 0];
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -8,128 +8,134 @@ LL | let a = [f(); 0];
|
|||
= help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - let a = [f(); 0];
|
||||
LL + f(); let a: [i32; 0] = [];
|
||||
LL ~ f();
|
||||
LL + let a: [i32; 0] = [];
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:19:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:20:5
|
||||
|
|
||||
LL | b = [f(); 0];
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - b = [f(); 0];
|
||||
LL + f(); b = [] as [i32; 0];
|
||||
LL ~ f();
|
||||
LL ~ b = [] as [i32; 0];
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:24:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:25:5
|
||||
|
|
||||
LL | let c = vec![f(); 0];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - let c = vec![f(); 0];
|
||||
LL + f(); let c: std::vec::Vec<i32> = vec![];
|
||||
LL ~ f();
|
||||
LL + let c: std::vec::Vec<i32> = vec![];
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:27:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:28:5
|
||||
|
|
||||
LL | d = vec![f(); 0];
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - d = vec![f(); 0];
|
||||
LL + f(); d = vec![] as std::vec::Vec<i32>;
|
||||
LL ~ f();
|
||||
LL ~ d = vec![] as std::vec::Vec<i32>;
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:31:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:32:5
|
||||
|
|
||||
LL | let e = [println!("side effect"); 0];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - let e = [println!("side effect"); 0];
|
||||
LL + println!("side effect"); let e: [(); 0] = [];
|
||||
LL ~ println!("side effect");
|
||||
LL + let e: [(); 0] = [];
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:35:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:36:5
|
||||
|
|
||||
LL | let g = [{ f() }; 0];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - let g = [{ f() }; 0];
|
||||
LL + { f() }; let g: [i32; 0] = [];
|
||||
LL ~ { f() };
|
||||
LL + let g: [i32; 0] = [];
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:39:10
|
||||
--> tests/ui/zero_repeat_side_effects.rs:40:10
|
||||
|
|
||||
LL | drop(vec![f(); 0]);
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - drop(vec![f(); 0]);
|
||||
LL + drop({ f(); vec![] as std::vec::Vec<i32> });
|
||||
LL ~ drop({
|
||||
LL + f();
|
||||
LL + vec![] as std::vec::Vec<i32>
|
||||
LL ~ });
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:43:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:44:5
|
||||
|
|
||||
LL | vec![f(); 0];
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - vec![f(); 0];
|
||||
LL + { f(); vec![] as std::vec::Vec<i32> };
|
||||
LL ~ f();
|
||||
LL ~ vec![] as std::vec::Vec<i32>;
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:45:5
|
||||
--> tests/ui/zero_repeat_side_effects.rs:46:5
|
||||
|
|
||||
LL | [f(); 0];
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - [f(); 0];
|
||||
LL + { f(); [] as [i32; 0] };
|
||||
LL ~ f();
|
||||
LL ~ [] as [i32; 0];
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:99:10
|
||||
--> tests/ui/zero_repeat_side_effects.rs:100:10
|
||||
|
|
||||
LL | foo(&[Some(f()); 0]);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - foo(&[Some(f()); 0]);
|
||||
LL + foo(&{ Some(f()); [] as [std::option::Option<i32>; 0] });
|
||||
LL ~ foo(&{
|
||||
LL + Some(f());
|
||||
LL + [] as [std::option::Option<i32>; 0]
|
||||
LL ~ });
|
||||
|
|
||||
|
||||
error: expression with side effects as the initial value in a zero-sized array initializer
|
||||
--> tests/ui/zero_repeat_side_effects.rs:101:10
|
||||
--> tests/ui/zero_repeat_side_effects.rs:102:10
|
||||
|
|
||||
LL | foo(&[Some(Some(S::new())); 0]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - foo(&[Some(Some(S::new())); 0]);
|
||||
LL + foo(&{ Some(Some(S::new())); [] as [std::option::Option<std::option::Option<S>>; 0] });
|
||||
LL ~ foo(&{
|
||||
LL + Some(Some(S::new()));
|
||||
LL + [] as [std::option::Option<std::option::Option<S>>; 0]
|
||||
LL ~ });
|
||||
|
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
fn issue_14998() {
|
||||
// nameable type thanks to `never_type` being enabled, suggest
|
||||
panic!(); let _data: [!; 0] = [];
|
||||
panic!();
|
||||
let _data: [!; 0] = [];
|
||||
//~^ zero_repeat_side_effects
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ LL | let _data = [panic!(); 0];
|
|||
= help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`
|
||||
help: consider performing the side effect separately
|
||||
|
|
||||
LL - let _data = [panic!(); 0];
|
||||
LL + panic!(); let _data: [!; 0] = [];
|
||||
LL ~ panic!();
|
||||
LL + let _data: [!; 0] = [];
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue