skip todo / unimplemented in never_loop

This commit is contained in:
Mario Carneiro 2023-09-02 23:34:03 -04:00
parent b9906aca5a
commit 61a2f972b3
7 changed files with 47 additions and 45 deletions

View file

@ -2,6 +2,7 @@ use super::utils::make_iterator_snippet;
use super::NEVER_LOOP; use super::NEVER_LOOP;
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::ForLoop; use clippy_utils::higher::ForLoop;
use clippy_utils::macros::root_macro_call_first_node;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind}; use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
@ -263,13 +264,25 @@ fn never_loop_expr<'tcx>(
| ExprKind::Lit(_) | ExprKind::Lit(_)
| ExprKind::Err(_) => NeverLoopResult::Normal, | ExprKind::Err(_) => NeverLoopResult::Normal,
}; };
combine_seq(result, || { let result = combine_seq(result, || {
if cx.typeck_results().expr_ty(expr).is_never() { if cx.typeck_results().expr_ty(expr).is_never() {
NeverLoopResult::Diverging NeverLoopResult::Diverging
} else { } else {
NeverLoopResult::Normal NeverLoopResult::Normal
} }
}) });
if let NeverLoopResult::Diverging = result &&
let Some(macro_call) = root_macro_call_first_node(cx, expr) &&
let "todo" | "unimplemented" = cx.tcx.item_name(macro_call.def_id).as_str()
{
// We return MayContinueMainLoop here because we treat `todo!()` and
// `unimplemented!()` macros as potentially containing any code,
// including a continue of the main loop. This effectively silences the lint
// whenever a loop contains one of these macros anywhere.
NeverLoopResult::MayContinueMainLoop
} else {
result
}
} }
fn never_loop_expr_all<'tcx, T: Iterator<Item = &'tcx Expr<'tcx>>>( fn never_loop_expr_all<'tcx, T: Iterator<Item = &'tcx Expr<'tcx>>>(

View file

@ -260,7 +260,6 @@ mod issue_8553 {
let w = v.iter().collect::<Vec<_>>(); let w = v.iter().collect::<Vec<_>>();
//~^ ERROR: avoid using `collect()` when not needed //~^ ERROR: avoid using `collect()` when not needed
// Do lint // Do lint
#[allow(clippy::never_loop)]
for _ in 0..w.len() { for _ in 0..w.len() {
todo!(); todo!();
} }
@ -271,7 +270,6 @@ mod issue_8553 {
let v: Vec<usize> = vec.iter().map(|i| i * i).collect(); let v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let w = v.iter().collect::<Vec<_>>(); let w = v.iter().collect::<Vec<_>>();
// Do not lint, because w is used. // Do not lint, because w is used.
#[allow(clippy::never_loop)]
for _ in 0..w.len() { for _ in 0..w.len() {
todo!(); todo!();
} }
@ -285,7 +283,6 @@ mod issue_8553 {
let mut w = v.iter().collect::<Vec<_>>(); let mut w = v.iter().collect::<Vec<_>>();
//~^ ERROR: avoid using `collect()` when not needed //~^ ERROR: avoid using `collect()` when not needed
// Do lint // Do lint
#[allow(clippy::never_loop)]
while 1 == w.len() { while 1 == w.len() {
todo!(); todo!();
} }
@ -296,7 +293,6 @@ mod issue_8553 {
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect(); let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut w = v.iter().collect::<Vec<_>>(); let mut w = v.iter().collect::<Vec<_>>();
// Do not lint, because w is used. // Do not lint, because w is used.
#[allow(clippy::never_loop)]
while 1 == w.len() { while 1 == w.len() {
todo!(); todo!();
} }
@ -310,7 +306,6 @@ mod issue_8553 {
let mut w = v.iter().collect::<Vec<_>>(); let mut w = v.iter().collect::<Vec<_>>();
//~^ ERROR: avoid using `collect()` when not needed //~^ ERROR: avoid using `collect()` when not needed
// Do lint // Do lint
#[allow(clippy::never_loop)]
while let Some(i) = Some(w.len()) { while let Some(i) = Some(w.len()) {
todo!(); todo!();
} }
@ -321,7 +316,6 @@ mod issue_8553 {
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect(); let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut w = v.iter().collect::<Vec<_>>(); let mut w = v.iter().collect::<Vec<_>>();
// Do not lint, because w is used. // Do not lint, because w is used.
#[allow(clippy::never_loop)]
while let Some(i) = Some(w.len()) { while let Some(i) = Some(w.len()) {
todo!(); todo!();
} }

View file

@ -230,12 +230,11 @@ help: take the original Iterator's count instead of collecting it and finding th
LL ~ LL ~
LL | LL |
LL | // Do lint LL | // Do lint
LL | #[allow(clippy::never_loop)]
LL ~ for _ in 0..v.iter().count() { LL ~ for _ in 0..v.iter().count() {
| |
error: avoid using `collect()` when not needed error: avoid using `collect()` when not needed
--> $DIR/needless_collect_indirect.rs:285:30 --> $DIR/needless_collect_indirect.rs:283:30
| |
LL | let mut w = v.iter().collect::<Vec<_>>(); LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^ | ^^^^^^^
@ -248,12 +247,11 @@ help: take the original Iterator's count instead of collecting it and finding th
LL ~ LL ~
LL | LL |
LL | // Do lint LL | // Do lint
LL | #[allow(clippy::never_loop)]
LL ~ while 1 == v.iter().count() { LL ~ while 1 == v.iter().count() {
| |
error: avoid using `collect()` when not needed error: avoid using `collect()` when not needed
--> $DIR/needless_collect_indirect.rs:310:30 --> $DIR/needless_collect_indirect.rs:306:30
| |
LL | let mut w = v.iter().collect::<Vec<_>>(); LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^ | ^^^^^^^
@ -266,7 +264,6 @@ help: take the original Iterator's count instead of collecting it and finding th
LL ~ LL ~
LL | LL |
LL | // Do lint LL | // Do lint
LL | #[allow(clippy::never_loop)]
LL ~ while let Some(i) = Some(v.iter().count()) { LL ~ while let Some(i) = Some(v.iter().count()) {
| |

View file

@ -385,11 +385,19 @@ pub fn test31(b: bool) {
} }
} }
pub fn test32(b: bool) { pub fn test32() {
loop { loop {
//~^ ERROR: this loop never actually loops //~^ ERROR: this loop never actually loops
panic!("oh no"); panic!("oh no");
} }
loop {
// no error
unimplemented!("not yet");
}
loop {
// no error
todo!("maybe later");
}
} }
fn main() { fn main() {

View file

@ -1,10 +1,5 @@
#![warn(clippy::useless_vec)] #![warn(clippy::useless_vec)]
#![allow( #![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
clippy::nonstandard_macro_braces,
clippy::never_loop,
clippy::uninlined_format_args,
unused
)]
use std::rc::Rc; use std::rc::Rc;

View file

@ -1,10 +1,5 @@
#![warn(clippy::useless_vec)] #![warn(clippy::useless_vec)]
#![allow( #![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
clippy::nonstandard_macro_braces,
clippy::never_loop,
clippy::uninlined_format_args,
unused
)]
use std::rc::Rc; use std::rc::Rc;

View file

@ -1,5 +1,5 @@
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:35:14 --> $DIR/vec.rs:30:14
| |
LL | on_slice(&vec![]); LL | on_slice(&vec![]);
| ^^^^^^^ help: you can use a slice directly: `&[]` | ^^^^^^^ help: you can use a slice directly: `&[]`
@ -7,109 +7,109 @@ LL | on_slice(&vec![]);
= note: `-D clippy::useless-vec` implied by `-D warnings` = note: `-D clippy::useless-vec` implied by `-D warnings`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:37:18 --> $DIR/vec.rs:32:18
| |
LL | on_mut_slice(&mut vec![]); LL | on_mut_slice(&mut vec![]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&mut []` | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:39:14 --> $DIR/vec.rs:34:14
| |
LL | on_slice(&vec![1, 2]); LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:41:18 --> $DIR/vec.rs:36:18
| |
LL | on_mut_slice(&mut vec![1, 2]); LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:43:14 --> $DIR/vec.rs:38:14
| |
LL | on_slice(&vec![1, 2]); LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:45:18 --> $DIR/vec.rs:40:18
| |
LL | on_mut_slice(&mut vec![1, 2]); LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:47:14 --> $DIR/vec.rs:42:14
| |
LL | on_slice(&vec!(1, 2)); LL | on_slice(&vec!(1, 2));
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:49:18 --> $DIR/vec.rs:44:18
| |
LL | on_mut_slice(&mut vec![1, 2]); LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:51:14 --> $DIR/vec.rs:46:14
| |
LL | on_slice(&vec![1; 2]); LL | on_slice(&vec![1; 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:53:18 --> $DIR/vec.rs:48:18
| |
LL | on_mut_slice(&mut vec![1; 2]); LL | on_mut_slice(&mut vec![1; 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]` | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:79:19 --> $DIR/vec.rs:74:19
| |
LL | let _x: i32 = vec![1, 2, 3].iter().sum(); LL | let _x: i32 = vec![1, 2, 3].iter().sum();
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:82:17 --> $DIR/vec.rs:77:17
| |
LL | let mut x = vec![1, 2, 3]; LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:88:22 --> $DIR/vec.rs:83:22
| |
LL | let _x: &[i32] = &vec![1, 2, 3]; LL | let _x: &[i32] = &vec![1, 2, 3];
| ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:90:14 --> $DIR/vec.rs:85:14
| |
LL | for _ in vec![1, 2, 3] {} LL | for _ in vec![1, 2, 3] {}
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:128:20 --> $DIR/vec.rs:123:20
| |
LL | for _string in vec![repro!(true), repro!(null)] { LL | for _string in vec![repro!(true), repro!(null)] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:145:18 --> $DIR/vec.rs:140:18
| |
LL | in_macro!(1, vec![1, 2], vec![1; 2]); LL | in_macro!(1, vec![1, 2], vec![1; 2]);
| ^^^^^^^^^^ help: you can use an array directly: `[1, 2]` | ^^^^^^^^^^ help: you can use an array directly: `[1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:145:30 --> $DIR/vec.rs:140:30
| |
LL | in_macro!(1, vec![1, 2], vec![1; 2]); LL | in_macro!(1, vec![1, 2], vec![1; 2]);
| ^^^^^^^^^^ help: you can use an array directly: `[1; 2]` | ^^^^^^^^^^ help: you can use an array directly: `[1; 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:164:14 --> $DIR/vec.rs:159:14
| |
LL | for a in vec![1, 2, 3] { LL | for a in vec![1, 2, 3] {
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:168:14 --> $DIR/vec.rs:163:14
| |
LL | for a in vec![String::new(), String::new()] { LL | for a in vec![String::new(), String::new()] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]`