Skip to content

Commit 08b84b3

Browse files
committed
Auto merge of #5378 - Centril:unnested-or-pats, r=flip1995,phansch
New lint: `unnested_or_patterns` changelog: Adds a lint `unnested_or_patterns`, suggesting `Some(0 | 2)` as opposed to `Some(0) | Some(2)`. The lint only fires on compilers capable of using `#![feature(or_patterns)]`. - The lint is primarily encoded as a pure algorithm which to unnest or-patterns in an `ast::Pat` (`fn unnest_or_patterns`) through a `MutVisitor`. After that is done, and assuming that any change was detected, then `pprust::pat_to_string` is used to simply convert the transformed pattern into a suggestion. - The PR introduces a module `utils::ast_utils` with a bunch of functions for spanless & nodeless equality comparisons of ASTs. cc rust-lang/rust#54883
2 parents 67ec96c + a9ca832 commit 08b84b3

27 files changed

+1389
-96
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,7 @@ Released 2018-09-13
16831683
[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
16841684
[`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_field_pattern
16851685
[`unneeded_wildcard_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_wildcard_pattern
1686+
[`unnested_or_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns
16861687
[`unreachable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreachable
16871688
[`unreadable_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal
16881689
[`unsafe_derive_deserialize`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_derive_deserialize

clippy_lints/src/await_holding_lock.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,13 @@ declare_lint_pass!(AwaitHoldingLock => [AWAIT_HOLDING_LOCK]);
5454
impl LateLintPass<'_, '_> for AwaitHoldingLock {
5555
fn check_body(&mut self, cx: &LateContext<'_, '_>, body: &'_ Body<'_>) {
5656
use AsyncGeneratorKind::{Block, Closure, Fn};
57-
match body.generator_kind {
58-
Some(GeneratorKind::Async(Block))
59-
| Some(GeneratorKind::Async(Closure))
60-
| Some(GeneratorKind::Async(Fn)) => {
61-
let body_id = BodyId {
62-
hir_id: body.value.hir_id,
63-
};
64-
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
65-
let tables = cx.tcx.typeck_tables_of(def_id);
66-
check_interior_types(cx, &tables.generator_interior_types, body.value.span);
67-
},
68-
_ => {},
57+
if let Some(GeneratorKind::Async(Block | Closure | Fn)) = body.generator_kind {
58+
let body_id = BodyId {
59+
hir_id: body.value.hir_id,
60+
};
61+
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
62+
let tables = cx.tcx.typeck_tables_of(def_id);
63+
check_interior_types(cx, &tables.generator_interior_types, body.value.span);
6964
}
7065
}
7166
}

clippy_lints/src/formatting.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,8 @@ declare_lint_pass!(Formatting => [
112112
impl EarlyLintPass for Formatting {
113113
fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {
114114
for w in block.stmts.windows(2) {
115-
match (&w[0].kind, &w[1].kind) {
116-
(&StmtKind::Expr(ref first), &StmtKind::Expr(ref second))
117-
| (&StmtKind::Expr(ref first), &StmtKind::Semi(ref second)) => {
118-
check_missing_else(cx, first, second);
119-
},
120-
_ => (),
115+
if let (StmtKind::Expr(first), StmtKind::Expr(second) | StmtKind::Semi(second)) = (&w[0].kind, &w[1].kind) {
116+
check_missing_else(cx, first, second);
121117
}
122118
}
123119
}

clippy_lints/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// error-pattern:cargo-clippy
22

3+
#![feature(bindings_after_at)]
34
#![feature(box_syntax)]
45
#![feature(box_patterns)]
56
#![feature(or_patterns)]
@@ -12,6 +13,7 @@
1213
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
1314
#![feature(crate_visibility_modifier)]
1415
#![feature(concat_idents)]
16+
#![feature(drain_filter)]
1517

1618
// FIXME: switch to something more ergonomic here, once available.
1719
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
@@ -319,6 +321,7 @@ mod types;
319321
mod unicode;
320322
mod unnamed_address;
321323
mod unnecessary_sort_by;
324+
mod unnested_or_patterns;
322325
mod unsafe_removed_from_name;
323326
mod unused_io_amount;
324327
mod unused_self;
@@ -836,6 +839,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
836839
&unnamed_address::FN_ADDRESS_COMPARISONS,
837840
&unnamed_address::VTABLE_ADDRESS_COMPARISONS,
838841
&unnecessary_sort_by::UNNECESSARY_SORT_BY,
842+
&unnested_or_patterns::UNNESTED_OR_PATTERNS,
839843
&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
840844
&unused_io_amount::UNUSED_IO_AMOUNT,
841845
&unused_self::UNUSED_SELF,
@@ -1073,6 +1077,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10731077
store.register_early_pass(move || box non_expressive_names::NonExpressiveNames {
10741078
single_char_binding_names_threshold,
10751079
});
1080+
store.register_early_pass(|| box unnested_or_patterns::UnnestedOrPatterns);
10761081

10771082
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
10781083
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
@@ -1433,6 +1438,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
14331438
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
14341439
LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS),
14351440
LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY),
1441+
LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS),
14361442
LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
14371443
LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT),
14381444
LintId::of(&unwrap::PANICKING_UNWRAP),
@@ -1616,6 +1622,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
16161622
LintId::of(&types::UNNECESSARY_CAST),
16171623
LintId::of(&types::VEC_BOX),
16181624
LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY),
1625+
LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS),
16191626
LintId::of(&unwrap::UNNECESSARY_UNWRAP),
16201627
LintId::of(&useless_conversion::USELESS_CONVERSION),
16211628
LintId::of(&zero_div_zero::ZERO_DIVIDED_BY_ZERO),

clippy_lints/src/methods/manual_saturating_arithmetic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[&[hir::Expr<
5757
);
5858
} else {
5959
match (mm, arith) {
60-
(MinMax::Max, "add") | (MinMax::Max, "mul") | (MinMax::Min, "sub") => (),
60+
(MinMax::Max, "add" | "mul") | (MinMax::Min, "sub") => (),
6161
_ => return,
6262
}
6363

clippy_lints/src/methods/mod.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,9 +1403,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
14031403
lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1])
14041404
},
14051405
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
1406-
["as_ptr", "unwrap"] | ["as_ptr", "expect"] => {
1407-
lint_cstring_as_ptr(cx, expr, &arg_lists[1][0], &arg_lists[0][0])
1408-
},
1406+
["as_ptr", "unwrap" | "expect"] => lint_cstring_as_ptr(cx, expr, &arg_lists[1][0], &arg_lists[0][0]),
14091407
["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
14101408
["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
14111409
["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
@@ -1418,12 +1416,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
14181416
["filter_map", ..] => unnecessary_filter_map::lint(cx, expr, arg_lists[0]),
14191417
["count", "map"] => lint_suspicious_map(cx, expr),
14201418
["assume_init"] => lint_maybe_uninit(cx, &arg_lists[0][0], expr),
1421-
["unwrap_or", arith @ "checked_add"]
1422-
| ["unwrap_or", arith @ "checked_sub"]
1423-
| ["unwrap_or", arith @ "checked_mul"] => {
1419+
["unwrap_or", arith @ ("checked_add" | "checked_sub" | "checked_mul")] => {
14241420
manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..])
14251421
},
1426-
["add"] | ["offset"] | ["sub"] | ["wrapping_offset"] | ["wrapping_add"] | ["wrapping_sub"] => {
1422+
["add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub"] => {
14271423
check_pointer_offset(cx, expr, arg_lists[0])
14281424
},
14291425
["is_file", ..] => lint_filetype_is_file(cx, expr, arg_lists[0]),
@@ -1829,8 +1825,7 @@ fn lint_expect_fun_call(
18291825
hir::ExprKind::Call(fun, _) => {
18301826
if let hir::ExprKind::Path(ref p) = fun.kind {
18311827
match cx.tables.qpath_res(p, fun.hir_id) {
1832-
hir::def::Res::Def(hir::def::DefKind::Fn, def_id)
1833-
| hir::def::Res::Def(hir::def::DefKind::AssocFn, def_id) => matches!(
1828+
hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!(
18341829
cx.tcx.fn_sig(def_id).output().skip_binder().kind,
18351830
ty::Ref(ty::ReStatic, ..)
18361831
),

clippy_lints/src/misc.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
275275
return;
276276
}
277277
for arg in iter_input_pats(decl, body) {
278-
match arg.pat.kind {
279-
PatKind::Binding(BindingAnnotation::Ref, ..) | PatKind::Binding(BindingAnnotation::RefMut, ..) => {
280-
span_lint(
281-
cx,
282-
TOPLEVEL_REF_ARG,
283-
arg.pat.span,
284-
"`ref` directly on a function argument is ignored. Consider using a reference type \
285-
instead.",
286-
);
287-
},
288-
_ => {},
278+
if let PatKind::Binding(BindingAnnotation::Ref | BindingAnnotation::RefMut, ..) = arg.pat.kind {
279+
span_lint(
280+
cx,
281+
TOPLEVEL_REF_ARG,
282+
arg.pat.span,
283+
"`ref` directly on a function argument is ignored. \
284+
Consider using a reference type instead.",
285+
);
289286
}
290287
}
291288
}

clippy_lints/src/no_effect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option
147147
if let ExprKind::Path(ref qpath) = callee.kind {
148148
let res = qpath_res(cx, qpath, callee.hir_id);
149149
match res {
150-
Res::Def(DefKind::Struct, ..) | Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(..), _)
150+
Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..)
151151
if !has_drop(cx, cx.tables.expr_ty(expr)) =>
152152
{
153153
Some(args.iter().collect())

clippy_lints/src/suspicious_trait_impl.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
7171
if let hir::Node::Expr(e) = cx.tcx.hir().get(parent_expr) {
7272
match e.kind {
7373
hir::ExprKind::Binary(..)
74-
| hir::ExprKind::Unary(hir::UnOp::UnNot, _)
75-
| hir::ExprKind::Unary(hir::UnOp::UnNeg, _)
74+
| hir::ExprKind::Unary(hir::UnOp::UnNot | hir::UnOp::UnNeg, _)
7675
| hir::ExprKind::AssignOp(..) => return,
7776
_ => {},
7877
}
@@ -191,8 +190,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BinaryExprVisitor {
191190
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
192191
match expr.kind {
193192
hir::ExprKind::Binary(..)
194-
| hir::ExprKind::Unary(hir::UnOp::UnNot, _)
195-
| hir::ExprKind::Unary(hir::UnOp::UnNeg, _)
193+
| hir::ExprKind::Unary(hir::UnOp::UnNot | hir::UnOp::UnNeg, _)
196194
| hir::ExprKind::AssignOp(..) => self.in_binary_expr = true,
197195
_ => {},
198196
}

0 commit comments

Comments
 (0)