Skip to content

Commit 54bf4ff

Browse files
committed
Auto merge of #4613 - Lythenas:lint-assert_eq-unit_exprs, r=flip1995
Add check for assert_eq macros to unit_cmp lint changelog: Add check for unit comparisons through `assert_eq!`, `debug_assert_eq!`, `assert_ne!` and `debug_assert_ne!` macros to unit_cmp lint. fixes #4481
2 parents 933df2a + 5a0a2b3 commit 54bf4ff

File tree

6 files changed

+131
-4
lines changed

6 files changed

+131
-4
lines changed

clippy_lints/src/types.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use rustc_target::spec::abi::Abi;
1717
use rustc_typeck::hir_ty_to_ty;
1818
use syntax::ast::{FloatTy, IntTy, LitIntType, LitKind, UintTy};
1919
use syntax::errors::DiagnosticBuilder;
20+
use syntax::ext::base::MacroKind;
21+
use syntax::ext::hygiene::ExpnKind;
2022
use syntax::source_map::Span;
2123
use syntax::symbol::{sym, Symbol};
2224

@@ -485,7 +487,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnitValue {
485487
}
486488

487489
declare_clippy_lint! {
488-
/// **What it does:** Checks for comparisons to unit.
490+
/// **What it does:** Checks for comparisons to unit. This includes all binary
491+
/// comparisons (like `==` and `<`) and asserts.
489492
///
490493
/// **Why is this bad?** Unit is always equal to itself, and thus is just a
491494
/// clumsily written constant. Mostly this happens when someone accidentally
@@ -517,6 +520,14 @@ declare_clippy_lint! {
517520
/// baz();
518521
/// }
519522
/// ```
523+
///
524+
/// For asserts:
525+
/// ```rust
526+
/// # fn foo() {};
527+
/// # fn bar() {};
528+
/// assert_eq!({ foo(); }, { bar(); });
529+
/// ```
530+
/// will always succeed
520531
pub UNIT_CMP,
521532
correctness,
522533
"comparing unit values"
@@ -527,6 +538,30 @@ declare_lint_pass!(UnitCmp => [UNIT_CMP]);
527538
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
528539
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
529540
if expr.span.from_expansion() {
541+
if let Some(callee) = expr.span.source_callee() {
542+
if let ExpnKind::Macro(MacroKind::Bang, symbol) = callee.kind {
543+
if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind {
544+
let op = cmp.node;
545+
if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) {
546+
let result = match &*symbol.as_str() {
547+
"assert_eq" | "debug_assert_eq" => "succeed",
548+
"assert_ne" | "debug_assert_ne" => "fail",
549+
_ => return,
550+
};
551+
span_lint(
552+
cx,
553+
UNIT_CMP,
554+
expr.span,
555+
&format!(
556+
"`{}` of unit values detected. This will always {}",
557+
symbol.as_str(),
558+
result
559+
),
560+
);
561+
}
562+
}
563+
}
564+
}
530565
return;
531566
}
532567
if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind {

tests/ui/unit_cmp.rs

+34
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,38 @@ fn main() {
2020
} > {
2121
false;
2222
} {}
23+
24+
assert_eq!(
25+
{
26+
true;
27+
},
28+
{
29+
false;
30+
}
31+
);
32+
debug_assert_eq!(
33+
{
34+
true;
35+
},
36+
{
37+
false;
38+
}
39+
);
40+
41+
assert_ne!(
42+
{
43+
true;
44+
},
45+
{
46+
false;
47+
}
48+
);
49+
debug_assert_ne!(
50+
{
51+
true;
52+
},
53+
{
54+
false;
55+
}
56+
);
2357
}

tests/ui/unit_cmp.stderr

+57-1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,61 @@ LL | | false;
2222
LL | | } {}
2323
| |_____^
2424

25-
error: aborting due to 2 previous errors
25+
error: `assert_eq` of unit values detected. This will always succeed
26+
--> $DIR/unit_cmp.rs:24:5
27+
|
28+
LL | / assert_eq!(
29+
LL | | {
30+
LL | | true;
31+
LL | | },
32+
... |
33+
LL | | }
34+
LL | | );
35+
| |______^
36+
|
37+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
38+
39+
error: `debug_assert_eq` of unit values detected. This will always succeed
40+
--> $DIR/unit_cmp.rs:32:5
41+
|
42+
LL | / debug_assert_eq!(
43+
LL | | {
44+
LL | | true;
45+
LL | | },
46+
... |
47+
LL | | }
48+
LL | | );
49+
| |______^
50+
|
51+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
52+
53+
error: `assert_ne` of unit values detected. This will always fail
54+
--> $DIR/unit_cmp.rs:41:5
55+
|
56+
LL | / assert_ne!(
57+
LL | | {
58+
LL | | true;
59+
LL | | },
60+
... |
61+
LL | | }
62+
LL | | );
63+
| |______^
64+
|
65+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
66+
67+
error: `debug_assert_ne` of unit values detected. This will always fail
68+
--> $DIR/unit_cmp.rs:49:5
69+
|
70+
LL | / debug_assert_ne!(
71+
LL | | {
72+
LL | | true;
73+
LL | | },
74+
... |
75+
LL | | }
76+
LL | | );
77+
| |______^
78+
|
79+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
80+
81+
error: aborting due to 6 previous errors
2682

tests/ui/unused_unit.fixed

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fn return_unit() { }
3434

3535
#[allow(clippy::needless_return)]
3636
#[allow(clippy::never_loop)]
37+
#[allow(clippy::unit_cmp)]
3738
fn main() {
3839
let u = Unitter;
3940
assert_eq!(u.get_unit(|| {}, return_unit), u.into());

tests/ui/unused_unit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ fn return_unit() -> () { () }
3535

3636
#[allow(clippy::needless_return)]
3737
#[allow(clippy::never_loop)]
38+
#[allow(clippy::unit_cmp)]
3839
fn main() {
3940
let u = Unitter;
4041
assert_eq!(u.get_unit(|| {}, return_unit), u.into());

tests/ui/unused_unit.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ LL | fn return_unit() -> () { () }
3737
| ^^ help: remove the final `()`
3838

3939
error: unneeded `()`
40-
--> $DIR/unused_unit.rs:43:14
40+
--> $DIR/unused_unit.rs:44:14
4141
|
4242
LL | break();
4343
| ^^ help: remove the `()`
4444

4545
error: unneeded `()`
46-
--> $DIR/unused_unit.rs:45:11
46+
--> $DIR/unused_unit.rs:46:11
4747
|
4848
LL | return();
4949
| ^^ help: remove the `()`

0 commit comments

Comments
 (0)