Skip to content

Commit c3f3c58

Browse files
committed
Auto merge of rust-lang#8805 - Alexendoo:let-chain-docs, r=flip1995
Recommend let chains over if_chain in docs Switches over bit_mask.rs to let chains in order to create a nice example While the rustfmt thing isn't resolved yet, my rust-analyzer isn't a fan of large `if_chains!`s, it stops giving me hover info and such after some number of if statements changelog: none
2 parents 4667198 + c9d88ef commit c3f3c58

File tree

4 files changed

+37
-41
lines changed

4 files changed

+37
-41
lines changed

CONTRIBUTING.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ and resolved paths.
6969
To figure out how this syntax structure is encoded in the AST, it is recommended to run
7070
`rustc -Z unpretty=ast-tree` on an example of the structure and compare with the [nodes in the AST docs].
7171
Usually the lint will end up to be a nested series of matches and ifs, [like so][deep-nesting].
72-
But we can make it nest-less by using [if_chain] macro, [like this][nest-less].
72+
But we can make it nest-less by using [let chains], [like this][nest-less].
7373

7474
[`E-medium`] issues are generally pretty easy too, though it's recommended you work on an [`good-first-issue`]
7575
first. Sometimes they are only somewhat involved code wise, but not difficult per-se.
@@ -87,9 +87,9 @@ an AST expression). `match_def_path()` in Clippy's `utils` module can also be us
8787
[`E-medium`]: https://github.com/rust-lang/rust-clippy/labels/E-medium
8888
[`ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty
8989
[nodes in the AST docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/
90-
[deep-nesting]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/mem_forget.rs#L29-L43
91-
[if_chain]: https://docs.rs/if_chain/*/if_chain
92-
[nest-less]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/bit_mask.rs#L124-L150
90+
[deep-nesting]: https://github.com/rust-lang/rust-clippy/blob/5e4f0922911536f80d9591180fa604229ac13939/clippy_lints/src/mem_forget.rs#L31-L45
91+
[let chains]: https://github.com/rust-lang/rust/pull/94927
92+
[nest-less]: https://github.com/rust-lang/rust-clippy/blob/5e4f0922911536f80d9591180fa604229ac13939/clippy_lints/src/bit_mask.rs#L133-L159
9393

9494
## Writing code
9595

clippy_lints/src/bit_mask.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use clippy_utils::consts::{constant, Constant};
22
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
33
use clippy_utils::sugg::Sugg;
4-
use if_chain::if_chain;
54
use rustc_ast::ast::LitKind;
65
use rustc_errors::Applicability;
76
use rustc_hir::{BinOpKind, Expr, ExprKind};
@@ -130,32 +129,33 @@ impl<'tcx> LateLintPass<'tcx> for BitMask {
130129
}
131130
}
132131
}
133-
if_chain! {
134-
if let ExprKind::Binary(op, left, right) = &e.kind;
135-
if BinOpKind::Eq == op.node;
136-
if let ExprKind::Binary(op1, left1, right1) = &left.kind;
137-
if BinOpKind::BitAnd == op1.node;
138-
if let ExprKind::Lit(lit) = &right1.kind;
139-
if let LitKind::Int(n, _) = lit.node;
140-
if let ExprKind::Lit(lit1) = &right.kind;
141-
if let LitKind::Int(0, _) = lit1.node;
142-
if n.leading_zeros() == n.count_zeros();
143-
if n > u128::from(self.verbose_bit_mask_threshold);
144-
then {
145-
span_lint_and_then(cx,
146-
VERBOSE_BIT_MASK,
147-
e.span,
148-
"bit mask could be simplified with a call to `trailing_zeros`",
149-
|diag| {
132+
133+
if let ExprKind::Binary(op, left, right) = &e.kind
134+
&& BinOpKind::Eq == op.node
135+
&& let ExprKind::Binary(op1, left1, right1) = &left.kind
136+
&& BinOpKind::BitAnd == op1.node
137+
&& let ExprKind::Lit(lit) = &right1.kind
138+
&& let LitKind::Int(n, _) = lit.node
139+
&& let ExprKind::Lit(lit1) = &right.kind
140+
&& let LitKind::Int(0, _) = lit1.node
141+
&& n.leading_zeros() == n.count_zeros()
142+
&& n > u128::from(self.verbose_bit_mask_threshold)
143+
{
144+
span_lint_and_then(
145+
cx,
146+
VERBOSE_BIT_MASK,
147+
e.span,
148+
"bit mask could be simplified with a call to `trailing_zeros`",
149+
|diag| {
150150
let sugg = Sugg::hir(cx, left1, "...").maybe_par();
151151
diag.span_suggestion(
152152
e.span,
153153
"try",
154154
format!("{}.trailing_zeros() >= {}", sugg, n.count_ones()),
155155
Applicability::MaybeIncorrect,
156156
);
157-
});
158-
}
157+
},
158+
);
159159
}
160160
}
161161
}

doc/adding_lints.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ Here are some pointers to things you are likely going to need for every lint:
656656
* [Clippy utils][utils] - Various helper functions. Maybe the function you need
657657
is already in here ([`is_type_diagnostic_item`], [`implements_trait`], [`snippet`], etc)
658658
* [Clippy diagnostics][diagnostics]
659-
* [The `if_chain` macro][if_chain]
659+
* [Let chains][let-chains]
660660
* [`from_expansion`][from_expansion] and [`in_external_macro`][in_external_macro]
661661
* [`Span`][span]
662662
* [`Applicability`][applicability]
@@ -684,7 +684,7 @@ don't hesitate to ask on [Zulip] or in the issue/PR.
684684
[`is_type_diagnostic_item`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.is_type_diagnostic_item.html
685685
[`implements_trait`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.implements_trait.html
686686
[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
687-
[if_chain]: https://docs.rs/if_chain/*/if_chain/
687+
[let-chains]: https://github.com/rust-lang/rust/pull/94927
688688
[from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
689689
[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
690690
[span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html

doc/common_tools_writing_lints.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,14 @@ Starting with an `expr`, you can check whether it is calling a specific method `
6262
```rust
6363
impl<'tcx> LateLintPass<'tcx> for MyStructLint {
6464
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
65-
if_chain! {
66-
// Check our expr is calling a method
67-
if let hir::ExprKind::MethodCall(path, _, [_self_arg, ..]) = &expr.kind;
65+
// Check our expr is calling a method
66+
if let hir::ExprKind::MethodCall(path, _, [_self_arg, ..]) = &expr.kind
6867
// Check the name of this method is `some_method`
69-
if path.ident.name == sym!(some_method);
68+
&& path.ident.name == sym!(some_method)
7069
// Optionally, check the type of the self argument.
7170
// - See "Checking for a specific type"
72-
then {
71+
{
7372
// ...
74-
}
7573
}
7674
}
7775
}
@@ -165,18 +163,16 @@ use clippy_utils::{is_type_diagnostic_item, return_ty};
165163

166164
impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
167165
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
168-
if_chain! {
169-
// Check if item is a method/function
170-
if let ImplItemKind::Fn(ref signature, _) = impl_item.kind;
166+
// Check if item is a method/function
167+
if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
171168
// Check the method is named `some_method`
172-
if impl_item.ident.name == sym!(some_method);
169+
&& impl_item.ident.name == sym!(some_method)
173170
// We can also check it has a parameter `self`
174-
if signature.decl.implicit_self.has_implicit_self();
171+
&& signature.decl.implicit_self.has_implicit_self()
175172
// We can go further and even check if its return type is `String`
176-
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym!(string_type));
177-
then {
178-
// ...
179-
}
173+
&& is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym!(string_type))
174+
{
175+
// ...
180176
}
181177
}
182178
}

0 commit comments

Comments
 (0)