use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::MetaItemInner; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does /// Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#[cfg(not(test))]`) /// /// ### Why is this bad? /// This may give the false impression that a codebase has 100% coverage, yet actually has untested code. /// Enabling this also guards against excessive mockery as well, which is an anti-pattern. /// /// ### Example /// ```rust /// # fn important_check() {} /// #[cfg(not(test))] /// important_check(); // I'm not actually tested, but not including me will falsely increase coverage! /// ``` /// Use instead: /// ```rust /// # fn important_check() {} /// important_check(); /// ``` #[clippy::version = "1.81.0"] pub CFG_NOT_TEST, restriction, "enforce against excluding code from test builds" } declare_lint_pass!(CfgNotTest => [CFG_NOT_TEST]); impl EarlyLintPass for CfgNotTest { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &rustc_ast::Attribute) { if attr.has_name(rustc_span::sym::cfg) && contains_not_test(attr.meta_item_list().as_deref(), false) { span_lint_and_then( cx, CFG_NOT_TEST, attr.span, "code is excluded from test builds", |diag| { diag.help("consider not excluding any code from test builds"); diag.note_once("this could increase code coverage despite not actually being tested"); }, ); } } } fn contains_not_test(list: Option<&[MetaItemInner]>, not: bool) -> bool { list.is_some_and(|list| { list.iter().any(|item| { item.ident().is_some_and(|ident| match ident.name { rustc_span::sym::not => contains_not_test(item.meta_item_list(), !not), rustc_span::sym::test => not, _ => contains_not_test(item.meta_item_list(), not), }) }) }) }