Skip to content

Commit 7c7bd6e

Browse files
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
2 parents ebbbbeb + 6b076ca commit 7c7bd6e

6 files changed

+89
-51
lines changed

clippy_lints/src/zero_repeat_side_effects.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::higher::VecArgs;
3-
use clippy_utils::source::snippet;
3+
use clippy_utils::source::{snippet, snippet_indent};
44
use rustc_ast::LitKind;
55
use rustc_data_structures::packed::Pu128;
66
use rustc_errors::Applicability;
@@ -77,24 +77,36 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr:
7777
let return_type = cx.typeck_results().expr_ty(expr);
7878

7979
let inner_expr = snippet(cx, inner_expr.span.source_callsite(), "..");
80+
let indent = snippet_indent(cx, expr.span).unwrap_or_default();
8081
let vec = if is_vec { "vec!" } else { "" };
8182

8283
let (span, sugg) = match parent_hir_node {
8384
Node::LetStmt(l) => (
8485
l.span,
8586
format!(
86-
"{inner_expr}; let {var_name}: {return_type} = {vec}[];",
87+
"{inner_expr};\n{indent}let {var_name}: {return_type} = {vec}[];",
8788
var_name = snippet(cx, l.pat.span.source_callsite(), "..")
8889
),
8990
),
9091
Node::Expr(x) if let ExprKind::Assign(l, _, _) = x.kind => (
9192
x.span,
9293
format!(
93-
"{inner_expr}; {var_name} = {vec}[] as {return_type}",
94+
"{inner_expr};\n{indent}{var_name} = {vec}[] as {return_type}",
9495
var_name = snippet(cx, l.span.source_callsite(), "..")
9596
),
9697
),
97-
_ => (expr.span, format!("{{ {inner_expr}; {vec}[] as {return_type} }}")),
98+
// NOTE: don't use the stmt span to avoid touching the trailing semicolon
99+
Node::Stmt(_) => (expr.span, format!("{inner_expr};\n{indent}{vec}[] as {return_type}")),
100+
_ => (
101+
expr.span,
102+
format!(
103+
"\
104+
{{
105+
{indent} {inner_expr};
106+
{indent} {vec}[] as {return_type}
107+
{indent}}}"
108+
),
109+
),
98110
};
99111
let span = span.source_callsite();
100112
span_lint_and_then(

tests/ui/zero_repeat_side_effects.fixed

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![warn(clippy::zero_repeat_side_effects)]
22
#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)]
3+
#![allow(clippy::no_effect)] // only fires _after_ the fix
34

45
fn f() -> i32 {
56
println!("side effect");
@@ -13,36 +14,47 @@ fn main() {
1314
// should trigger
1415

1516
// on arrays
16-
f(); let a: [i32; 0] = [];
17+
f();
18+
let a: [i32; 0] = [];
1719
//~^ zero_repeat_side_effects
1820
let mut b;
19-
f(); b = [] as [i32; 0];
21+
f();
22+
b = [] as [i32; 0];
2023
//~^ zero_repeat_side_effects
2124

2225
// on vecs
2326
// vecs dont support inferring value of consts
24-
f(); let c: std::vec::Vec<i32> = vec![];
27+
f();
28+
let c: std::vec::Vec<i32> = vec![];
2529
//~^ zero_repeat_side_effects
2630
let d;
27-
f(); d = vec![] as std::vec::Vec<i32>;
31+
f();
32+
d = vec![] as std::vec::Vec<i32>;
2833
//~^ zero_repeat_side_effects
2934

3035
// for macros
31-
println!("side effect"); let e: [(); 0] = [];
36+
println!("side effect");
37+
let e: [(); 0] = [];
3238
//~^ zero_repeat_side_effects
3339

3440
// for nested calls
35-
{ f() }; let g: [i32; 0] = [];
41+
{ f() };
42+
let g: [i32; 0] = [];
3643
//~^ zero_repeat_side_effects
3744

3845
// as function param
39-
drop({ f(); vec![] as std::vec::Vec<i32> });
46+
drop({
47+
f();
48+
vec![] as std::vec::Vec<i32>
49+
});
4050
//~^ zero_repeat_side_effects
4151

4252
// when singled out/not part of assignment/local
43-
{ f(); vec![] as std::vec::Vec<i32> };
53+
f();
54+
vec![] as std::vec::Vec<i32>;
4455
//~^ zero_repeat_side_effects
45-
{ f(); [] as [i32; 0] };
56+
f();
57+
[] as [i32; 0];
4658
//~^ zero_repeat_side_effects
4759

4860
// should not trigger
@@ -96,8 +108,14 @@ fn issue_14681() {
96108

97109
foo(&[Some(0i64); 0]);
98110
foo(&[Some(Some(0i64)); 0]);
99-
foo(&{ Some(f()); [] as [std::option::Option<i32>; 0] });
111+
foo(&{
112+
Some(f());
113+
[] as [std::option::Option<i32>; 0]
114+
});
100115
//~^ zero_repeat_side_effects
101-
foo(&{ Some(Some(S::new())); [] as [std::option::Option<std::option::Option<S>>; 0] });
116+
foo(&{
117+
Some(Some(S::new()));
118+
[] as [std::option::Option<std::option::Option<S>>; 0]
119+
});
102120
//~^ zero_repeat_side_effects
103121
}

tests/ui/zero_repeat_side_effects.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![warn(clippy::zero_repeat_side_effects)]
22
#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)]
3+
#![allow(clippy::no_effect)] // only fires _after_ the fix
34

45
fn f() -> i32 {
56
println!("side effect");

tests/ui/zero_repeat_side_effects.stderr

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: expression with side effects as the initial value in a zero-sized array initializer
2-
--> tests/ui/zero_repeat_side_effects.rs:16:5
2+
--> tests/ui/zero_repeat_side_effects.rs:17:5
33
|
44
LL | let a = [f(); 0];
55
| ^^^^^^^^^^^^^^^^^
@@ -8,128 +8,134 @@ LL | let a = [f(); 0];
88
= help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`
99
help: consider performing the side effect separately
1010
|
11-
LL - let a = [f(); 0];
12-
LL + f(); let a: [i32; 0] = [];
11+
LL ~ f();
12+
LL + let a: [i32; 0] = [];
1313
|
1414

1515
error: expression with side effects as the initial value in a zero-sized array initializer
16-
--> tests/ui/zero_repeat_side_effects.rs:19:5
16+
--> tests/ui/zero_repeat_side_effects.rs:20:5
1717
|
1818
LL | b = [f(); 0];
1919
| ^^^^^^^^^^^^
2020
|
2121
help: consider performing the side effect separately
2222
|
23-
LL - b = [f(); 0];
24-
LL + f(); b = [] as [i32; 0];
23+
LL ~ f();
24+
LL ~ b = [] as [i32; 0];
2525
|
2626

2727
error: expression with side effects as the initial value in a zero-sized array initializer
28-
--> tests/ui/zero_repeat_side_effects.rs:24:5
28+
--> tests/ui/zero_repeat_side_effects.rs:25:5
2929
|
3030
LL | let c = vec![f(); 0];
3131
| ^^^^^^^^^^^^^^^^^^^^^
3232
|
3333
help: consider performing the side effect separately
3434
|
35-
LL - let c = vec![f(); 0];
36-
LL + f(); let c: std::vec::Vec<i32> = vec![];
35+
LL ~ f();
36+
LL + let c: std::vec::Vec<i32> = vec![];
3737
|
3838

3939
error: expression with side effects as the initial value in a zero-sized array initializer
40-
--> tests/ui/zero_repeat_side_effects.rs:27:5
40+
--> tests/ui/zero_repeat_side_effects.rs:28:5
4141
|
4242
LL | d = vec![f(); 0];
4343
| ^^^^^^^^^^^^^^^^
4444
|
4545
help: consider performing the side effect separately
4646
|
47-
LL - d = vec![f(); 0];
48-
LL + f(); d = vec![] as std::vec::Vec<i32>;
47+
LL ~ f();
48+
LL ~ d = vec![] as std::vec::Vec<i32>;
4949
|
5050

5151
error: expression with side effects as the initial value in a zero-sized array initializer
52-
--> tests/ui/zero_repeat_side_effects.rs:31:5
52+
--> tests/ui/zero_repeat_side_effects.rs:32:5
5353
|
5454
LL | let e = [println!("side effect"); 0];
5555
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5656
|
5757
help: consider performing the side effect separately
5858
|
59-
LL - let e = [println!("side effect"); 0];
60-
LL + println!("side effect"); let e: [(); 0] = [];
59+
LL ~ println!("side effect");
60+
LL + let e: [(); 0] = [];
6161
|
6262

6363
error: expression with side effects as the initial value in a zero-sized array initializer
64-
--> tests/ui/zero_repeat_side_effects.rs:35:5
64+
--> tests/ui/zero_repeat_side_effects.rs:36:5
6565
|
6666
LL | let g = [{ f() }; 0];
6767
| ^^^^^^^^^^^^^^^^^^^^^
6868
|
6969
help: consider performing the side effect separately
7070
|
71-
LL - let g = [{ f() }; 0];
72-
LL + { f() }; let g: [i32; 0] = [];
71+
LL ~ { f() };
72+
LL + let g: [i32; 0] = [];
7373
|
7474

7575
error: expression with side effects as the initial value in a zero-sized array initializer
76-
--> tests/ui/zero_repeat_side_effects.rs:39:10
76+
--> tests/ui/zero_repeat_side_effects.rs:40:10
7777
|
7878
LL | drop(vec![f(); 0]);
7979
| ^^^^^^^^^^^^
8080
|
8181
help: consider performing the side effect separately
8282
|
83-
LL - drop(vec![f(); 0]);
84-
LL + drop({ f(); vec![] as std::vec::Vec<i32> });
83+
LL ~ drop({
84+
LL + f();
85+
LL + vec![] as std::vec::Vec<i32>
86+
LL ~ });
8587
|
8688

8789
error: expression with side effects as the initial value in a zero-sized array initializer
88-
--> tests/ui/zero_repeat_side_effects.rs:43:5
90+
--> tests/ui/zero_repeat_side_effects.rs:44:5
8991
|
9092
LL | vec![f(); 0];
9193
| ^^^^^^^^^^^^
9294
|
9395
help: consider performing the side effect separately
9496
|
95-
LL - vec![f(); 0];
96-
LL + { f(); vec![] as std::vec::Vec<i32> };
97+
LL ~ f();
98+
LL ~ vec![] as std::vec::Vec<i32>;
9799
|
98100

99101
error: expression with side effects as the initial value in a zero-sized array initializer
100-
--> tests/ui/zero_repeat_side_effects.rs:45:5
102+
--> tests/ui/zero_repeat_side_effects.rs:46:5
101103
|
102104
LL | [f(); 0];
103105
| ^^^^^^^^
104106
|
105107
help: consider performing the side effect separately
106108
|
107-
LL - [f(); 0];
108-
LL + { f(); [] as [i32; 0] };
109+
LL ~ f();
110+
LL ~ [] as [i32; 0];
109111
|
110112

111113
error: expression with side effects as the initial value in a zero-sized array initializer
112-
--> tests/ui/zero_repeat_side_effects.rs:99:10
114+
--> tests/ui/zero_repeat_side_effects.rs:100:10
113115
|
114116
LL | foo(&[Some(f()); 0]);
115117
| ^^^^^^^^^^^^^^
116118
|
117119
help: consider performing the side effect separately
118120
|
119-
LL - foo(&[Some(f()); 0]);
120-
LL + foo(&{ Some(f()); [] as [std::option::Option<i32>; 0] });
121+
LL ~ foo(&{
122+
LL + Some(f());
123+
LL + [] as [std::option::Option<i32>; 0]
124+
LL ~ });
121125
|
122126

123127
error: expression with side effects as the initial value in a zero-sized array initializer
124-
--> tests/ui/zero_repeat_side_effects.rs:101:10
128+
--> tests/ui/zero_repeat_side_effects.rs:102:10
125129
|
126130
LL | foo(&[Some(Some(S::new())); 0]);
127131
| ^^^^^^^^^^^^^^^^^^^^^^^^^
128132
|
129133
help: consider performing the side effect separately
130134
|
131-
LL - foo(&[Some(Some(S::new())); 0]);
132-
LL + foo(&{ Some(Some(S::new())); [] as [std::option::Option<std::option::Option<S>>; 0] });
135+
LL ~ foo(&{
136+
LL + Some(Some(S::new()));
137+
LL + [] as [std::option::Option<std::option::Option<S>>; 0]
138+
LL ~ });
133139
|
134140

135141
error: aborting due to 11 previous errors

tests/ui/zero_repeat_side_effects_never_pattern.fixed

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
fn issue_14998() {
66
// nameable type thanks to `never_type` being enabled, suggest
7-
panic!(); let _data: [!; 0] = [];
7+
panic!();
8+
let _data: [!; 0] = [];
89
//~^ zero_repeat_side_effects
910
}

tests/ui/zero_repeat_side_effects_never_pattern.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ LL | let _data = [panic!(); 0];
88
= help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`
99
help: consider performing the side effect separately
1010
|
11-
LL - let _data = [panic!(); 0];
12-
LL + panic!(); let _data: [!; 0] = [];
11+
LL ~ panic!();
12+
LL + let _data: [!; 0] = [];
1313
|
1414

1515
error: aborting due to 1 previous error

0 commit comments

Comments
 (0)