Skip to content

feat(fix): ignore todo! and unimplemented! in if_same_then_else #9006

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::consts::constant_simple;
use crate::macros::macro_backtrace;
use crate::source::snippet_opt;
use rustc_ast::ast::InlineAsmTemplatePiece;
use rustc_data_structures::fx::FxHasher;
Expand All @@ -12,7 +13,7 @@ use rustc_hir::{
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::LateContext;
use rustc_middle::ty::TypeckResults;
use rustc_span::Symbol;
use rustc_span::{sym, Symbol};
use std::hash::{Hash, Hasher};

/// Type used to check whether two ast are the same. This is different from the
Expand Down Expand Up @@ -121,6 +122,9 @@ impl HirEqInterExpr<'_, '_, '_> {

/// Checks whether two blocks are the same.
fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool {
if self.cannot_be_compared_block(left) || self.cannot_be_compared_block(right) {
return false;
}
match (left.stmts, left.expr, right.stmts, right.expr) {
([], None, [], None) => {
// For empty blocks, check to see if the tokens are equal. This will catch the case where a macro
Expand Down Expand Up @@ -171,6 +175,38 @@ impl HirEqInterExpr<'_, '_, '_> {
}
}

fn cannot_be_compared_block(&mut self, block: &Block<'_>) -> bool {
if block.stmts.last().map_or(false, |stmt| {
matches!(
stmt.kind,
StmtKind::Semi(semi_expr) if self.should_ignore(semi_expr)
)
}) {
return true;
}

if let Some(block_expr) = block.expr
&& self.should_ignore(block_expr)
{
return true
}

false
}

fn should_ignore(&mut self, expr: &Expr<'_>) -> bool {
if macro_backtrace(expr.span).last().map_or(false, |macro_call| {
matches!(
&self.inner.cx.tcx.get_diagnostic_name(macro_call.def_id),
Some(sym::todo_macro | sym::unimplemented_macro)
)
}) {
return true;
}

false
}

pub fn eq_array_length(&mut self, left: ArrayLen, right: ArrayLen) -> bool {
match (left, right) {
(ArrayLen::Infer(..), ArrayLen::Infer(..)) => true,
Expand Down
61 changes: 60 additions & 1 deletion tests/ui/if_same_then_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
clippy::no_effect,
clippy::unused_unit,
clippy::zero_divided_by_zero,
clippy::branches_sharing_code
clippy::branches_sharing_code,
dead_code,
unreachable_code
)]

struct Foo {
Expand Down Expand Up @@ -155,4 +157,61 @@ mod issue_5698 {
}
}

mod issue_8836 {
fn do_not_lint() {
if true {
todo!()
} else {
todo!()
}
if true {
todo!();
} else {
todo!();
}
if true {
unimplemented!()
} else {
unimplemented!()
}
if true {
unimplemented!();
} else {
unimplemented!();
}

if true {
println!("FOO");
todo!();
} else {
println!("FOO");
todo!();
}

if true {
println!("FOO");
unimplemented!();
} else {
println!("FOO");
unimplemented!();
}

if true {
println!("FOO");
todo!()
} else {
println!("FOO");
todo!()
}

if true {
println!("FOO");
unimplemented!()
} else {
println!("FOO");
unimplemented!()
}
}
}

fn main() {}
20 changes: 10 additions & 10 deletions tests/ui/if_same_then_else.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: this `if` has identical blocks
--> $DIR/if_same_then_else.rs:21:13
--> $DIR/if_same_then_else.rs:23:13
|
LL | if true {
| _____________^
Expand All @@ -13,7 +13,7 @@ LL | | } else {
|
= note: `-D clippy::if-same-then-else` implied by `-D warnings`
note: same as this
--> $DIR/if_same_then_else.rs:29:12
--> $DIR/if_same_then_else.rs:31:12
|
LL | } else {
| ____________^
Expand All @@ -26,7 +26,7 @@ LL | | }
| |_____^

error: this `if` has identical blocks
--> $DIR/if_same_then_else.rs:65:21
--> $DIR/if_same_then_else.rs:67:21
|
LL | let _ = if true {
| _____________________^
Expand All @@ -35,7 +35,7 @@ LL | | } else {
| |_____^
|
note: same as this
--> $DIR/if_same_then_else.rs:67:12
--> $DIR/if_same_then_else.rs:69:12
|
LL | } else {
| ____________^
Expand All @@ -45,7 +45,7 @@ LL | | };
| |_____^

error: this `if` has identical blocks
--> $DIR/if_same_then_else.rs:72:21
--> $DIR/if_same_then_else.rs:74:21
|
LL | let _ = if true {
| _____________________^
Expand All @@ -54,7 +54,7 @@ LL | | } else {
| |_____^
|
note: same as this
--> $DIR/if_same_then_else.rs:74:12
--> $DIR/if_same_then_else.rs:76:12
|
LL | } else {
| ____________^
Expand All @@ -64,7 +64,7 @@ LL | | };
| |_____^

error: this `if` has identical blocks
--> $DIR/if_same_then_else.rs:88:21
--> $DIR/if_same_then_else.rs:90:21
|
LL | let _ = if true {
| _____________________^
Expand All @@ -73,7 +73,7 @@ LL | | } else {
| |_____^
|
note: same as this
--> $DIR/if_same_then_else.rs:90:12
--> $DIR/if_same_then_else.rs:92:12
|
LL | } else {
| ____________^
Expand All @@ -83,7 +83,7 @@ LL | | };
| |_____^

error: this `if` has identical blocks
--> $DIR/if_same_then_else.rs:95:13
--> $DIR/if_same_then_else.rs:97:13
|
LL | if true {
| _____________^
Expand All @@ -96,7 +96,7 @@ LL | | } else {
| |_____^
|
note: same as this
--> $DIR/if_same_then_else.rs:102:12
--> $DIR/if_same_then_else.rs:104:12
|
LL | } else {
| ____________^
Expand Down