Make collapsible_if recognize the let_chains feature

Until `if let` chains are stabilized, we do not collapse them together
or with other `if` expressions unless the `let_chains` feature is
enabled. This is the case for example in Clippy sources.
This commit is contained in:
Samuel Tardieu 2025-03-26 20:23:31 +01:00
parent 9df5177287
commit cd70152470
9 changed files with 254 additions and 13 deletions

View file

@ -5,6 +5,7 @@ use rustc_ast::BinOpKind;
use rustc_errors::Applicability;
use rustc_hir::{Block, Expr, ExprKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyCtxt;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
@ -77,12 +78,14 @@ declare_clippy_lint! {
}
pub struct CollapsibleIf {
let_chains_enabled: bool,
lint_commented_code: bool,
}
impl CollapsibleIf {
pub fn new(conf: &'static Conf) -> Self {
pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
Self {
let_chains_enabled: tcx.features().let_chains(),
lint_commented_code: conf.lint_commented_code,
}
}
@ -124,8 +127,7 @@ impl CollapsibleIf {
if let Some(inner) = expr_block(then)
&& cx.tcx.hir_attrs(inner.hir_id).is_empty()
&& let ExprKind::If(check_inner, _, None) = &inner.kind
// Prevent triggering on `if c { if let a = b { .. } }`.
&& !matches!(check_inner.kind, ExprKind::Let(..))
&& self.eligible_condition(check_inner)
&& let ctxt = expr.span.ctxt()
&& inner.span.ctxt() == ctxt
&& (self.lint_commented_code || !block_starts_with_comment(cx, then))
@ -160,6 +162,10 @@ impl CollapsibleIf {
);
}
}
pub fn eligible_condition(&self, cond: &Expr<'_>) -> bool {
self.let_chains_enabled || !matches!(cond.kind, ExprKind::Let(..))
}
}
impl_lint_pass!(CollapsibleIf => [COLLAPSIBLE_IF, COLLAPSIBLE_ELSE_IF]);
@ -174,11 +180,10 @@ impl LateLintPass<'_> for CollapsibleIf {
{
Self::check_collapsible_else_if(cx, then.span, else_);
} else if else_.is_none()
&& !matches!(cond.kind, ExprKind::Let(..))
&& self.eligible_condition(cond)
&& let ExprKind::Block(then, None) = then.kind
{
// Prevent triggering on `if c { if let a = b { .. } }`.
self.check_collapsible_if_if(cx, expr, cond, block!(then));
self.check_collapsible_if_if(cx, expr, cond, then);
}
}
}

View file

@ -771,7 +771,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(redundant_closure_call::RedundantClosureCall));
store.register_early_pass(|| Box::new(unused_unit::UnusedUnit));
store.register_late_pass(|_| Box::new(returns::Return));
store.register_late_pass(move |_| Box::new(collapsible_if::CollapsibleIf::new(conf)));
store.register_late_pass(move |tcx| Box::new(collapsible_if::CollapsibleIf::new(tcx, conf)));
store.register_late_pass(|_| Box::new(items_after_statements::ItemsAfterStatements));
store.register_early_pass(|| Box::new(precedence::Precedence));
store.register_late_pass(|_| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals));