fix issues 10836
This commit is contained in:
parent
f1fd4673bc
commit
d3534a6521
@ -8,10 +8,12 @@ use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
||||
use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass, Level};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::sym;
|
||||
use rustc_span::symbol::Ident;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
@ -89,6 +91,27 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
cx.tcx
|
||||
.lang_items()
|
||||
.not_trait()
|
||||
.filter(|trait_id| implements_trait(cx, ty, *trait_id, &[]))
|
||||
.and_then(|trait_id| {
|
||||
cx.tcx.associated_items(trait_id).find_by_name_and_kind(
|
||||
cx.tcx,
|
||||
Ident::from_str("Output"),
|
||||
ty::AssocKind::Type,
|
||||
trait_id,
|
||||
)
|
||||
})
|
||||
.map_or(false, |assoc_item| {
|
||||
let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, []));
|
||||
let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj);
|
||||
|
||||
nty.is_bool()
|
||||
})
|
||||
}
|
||||
|
||||
struct NonminimalBoolVisitor<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
}
|
||||
@ -473,6 +496,12 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
|
||||
self.bool_expr(e);
|
||||
},
|
||||
ExprKind::Unary(UnOp::Not, inner) => {
|
||||
if let ExprKind::Unary(UnOp::Not, ex) = inner.kind {
|
||||
let ty = self.cx.typeck_results().expr_ty(ex);
|
||||
if is_impl_not_trait_with_bool_out(self.cx, ty) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {
|
||||
self.bool_expr(e);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ fn main() {
|
||||
let e: bool = unimplemented!();
|
||||
let _ = !true;
|
||||
let _ = !false;
|
||||
// vvv Should not lint
|
||||
let _ = !!a;
|
||||
let _ = false || a;
|
||||
// don't lint on cfgs
|
||||
@ -54,7 +55,6 @@ fn issue4548() {
|
||||
|
||||
fn check_expect() {
|
||||
let a: bool = unimplemented!();
|
||||
#[expect(clippy::nonminimal_bool)]
|
||||
let _ = !!a;
|
||||
}
|
||||
|
||||
@ -110,3 +110,17 @@ fn issue_10435() {
|
||||
println!("{}", line!());
|
||||
}
|
||||
}
|
||||
|
||||
fn issue10836() {
|
||||
struct Foo(bool);
|
||||
impl std::ops::Not for Foo {
|
||||
type Output = bool;
|
||||
|
||||
fn not(self) -> Self::Output {
|
||||
!self.0
|
||||
}
|
||||
}
|
||||
|
||||
// Should not lint
|
||||
let _: bool = !!Foo(true);
|
||||
}
|
||||
|
@ -13,37 +13,31 @@ LL | let _ = !false;
|
||||
| ^^^^^^ help: try: `true`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:13:13
|
||||
|
|
||||
LL | let _ = !!a;
|
||||
| ^^^ help: try: `a`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:14:13
|
||||
--> $DIR/nonminimal_bool.rs:15:13
|
||||
|
|
||||
LL | let _ = false || a;
|
||||
| ^^^^^^^^^^ help: try: `a`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:18:13
|
||||
--> $DIR/nonminimal_bool.rs:19:13
|
||||
|
|
||||
LL | let _ = !(!a && b);
|
||||
| ^^^^^^^^^^ help: try: `a || !b`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:19:13
|
||||
--> $DIR/nonminimal_bool.rs:20:13
|
||||
|
|
||||
LL | let _ = !(!a || b);
|
||||
| ^^^^^^^^^^ help: try: `a && !b`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:20:13
|
||||
--> $DIR/nonminimal_bool.rs:21:13
|
||||
|
|
||||
LL | let _ = !a && !(b && c);
|
||||
| ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)`
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:28:13
|
||||
--> $DIR/nonminimal_bool.rs:29:13
|
||||
|
|
||||
LL | let _ = a == b && c == 5 && a == b;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -56,7 +50,7 @@ LL | let _ = a == b && c == 5;
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:29:13
|
||||
--> $DIR/nonminimal_bool.rs:30:13
|
||||
|
|
||||
LL | let _ = a == b || c == 5 || a == b;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -69,7 +63,7 @@ LL | let _ = a == b || c == 5;
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:30:13
|
||||
--> $DIR/nonminimal_bool.rs:31:13
|
||||
|
|
||||
LL | let _ = a == b && c == 5 && b == a;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -82,7 +76,7 @@ LL | let _ = a == b && c == 5;
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:31:13
|
||||
--> $DIR/nonminimal_bool.rs:32:13
|
||||
|
|
||||
LL | let _ = a != b || !(a != b || c == d);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -95,7 +89,7 @@ LL | let _ = a != b || c != d;
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/nonminimal_bool.rs:32:13
|
||||
--> $DIR/nonminimal_bool.rs:33:13
|
||||
|
|
||||
LL | let _ = a != b && !(a != b && c == d);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -113,5 +107,5 @@ error: this boolean expression can be simplified
|
||||
LL | if matches!(true, true) && true {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)`
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user