From 9f131e5a0bbaa2d4a9cd8cd2524695725680ceb4 Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Thu, 31 Mar 2022 22:28:59 -0600
Subject: [PATCH] assertions_on_constants: ignore indirect `cfg!`
---
clippy_utils/src/consts.rs | 18 +++++++++++++++++-
tests/ui/assertions_on_constants.rs | 10 ++++++++--
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index 1d6f7acab13..0e916ca8164 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -5,7 +5,7 @@ use if_chain::if_chain;
use rustc_ast::ast::{self, LitFloatType, LitKind};
use rustc_data_structures::sync::Lrc;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, QPath, UnOp};
+use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
use rustc_lint::LateContext;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::ty::subst::{Subst, SubstsRef};
@@ -400,6 +400,22 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
let res = self.typeck_results.qpath_res(qpath, id);
match res {
Res::Def(DefKind::Const | DefKind::AssocConst, def_id) => {
+ // Check if this constant is based on `cfg!(..)`,
+ // which is NOT constant for our purposes.
+ if let Some(node) = self.lcx.tcx.hir().get_if_local(def_id) &&
+ let Node::Item(&Item {
+ kind: ItemKind::Const(_, body_id),
+ ..
+ }) = node &&
+ let Node::Expr(&Expr {
+ kind: ExprKind::Lit(_),
+ span,
+ ..
+ }) = self.lcx.tcx.hir().get(body_id.hir_id) &&
+ is_direct_expn_of(span, "cfg").is_some() {
+ return None;
+ }
+
let substs = self.typeck_results.node_substs(id);
let substs = if self.substs.is_empty() {
substs
diff --git a/tests/ui/assertions_on_constants.rs b/tests/ui/assertions_on_constants.rs
index 7477c01ca78..7bea9563d47 100644
--- a/tests/ui/assertions_on_constants.rs
+++ b/tests/ui/assertions_on_constants.rs
@@ -1,4 +1,4 @@
-#![allow(non_fmt_panics)]
+#![allow(non_fmt_panics, clippy::needless_bool)]
macro_rules! assert_const {
($len:expr) => {
@@ -28,6 +28,12 @@ fn main() {
assert_const!(3);
assert_const!(-1);
- // Don't lint on this:
+ // Don't lint if based on `cfg!(..)`:
assert!(cfg!(feature = "hey") || cfg!(not(feature = "asdf")));
+
+ let flag: bool = cfg!(not(feature = "asdf"));
+ assert!(flag);
+
+ const CFG_FLAG: &bool = &cfg!(feature = "hey");
+ assert!(!CFG_FLAG);
}