Skip to content

Commit da882f0

Browse files
committed
Auto merge of rust-lang#11455 - digama0:never_loop3, r=Centri3,dswij
skip `todo!()` in `never_loop` As promised in rust-lang#11450, here is an implementation which skips occurrences of the `todo!()` macro. changelog: [`never_loop`]: skip loops containing `todo!()`
2 parents f13e1f4 + 4e0a346 commit da882f0

File tree

8 files changed

+59
-47
lines changed

8 files changed

+59
-47
lines changed

Diff for: clippy_lints/src/loops/never_loop.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ use super::utils::make_iterator_snippet;
22
use super::NEVER_LOOP;
33
use clippy_utils::diagnostics::span_lint_and_then;
44
use clippy_utils::higher::ForLoop;
5+
use clippy_utils::macros::root_macro_call_first_node;
56
use clippy_utils::source::snippet;
67
use rustc_errors::Applicability;
78
use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
89
use rustc_lint::LateContext;
9-
use rustc_span::Span;
10+
use rustc_span::{sym, Span};
1011
use std::iter::{once, Iterator};
1112

1213
pub(super) fn check<'tcx>(
@@ -263,13 +264,24 @@ fn never_loop_expr<'tcx>(
263264
| ExprKind::Lit(_)
264265
| ExprKind::Err(_) => NeverLoopResult::Normal,
265266
};
266-
combine_seq(result, || {
267+
let result = combine_seq(result, || {
267268
if cx.typeck_results().expr_ty(expr).is_never() {
268269
NeverLoopResult::Diverging
269270
} else {
270271
NeverLoopResult::Normal
271272
}
272-
})
273+
});
274+
if let NeverLoopResult::Diverging = result &&
275+
let Some(macro_call) = root_macro_call_first_node(cx, expr) &&
276+
let Some(sym::todo_macro) = cx.tcx.get_diagnostic_name(macro_call.def_id)
277+
{
278+
// We return MayContinueMainLoop here because we treat `todo!()`
279+
// as potentially containing any code, including a continue of the main loop.
280+
// This effectively silences the lint whenever a loop contains this macro anywhere.
281+
NeverLoopResult::MayContinueMainLoop
282+
} else {
283+
result
284+
}
273285
}
274286

275287
fn never_loop_expr_all<'tcx, T: Iterator<Item = &'tcx Expr<'tcx>>>(

Diff for: tests/ui/needless_collect_indirect.rs

