Apply collapsible_if to Clippy itself

Since Clippy uses the `let_chains` feature, there are many occasions to
collapse `if` and `if let` statements.
This commit is contained in:
Samuel Tardieu 2025-03-26 20:38:58 +01:00
parent cd70152470
commit 79c69112dc
135 changed files with 1870 additions and 1913 deletions

View file

@ -17,16 +17,16 @@ use rustc_span::Span;
use std::env;
fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
if env::var("CLIPPY_DISABLE_DOCS_LINKS").is_err() {
if let Some(lint) = lint.name_lower().strip_prefix("clippy::") {
diag.help(format!(
"for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{lint}",
&option_env!("RUST_RELEASE_NUM").map_or("master".to_string(), |n| {
// extract just major + minor version and ignore patch versions
format!("rust-{}", n.rsplit_once('.').unwrap().1)
})
));
}
if env::var("CLIPPY_DISABLE_DOCS_LINKS").is_err()
&& let Some(lint) = lint.name_lower().strip_prefix("clippy::")
{
diag.help(format!(
"for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{lint}",
&option_env!("RUST_RELEASE_NUM").map_or("master".to_string(), |n| {
// extract just major + minor version and ignore patch versions
format!("rust-{}", n.rsplit_once('.').unwrap().1)
})
));
}
}

View file

