fix issues 10836

This commit is contained in:
disco07 2023-05-30 07:43:10 +02:00
parent f1fd4673bc
commit d3534a6521
3 changed files with 54 additions and 17 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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