-6
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ mod issue_8553 {
260260
let w = v.iter().collect::<Vec<_>>();
261261
//~^ ERROR: avoid using `collect()` when not needed
262262
// Do lint
263-
#[allow(clippy::never_loop)]
264263
for _ in 0..w.len() {
265264
todo!();
266265
}
@@ -271,7 +270,6 @@ mod issue_8553 {
271270
let v: Vec<usize> = vec.iter().map(|i| i * i).collect();
272271
let w = v.iter().collect::<Vec<_>>();
273272
// Do not lint, because w is used.
274-
#[allow(clippy::never_loop)]
275273
for _ in 0..w.len() {
276274
todo!();
277275
}
@@ -285,7 +283,6 @@ mod issue_8553 {
285283
let mut w = v.iter().collect::<Vec<_>>();
286284
//~^ ERROR: avoid using `collect()` when not needed
287285
// Do lint
288-
#[allow(clippy::never_loop)]
289286
while 1 == w.len() {
290287
todo!();
291288
}
@@ -296,7 +293,6 @@ mod issue_8553 {
296293
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
297294
let mut w = v.iter().collect::<Vec<_>>();
298295
// Do not lint, because w is used.
299-
#[allow(clippy::never_loop)]
300296
while 1 == w.len() {
301297
todo!();
302298
}
@@ -310,7 +306,6 @@ mod issue_8553 {
310306
let mut w = v.iter().collect::<Vec<_>>();
311307
//~^ ERROR: avoid using `collect()` when not needed
312308
// Do lint
313-
#[allow(clippy::never_loop)]
314309
while let Some(i) = Some(w.len()) {
315310
todo!();
316311
}
@@ -321,7 +316,6 @@ mod issue_8553 {
321316
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
322317
let mut w = v.iter().collect::<Vec<_>>();
323318
// Do not lint, because w is used.
324-
#[allow(clippy::never_loop)]
325319
while let Some(i) = Some(w.len()) {
326320
todo!();
327321
}

Diff for: tests/ui/needless_collect_indirect.stderr

+2-5
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,11 @@ help: take the original Iterator's count instead of collecting it and finding th
230230
LL ~
231231
LL |
232232
LL | // Do lint
233-
LL | #[allow(clippy::never_loop)]
234233
LL ~ for _ in 0..v.iter().count() {
235234
|
236235

237236
error: avoid using `collect()` when not needed
238-
--> $DIR/needless_collect_indirect.rs:285:30
237+
--> $DIR/needless_collect_indirect.rs:283:30
239238
|
240239
LL | let mut w = v.iter().collect::<Vec<_>>();
241240
| ^^^^^^^
@@ -248,12 +247,11 @@ help: take the original Iterator's count instead of collecting it and finding th
248247
LL ~
249248
LL |
250249
LL | // Do lint
251-
LL | #[allow(clippy::never_loop)]
252250
LL ~ while 1 == v.iter().count() {
253251
|
254252

255253
error: avoid using `collect()` when not needed
256-
--> $DIR/needless_collect_indirect.rs:310:30
254+
--> $DIR/needless_collect_indirect.rs:306:30
257255
|
258256
LL | let mut w = v.iter().collect::<Vec<_>>();
259257
| ^^^^^^^
@@ -266,7 +264,6 @@ help: take the original Iterator's count instead of collecting it and finding th
266264
LL ~
267265
LL |
268266
LL | // Do lint
269-
LL | #[allow(clippy::never_loop)]
270267
LL ~ while let Some(i) = Some(v.iter().count()) {
271268
|
272269

Diff for: tests/ui/never_loop.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,19 @@ pub fn test31(b: bool) {
385385
}
386386
}
387387

388-
pub fn test32(b: bool) {
388+
pub fn test32() {
389389
loop {
390390
//~^ ERROR: this loop never actually loops
391391
panic!("oh no");
392392
}
393+
loop {
394+
//~^ ERROR: this loop never actually loops
395+
unimplemented!("not yet");
396+
}
397+
loop {
398+
// no error
399+
todo!("maybe later");
400+
}
393401
}
394402

395403
fn main() {

Diff for: tests/ui/never_loop.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,14 @@ LL | | panic!("oh no");
170170
LL | | }
171171
| |_____^
172172

173-
error: aborting due to 15 previous errors
173+
error: this loop never actually loops
174+
--> $DIR/never_loop.rs:393:5
175+
|
176+
LL | / loop {
177+
LL | |
178+
LL | | unimplemented!("not yet");
179+
LL | | }
180+
| |_____^
181+
182+
error: aborting due to 16 previous errors
174183

Diff for: tests/ui/vec.fixed

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
#![warn(clippy::useless_vec)]
2-
#![allow(
3-
clippy::nonstandard_macro_braces,
4-
clippy::never_loop,
5-
clippy::uninlined_format_args,
6-
unused
7-
)]
2+
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
83

94
use std::rc::Rc;
105

@@ -125,6 +120,7 @@ fn issue11075() {
125120
stringify!($e)
126121
};
127122
}
123+
#[allow(clippy::never_loop)]
128124
for _string in [repro!(true), repro!(null)] {
129125
unimplemented!();
130126
}

Diff for: tests/ui/vec.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
#![warn(clippy::useless_vec)]
2-
#![allow(
3-
clippy::nonstandard_macro_braces,
4-
clippy::never_loop,
5-
clippy::uninlined_format_args,
6-
unused
7-
)]
2+
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
83

94
use std::rc::Rc;
105

@@ -125,6 +120,7 @@ fn issue11075() {
125120
stringify!($e)
126121
};
127122
}
123+
#[allow(clippy::never_loop)]
128124
for _string in vec![repro!(true), repro!(null)] {
129125
unimplemented!();
130126
}

Diff for: tests/ui/vec.stderr

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,115 @@
11
error: useless use of `vec!`
2-
--> $DIR/vec.rs:35:14
2+
--> $DIR/vec.rs:30:14
33
|
44
LL | on_slice(&vec![]);
55
| ^^^^^^^ help: you can use a slice directly: `&[]`
66
|
77
= note: `-D clippy::useless-vec` implied by `-D warnings`
88

99
error: useless use of `vec!`
10-
--> $DIR/vec.rs:37:18
10+
--> $DIR/vec.rs:32:18
1111
|
1212
LL | on_mut_slice(&mut vec![]);
1313
| ^^^^^^^^^^^ help: you can use a slice directly: `&mut []`
1414

1515
error: useless use of `vec!`
16-
--> $DIR/vec.rs:39:14
16+
--> $DIR/vec.rs:34:14
1717
|
1818
LL | on_slice(&vec![1, 2]);
1919
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
2020

2121
error: useless use of `vec!`
22-
--> $DIR/vec.rs:41:18
22+
--> $DIR/vec.rs:36:18
2323
|
2424
LL | on_mut_slice(&mut vec![1, 2]);
2525
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
2626

2727
error: useless use of `vec!`
28-
--> $DIR/vec.rs:43:14
28+
--> $DIR/vec.rs:38:14
2929
|
3030
LL | on_slice(&vec![1, 2]);
3131
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
3232

3333
error: useless use of `vec!`
34-
--> $DIR/vec.rs:45:18
34+
--> $DIR/vec.rs:40:18
3535
|
3636
LL | on_mut_slice(&mut vec![1, 2]);
3737
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
3838

3939
error: useless use of `vec!`
40-
--> $DIR/vec.rs:47:14
40+
--> $DIR/vec.rs:42:14
4141
|
4242
LL | on_slice(&vec!(1, 2));
4343
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
4444

4545
error: useless use of `vec!`
46-
--> $DIR/vec.rs:49:18
46+
--> $DIR/vec.rs:44:18
4747
|
4848
LL | on_mut_slice(&mut vec![1, 2]);
4949
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
5050

5151
error: useless use of `vec!`
52-
--> $DIR/vec.rs:51:14
52+
--> $DIR/vec.rs:46:14
5353
|
5454
LL | on_slice(&vec![1; 2]);
5555
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]`
5656

5757
error: useless use of `vec!`
58-
--> $DIR/vec.rs:53:18
58+
--> $DIR/vec.rs:48:18
5959
|
6060
LL | on_mut_slice(&mut vec![1; 2]);
6161
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]`
6262

6363
error: useless use of `vec!`
64-
--> $DIR/vec.rs:79:19
64+
--> $DIR/vec.rs:74:19
6565
|
6666
LL | let _x: i32 = vec![1, 2, 3].iter().sum();
6767
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
6868

6969
error: useless use of `vec!`
70-
--> $DIR/vec.rs:82:17
70+
--> $DIR/vec.rs:77:17
7171
|
7272
LL | let mut x = vec![1, 2, 3];
7373
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
7474

7575
error: useless use of `vec!`
76-
--> $DIR/vec.rs:88:22
76+
--> $DIR/vec.rs:83:22
7777
|
7878
LL | let _x: &[i32] = &vec![1, 2, 3];
7979
| ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
8080

8181
error: useless use of `vec!`
82-
--> $DIR/vec.rs:90:14
82+
--> $DIR/vec.rs:85:14
8383
|
8484
LL | for _ in vec![1, 2, 3] {}
8585
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
8686

8787
error: useless use of `vec!`
88-
--> $DIR/vec.rs:128:20
88+
--> $DIR/vec.rs:124:20
8989
|
9090
LL | for _string in vec![repro!(true), repro!(null)] {
9191
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]`
9292

9393
error: useless use of `vec!`
94-
--> $DIR/vec.rs:145:18
94+
--> $DIR/vec.rs:141:18
9595
|
9696
LL | in_macro!(1, vec![1, 2], vec![1; 2]);
9797
| ^^^^^^^^^^ help: you can use an array directly: `[1, 2]`
9898

9999
error: useless use of `vec!`
100-
--> $DIR/vec.rs:145:30
100+
--> $DIR/vec.rs:141:30
101101
|
102102
LL | in_macro!(1, vec![1, 2], vec![1; 2]);
103103
| ^^^^^^^^^^ help: you can use an array directly: `[1; 2]`
104104

105105
error: useless use of `vec!`
106-
--> $DIR/vec.rs:164:14
106+
--> $DIR/vec.rs:160:14
107107
|
108108
LL | for a in vec![1, 2, 3] {
109109
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
110110

111111
error: useless use of `vec!`
112-
--> $DIR/vec.rs:168:14
112+
--> $DIR/vec.rs:164:14
113113
|
114114
LL | for a in vec![String::new(), String::new()] {
115115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]`

0 commit comments

Comments
 (0)