about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-23 13:33:51 +0000
committerbors <bors@rust-lang.org>2023-04-23 13:33:51 +0000
commit496c11005c30d93cbae5e2f27f15cc387dc0787b (patch)
tree68ae1922329ca16b40859c8db3441b31d278ad91
parent316d83a4d81d295f5a36361d8141f030f513c3ee (diff)
parent654d12ff8930a332a4cdcfccc6c1c34700e2f3b7 (diff)
downloadrust-496c11005c30d93cbae5e2f27f15cc387dc0787b.tar.gz
rust-496c11005c30d93cbae5e2f27f15cc387dc0787b.zip
Auto merge of #10679 - y21:better-const-ctx-check, r=Jarcho
use `is_inside_const_context` for `in_constant` util fn

Fixes #10452.

This PR improves the `in_constant` util function to detect more cases of const contexts. Previously this function would not detect cases like expressions in array length position or expression in an inline const block `const { .. }`.

changelog: [`bool_to_int_with_if`]: recognize array length operand as being in a const context and don't suggest `usize::from` there
-rw-r--r--clippy_utils/src/lib.rs32
-rw-r--r--tests/ui/bool_to_int_with_if.fixed9
-rw-r--r--tests/ui/bool_to_int_with_if.rs9
-rw-r--r--tests/ui/bool_to_int_with_if.stderr2
4 files changed, 21 insertions, 31 deletions
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 4b9fa033446..ba4bd6e1769 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -86,10 +86,10 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
 use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
 use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
 use rustc_hir::{
-    self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination,
-    Expr, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item, ItemKind, LangItem, Local,
+    self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr,
+    ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item, ItemKind, LangItem, Local,
     MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind,
-    TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
+    TraitItem, TraitItemRef, TraitRef, TyKind, UnOp,
 };
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
@@ -197,31 +197,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<
 /// }
 /// ```
 pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool {
-    let parent_id = cx.tcx.hir().get_parent_item(id).def_id;
-    match cx.tcx.hir().get_by_def_id(parent_id) {
-        Node::Item(&Item {
-            kind: ItemKind::Const(..) | ItemKind::Static(..) | ItemKind::Enum(..),
-            ..
-        })
-        | Node::TraitItem(&TraitItem {
-            kind: TraitItemKind::Const(..),
-            ..
-        })
-        | Node::ImplItem(&ImplItem {
-            kind: ImplItemKind::Const(..),
-            ..
-        })
-        | Node::AnonConst(_) => true,
-        Node::Item(&Item {
-            kind: ItemKind::Fn(ref sig, ..),
-            ..
-        })
-        | Node::ImplItem(&ImplItem {
-            kind: ImplItemKind::Fn(ref sig, _),
-            ..
-        }) => sig.header.constness == Constness::Const,
-        _ => false,
-    }
+    cx.tcx.hir().is_inside_const_context(id)
 }
 
 /// Checks if a `Res` refers to a constructor of a `LangItem`
diff --git a/tests/ui/bool_to_int_with_if.fixed b/tests/ui/bool_to_int_with_if.fixed
index 9831c3373d4..fbb10a133e2 100644
--- a/tests/ui/bool_to_int_with_if.fixed
+++ b/tests/ui/bool_to_int_with_if.fixed
@@ -1,6 +1,6 @@
 //@run-rustfix
 
-#![feature(let_chains)]
+#![feature(let_chains, inline_const)]
 #![warn(clippy::bool_to_int_with_if)]
 #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
 
@@ -79,6 +79,13 @@ fn main() {
 
     pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 };
 
+    // https://github.com/rust-lang/rust-clippy/issues/10452
+    let should_not_lint = [(); if true { 1 } else { 0 }];
+
+    let should_not_lint = const {
+        if true { 1 } else { 0 }
+    };
+
     some_fn(a);
 }
 
diff --git a/tests/ui/bool_to_int_with_if.rs b/tests/ui/bool_to_int_with_if.rs
index 5e3047bb32c..709a18d63e4 100644
--- a/tests/ui/bool_to_int_with_if.rs
+++ b/tests/ui/bool_to_int_with_if.rs
@@ -1,6 +1,6 @@
 //@run-rustfix
 
-#![feature(let_chains)]
+#![feature(let_chains, inline_const)]
 #![warn(clippy::bool_to_int_with_if)]
 #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
 
@@ -111,6 +111,13 @@ fn main() {
 
     pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 };
 
+    // https://github.com/rust-lang/rust-clippy/issues/10452
+    let should_not_lint = [(); if true { 1 } else { 0 }];
+
+    let should_not_lint = const {
+        if true { 1 } else { 0 }
+    };
+
     some_fn(a);
 }
 
diff --git a/tests/ui/bool_to_int_with_if.stderr b/tests/ui/bool_to_int_with_if.stderr
index 5cfb75cc0df..3bdae75cad2 100644
--- a/tests/ui/bool_to_int_with_if.stderr
+++ b/tests/ui/bool_to_int_with_if.stderr
@@ -98,7 +98,7 @@ LL | |     };
    = note: `!b as i32` or `(!b).into()` can also be valid options
 
 error: boolean to int conversion using if
-  --> $DIR/bool_to_int_with_if.rs:119:5
+  --> $DIR/bool_to_int_with_if.rs:126:5
    |
 LL |     if a { 1 } else { 0 }
    |     ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)`