@ -118,18 +118,17 @@ impl<'hir> IfLet<'hir> {
) = expr.kind
{
let mut iter = cx.tcx.hir_parent_iter(expr.hir_id);
if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next() {
if let Some((
if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next()
&& let Some((
_,
Node::Expr(Expr {
kind: ExprKind::Loop(_, _, LoopSource::While, _),
..
}),
)) = iter.next()
{
// while loop desugar
return None;
}
{
// while loop desugar
return None;
}
return Some(Self {
let_pat,

View file

@ -367,10 +367,10 @@ pub fn is_inherent_method_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
/// Checks if a method is defined in an impl of a diagnostic item
pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
if let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() {
return cx.tcx.is_diagnostic_item(diag_item, adt.did());
}
if let Some(impl_did) = cx.tcx.impl_of_method(def_id)
&& let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def()
{
return cx.tcx.is_diagnostic_item(diag_item, adt.did());
}
false
}
@ -457,10 +457,10 @@ pub fn match_qpath(path: &QPath<'_>, segments: &[&str]) -> bool {
QPath::Resolved(_, path) => match_path(path, segments),
QPath::TypeRelative(ty, segment) => match ty.kind {
TyKind::Path(ref inner_path) => {
if let [prefix @ .., end] = segments {
if match_qpath(inner_path, prefix) {
return segment.ident.name.as_str() == *end;
}
if let [prefix @ .., end] = segments
&& match_qpath(inner_path, prefix)
{
return segment.ident.name.as_str() == *end;
}
false
},
@ -523,10 +523,10 @@ pub fn match_path(path: &Path<'_>, segments: &[&str]) -> bool {
/// If the expression is a path to a local, returns the canonical `HirId` of the local.
pub fn path_to_local(expr: &Expr<'_>) -> Option<HirId> {
if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind {
if let Res::Local(id) = path.res {
return Some(id);
}
if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind
&& let Res::Local(id) = path.res
{
return Some(id);
}
None
}
@ -893,16 +893,14 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
sym::BinaryHeap,
];
if let QPath::TypeRelative(_, method) = path {
if method.ident.name == sym::new {
if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
if let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() {
return std_types_symbols.iter().any(|&symbol| {
cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string()
});
}
}
}
if let QPath::TypeRelative(_, method) = path
&& method.ident.name == sym::new
&& let Some(impl_did) = cx.tcx.impl_of_method(def_id)
&& let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def()
{
return std_types_symbols.iter().any(|&symbol| {
cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string()
});
}
false
}
@ -1204,12 +1202,10 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
.adjustments()
.get(child_id)
.map_or(&[][..], |x| &**x)
{
if let rustc_ty::RawPtr(_, mutability) | rustc_ty::Ref(_, _, mutability) =
&& let rustc_ty::RawPtr(_, mutability) | rustc_ty::Ref(_, _, mutability) =
*adjust.last().map_or(target, |a| a.target).kind()
{
return CaptureKind::Ref(mutability);
}
{
return CaptureKind::Ref(mutability);
}
match parent {
@ -1737,10 +1733,10 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool
/// Checks whether the given expression is a constant literal of the given value.
pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool {
// FIXME: use constant folding
if let ExprKind::Lit(spanned) = expr.kind {
if let LitKind::Int(v, _) = spanned.node {
return v == value;
}
if let ExprKind::Lit(spanned) = expr.kind
&& let LitKind::Int(v, _) = spanned.node
{
return v == value;
}
false
}
@ -1777,10 +1773,10 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
let data = span.ctxt().outer_expn_data();
let new_span = data.call_site;
if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind {
if mac_name.as_str() == name {
return Some(new_span);
}
if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind
&& mac_name.as_str() == name
{
return Some(new_span);
}
span = new_span;
@ -1806,10 +1802,10 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
let data = span.ctxt().outer_expn_data();
let new_span = data.call_site;
if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind {
if mac_name.as_str() == name {
return Some(new_span);
}
if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind
&& mac_name.as_str() == name
{
return Some(new_span);
}
}
@ -1830,15 +1826,15 @@ pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId, nth: usize) ->
/// Checks if an expression is constructing a tuple-like enum variant or struct
pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
if let ExprKind::Call(fun, _) = expr.kind {
if let ExprKind::Path(ref qp) = fun.kind {
let res = cx.qpath_res(qp, fun.hir_id);
return match res {
Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
_ => false,
};
}
if let ExprKind::Call(fun, _) = expr.kind
&& let ExprKind::Path(ref qp) = fun.kind
{
let res = cx.qpath_res(qp, fun.hir_id);
return match res {
Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
_ => false,
};
}
false
}
@ -1911,10 +1907,10 @@ pub fn is_self(slf: &Param<'_>) -> bool {
}
pub fn is_self_ty(slf: &hir::Ty<'_>) -> bool {
if let TyKind::Path(QPath::Resolved(None, path)) = slf.kind {
if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path.res {
return true;
}
if let TyKind::Path(QPath::Resolved(None, path)) = slf.kind
&& let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path.res
{
return true;
}
false
}
@ -2119,10 +2115,10 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
}
// final `else {..}`
if !blocks.is_empty() {
if let ExprKind::Block(block, _) = expr.kind {
blocks.push(block);
}
if !blocks.is_empty()
&& let ExprKind::Block(block, _) = expr.kind
{
blocks.push(block);
}
(conds, blocks)
@ -2139,8 +2135,8 @@ pub fn is_async_fn(kind: FnKind<'_>) -> bool {
/// Peels away all the compiler generated code surrounding the body of an async function,
pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'tcx Expr<'tcx>> {
if let ExprKind::Closure(&Closure { body, .. }) = body.value.kind {
if let ExprKind::Block(
if let ExprKind::Closure(&Closure { body, .. }) = body.value.kind
&& let ExprKind::Block(
Block {
stmts: [],
expr:
@ -2152,9 +2148,8 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t
},
_,
) = tcx.hir_body(body).value.kind
{
return Some(expr);
}
{
return Some(expr);
}
None
}
@ -2628,10 +2623,10 @@ pub fn peel_ref_operators<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>
}
pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
if let Res::Def(_, def_id) = path.res {
return cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr);
}
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
&& let Res::Def(_, def_id) = path.res
{
return cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr);
}
false
}
@ -2650,18 +2645,16 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym
if matches!(tcx.def_kind(id.owner_id), DefKind::Const)
&& let item = tcx.hir_item(id)
&& let ItemKind::Const(ident, ty, _generics, _body) = item.kind
{
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
&& let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
// We could also check for the type name `test::TestDescAndFn`
if let Res::Def(DefKind::Struct, _) = path.res {
let has_test_marker = tcx
.hir_attrs(item.hir_id())
.iter()
.any(|a| a.has_name(sym::rustc_test_marker));
if has_test_marker {
names.push(ident.name);
}
}
&& let Res::Def(DefKind::Struct, _) = path.res
{
let has_test_marker = tcx
.hir_attrs(item.hir_id())
.iter()
.any(|a| a.has_name(sym::rustc_test_marker));
if has_test_marker {
names.push(ident.name);
}
}
}
@ -2682,12 +2675,12 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool {
// Since you can nest functions we need to collect all until we leave
// function scope
.any(|(_id, node)| {
if let Node::Item(item) = node {
if let ItemKind::Fn { ident, .. } = item.kind {
// Note that we have sorted the item names in the visitor,
// so the binary_search gets the same as `contains`, but faster.
return names.binary_search(&ident.name).is_ok();
}
if let Node::Item(item) = node
&& let ItemKind::Fn { ident, .. } = item.kind
{
// Note that we have sorted the item names in the visitor,
// so the binary_search gets the same as `contains`, but faster.
return names.binary_search(&ident.name).is_ok();
}
false
})

View file

@ -384,10 +384,10 @@ pub fn snippet_indent(sess: &impl HasSession, span: Span) -> Option<String> {
// For some reason these attributes don't have any expansion info on them, so
// we have to check it this way until there is a better way.
pub fn is_present_in_source(sess: &impl HasSession, span: Span) -> bool {
if let Some(snippet) = snippet_opt(sess, span) {
if snippet.is_empty() {
return false;
}
if let Some(snippet) = snippet_opt(sess, span)
&& snippet.is_empty()
{
return false;
}
true
}
@ -408,11 +408,11 @@ pub fn position_before_rarrow(s: &str) -> Option<usize> {
let mut rpos = rpos;
let chars: Vec<char> = s.chars().collect();
while rpos > 1 {
if let Some(c) = chars.get(rpos - 1) {
if c.is_whitespace() {
rpos -= 1;
continue;
}
if let Some(c) = chars.get(rpos - 1)
&& c.is_whitespace()
{
rpos -= 1;
continue;
}
break;
}

View file

@ -947,11 +947,10 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
// some items do not need explicit deref, such as array accesses,
// so we mark them as already processed
// i.e.: don't suggest `*sub[1..4].len()` for `|sub| sub[1..4].len() == 3`
if let ty::Ref(_, inner, _) = cmt.place.ty_before_projection(i).kind() {
if matches!(inner.kind(), ty::Ref(_, innermost, _) if innermost.is_array()) {
if let ty::Ref(_, inner, _) = cmt.place.ty_before_projection(i).kind()
&& matches!(inner.kind(), ty::Ref(_, innermost, _) if innermost.is_array()) {
projections_handled = true;
}
}
},
}
});

View file

@ -128,10 +128,10 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
// For `impl Trait<Assoc=U>`, it will register a predicate of `<T as Trait>::Assoc = U`,
// so we check the term for `U`.
ty::ClauseKind::Projection(projection_predicate) => {
if let ty::TermKind::Ty(ty) = projection_predicate.term.unpack() {
if contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen) {
return true;
}
if let ty::TermKind::Ty(ty) = projection_predicate.term.unpack()
&& contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen)
{
return true;
}
},
_ => (),
@ -337,20 +337,20 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),
ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
for (predicate, _) in cx.tcx.explicit_item_self_bounds(def_id).skip_binder() {
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
return true;
}
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
&& cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use)
{
return true;
}
}
false
},
ty::Dynamic(binder, _, _) => {
for predicate in *binder {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
if cx.tcx.has_attr(trait_ref.def_id, sym::must_use) {
return true;
}
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()
&& cx.tcx.has_attr(trait_ref.def_id, sym::must_use)
{
return true;
}
}
false

View file

@ -126,10 +126,10 @@ impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies;
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) -> Self::Result {
if let Res::Local(id) = path.res {
if self.binding_ids.contains(&id) {
return ControlFlow::Break(());
}
if let Res::Local(id) = path.res
&& self.binding_ids.contains(&id)
{
return ControlFlow::Break(());
}
ControlFlow::Continue(())

View file

@ -297,10 +297,10 @@ where
/// Checks if the given resolved path is used in the given body.
pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool {
for_each_expr(cx, cx.tcx.hir_body(body).value, |e| {
if let ExprKind::Path(p) = &e.kind {
if cx.qpath_res(p, e.hir_id) == res {
return ControlFlow::Break(());
}
if let ExprKind::Path(p) = &e.kind
&& cx.qpath_res(p, e.hir_id) == res
{
return ControlFlow::Break(());
}
ControlFlow::Continue(())
})