Skip to content

Commit 8da42dd

Browse files
committed
Auto merge of #75405 - flip1995:clippyup, r=Manishearth
Update Clippy Biweekly Clippy update (2 days late, since I wanted to wait for #75098) r? @Manishearth
2 parents 873fc46 + d6b991d commit 8da42dd

File tree

127 files changed

+2700
-619
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+2700
-619
lines changed

src/tools/clippy/CHANGELOG.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ document.
66

77
## Unreleased / In Rust Nightly
88

9-
[c2c07fa...master](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...master)
9+
[c2c07fa...master](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...master)
1010

1111
## Rust 1.46
1212

1313
Current beta, release 2020-08-27
1414

15-
[7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...master)
15+
[7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...c2c07fa)
1616

1717
### New lints
1818

@@ -1454,6 +1454,7 @@ Released 2018-09-13
14541454
[`deprecated_semver`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_semver
14551455
[`deref_addrof`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof
14561456
[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
1457+
[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
14571458
[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
14581459
[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
14591460
[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
@@ -1615,6 +1616,7 @@ Released 2018-09-13
16151616
[`mutex_atomic`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_atomic
16161617
[`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer
16171618
[`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/master/index.html#naive_bytecount
1619+
[`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type
16181620
[`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool
16191621
[`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
16201622
[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
@@ -1686,6 +1688,7 @@ Released 2018-09-13
16861688
[`result_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unit_fn
16871689
[`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges
16881690
[`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition
1691+
[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
16891692
[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
16901693
[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
16911694
[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
@@ -1701,6 +1704,7 @@ Released 2018-09-13
17011704
[`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else
17021705
[`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next
17031706
[`slow_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization
1707+
[`stable_sort_primitive`]: https://rust-lang.github.io/rust-clippy/master/index.html#stable_sort_primitive
17041708
[`str_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#str_to_string
17051709
[`string_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add
17061710
[`string_add_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add_assign
@@ -1723,6 +1727,7 @@ Released 2018-09-13
17231727
[`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments
17241728
[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
17251729
[`toplevel_ref_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#toplevel_ref_arg
1730+
[`trait_duplication_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#trait_duplication_in_bounds
17261731
[`transmute_bytes_to_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_bytes_to_str
17271732
[`transmute_float_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_float_to_int
17281733
[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_bool

src/tools/clippy/CONTRIBUTING.md

+15-12
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ All contributors are expected to follow the [Rust Code of Conduct].
2828

2929
## Getting started
3030

31-
High level approach:
31+
**Note: If this is your first time contributing to Clippy, you should
32+
first read the [Basics docs](doc/basics.md).**
33+
34+
### High level approach
3235

3336
1. Find something to fix/improve
3437
2. Change code (likely some file in `clippy_lints/src/`)
35-
3. Follow the instructions in the [docs for writing lints](doc/adding_lints.md) such as running the `setup-toolchain.sh` script
38+
3. Follow the instructions in the [Basics docs](doc/basics.md) to get set up
3639
4. Run `cargo test` in the root directory and wiggle code until it passes
3740
5. Open a PR (also can be done after 2. if you run into problems)
3841

@@ -95,16 +98,16 @@ quick read.
9598

9699
## Getting code-completion for rustc internals to work
97100

98-
Unfortunately, [`rust-analyzer`][ra_homepage] does not (yet?) understand how Clippy uses compiler-internals
99-
using `extern crate` and it also needs to be able to read the source files of the rustc-compiler which are not
100-
available via a `rustup` component at the time of writing.
101-
To work around this, you need to have a copy of the [rustc-repo][rustc_repo] available which can be obtained via
102-
`git clone https://github.com/rust-lang/rust/`.
103-
Then you can run a `cargo dev` command to automatically make Clippy use the rustc-repo via path-dependencies
104-
which rust-analyzer will be able to understand.
105-
Run `cargo dev ra-setup --repo-path <repo-path>` where `<repo-path>` is an absolute path to the rustc repo
106-
you just cloned.
107-
The command will add path-dependencies pointing towards rustc-crates inside the rustc repo to
101+
Unfortunately, [`rust-analyzer`][ra_homepage] does not (yet?) understand how Clippy uses compiler-internals
102+
using `extern crate` and it also needs to be able to read the source files of the rustc-compiler which are not
103+
available via a `rustup` component at the time of writing.
104+
To work around this, you need to have a copy of the [rustc-repo][rustc_repo] available which can be obtained via
105+
`git clone https://github.com/rust-lang/rust/`.
106+
Then you can run a `cargo dev` command to automatically make Clippy use the rustc-repo via path-dependencies
107+
which rust-analyzer will be able to understand.
108+
Run `cargo dev ra-setup --repo-path <repo-path>` where `<repo-path>` is an absolute path to the rustc repo
109+
you just cloned.
110+
The command will add path-dependencies pointing towards rustc-crates inside the rustc repo to
108111
Clippys `Cargo.toml`s and should allow rust-analyzer to understand most of the types that Clippy uses.
109112
Just make sure to remove the dependencies again before finally making a pull request!
110113

src/tools/clippy/clippy_dev/src/ra_setup.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ fn inject_deps_into_manifest(
6868
});
6969

7070
// format a new [dependencies]-block with the new deps we need to inject
71-
let mut all_deps = String::from("[dependencies]\n");
71+
let mut all_deps = String::from("[target.'cfg(NOT_A_PLATFORM)'.dependencies]\n");
7272
new_deps.for_each(|dep_line| {
7373
all_deps.push_str(&dep_line);
7474
});
75+
all_deps.push_str("\n[dependencies]\n");
7576

7677
// replace "[dependencies]" with
7778
// [dependencies]

src/tools/clippy/clippy_lints/src/attrs.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! checks for attributes
22
3-
use crate::reexport::Name;
43
use crate::utils::{
54
first_line_of_span, is_present_in_source, match_def_path, paths, snippet_opt, span_lint, span_lint_and_help,
65
span_lint_and_sugg, span_lint_and_then, without_block_comments,
@@ -517,7 +516,7 @@ fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>
517516
}
518517
}
519518

520-
fn check_attrs(cx: &LateContext<'_>, span: Span, name: Name, attrs: &[Attribute]) {
519+
fn check_attrs(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
521520
if span.from_expansion() {
522521
return;
523522
}
@@ -606,7 +605,7 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::as
606605
cx,
607606
EMPTY_LINE_AFTER_OUTER_ATTR,
608607
begin_of_attr_to_item,
609-
"Found an empty line after an outer attribute. \
608+
"found an empty line after an outer attribute. \
610609
Perhaps you forgot to add a `!` to make it an inner attribute?",
611610
);
612611
}

src/tools/clippy/clippy_lints/src/bytecount.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ impl<'tcx> LateLintPass<'tcx> for ByteCount {
8282
cx,
8383
NAIVE_BYTECOUNT,
8484
expr.span,
85-
"You appear to be counting bytes the naive way",
86-
"Consider using the bytecount crate",
85+
"you appear to be counting bytes the naive way",
86+
"consider using the bytecount crate",
8787
format!("bytecount::count({}, {})",
8888
snippet_with_applicability(cx, haystack.span, "..", &mut applicability),
8989
snippet_with_applicability(cx, needle.span, "..", &mut applicability)),

src/tools/clippy/clippy_lints/src/checked_conversions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
6666
cx,
6767
CHECKED_CONVERSIONS,
6868
item.span,
69-
"Checked cast can be simplified.",
69+
"checked cast can be simplified",
7070
"try",
7171
format!("{}::try_from({}).is_ok()", to_type, snippet),
7272
applicability,

src/tools/clippy/clippy_lints/src/default_trait_access.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultTraitAccess {
6161
cx,
6262
DEFAULT_TRAIT_ACCESS,
6363
expr.span,
64-
&format!("Calling `{}` is more clear than this expression", replacement),
64+
&format!("calling `{}` is more clear than this expression", replacement),
6565
"try",
6666
replacement,
6767
Applicability::Unspecified, // First resolve the TODO above

src/tools/clippy/clippy_lints/src/derive.rs

+117-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::utils::paths;
22
use crate::utils::{
3-
is_automatically_derived, is_copy, match_path, span_lint_and_help, span_lint_and_note, span_lint_and_then,
3+
get_trait_def_id, is_allowed, is_automatically_derived, is_copy, match_path, span_lint_and_help,
4+
span_lint_and_note, span_lint_and_then,
45
};
56
use if_chain::if_chain;
67
use rustc_hir::def_id::DefId;
@@ -43,6 +44,57 @@ declare_clippy_lint! {
4344
"deriving `Hash` but implementing `PartialEq` explicitly"
4445
}
4546

47+
declare_clippy_lint! {
48+
/// **What it does:** Checks for deriving `Ord` but implementing `PartialOrd`
49+
/// explicitly or vice versa.
50+
///
51+
/// **Why is this bad?** The implementation of these traits must agree (for
52+
/// example for use with `sort`) so it’s probably a bad idea to use a
53+
/// default-generated `Ord` implementation with an explicitly defined
54+
/// `PartialOrd`. In particular, the following must hold for any type
55+
/// implementing `Ord`:
56+
///
57+
/// ```text
58+
/// k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()
59+
/// ```
60+
///
61+
/// **Known problems:** None.
62+
///
63+
/// **Example:**
64+
///
65+
/// ```rust,ignore
66+
/// #[derive(Ord, PartialEq, Eq)]
67+
/// struct Foo;
68+
///
69+
/// impl PartialOrd for Foo {
70+
/// ...
71+
/// }
72+
/// ```
73+
/// Use instead:
74+
/// ```rust,ignore
75+
/// #[derive(PartialEq, Eq)]
76+
/// struct Foo;
77+
///
78+
/// impl PartialOrd for Foo {
79+
/// fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
80+
/// Some(self.cmp(other))
81+
/// }
82+
/// }
83+
///
84+
/// impl Ord for Foo {
85+
/// ...
86+
/// }
87+
/// ```
88+
/// or, if you don't need a custom ordering:
89+
/// ```rust,ignore
90+
/// #[derive(Ord, PartialOrd, PartialEq, Eq)]
91+
/// struct Foo;
92+
/// ```
93+
pub DERIVE_ORD_XOR_PARTIAL_ORD,
94+
correctness,
95+
"deriving `Ord` but implementing `PartialOrd` explicitly"
96+
}
97+
4698
declare_clippy_lint! {
4799
/// **What it does:** Checks for explicit `Clone` implementations for `Copy`
48100
/// types.
@@ -103,7 +155,12 @@ declare_clippy_lint! {
103155
"deriving `serde::Deserialize` on a type that has methods using `unsafe`"
104156
}
105157

106-
declare_lint_pass!(Derive => [EXPL_IMPL_CLONE_ON_COPY, DERIVE_HASH_XOR_EQ, UNSAFE_DERIVE_DESERIALIZE]);
158+
declare_lint_pass!(Derive => [
159+
EXPL_IMPL_CLONE_ON_COPY,
160+
DERIVE_HASH_XOR_EQ,
161+
DERIVE_ORD_XOR_PARTIAL_ORD,
162+
UNSAFE_DERIVE_DESERIALIZE
163+
]);
107164

108165
impl<'tcx> LateLintPass<'tcx> for Derive {
109166
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
@@ -116,6 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
116173
let is_automatically_derived = is_automatically_derived(&*item.attrs);
117174

118175
check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
176+
check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);
119177

120178
if is_automatically_derived {
121179
check_unsafe_derive_deserialize(cx, item, trait_ref, ty);
@@ -180,6 +238,60 @@ fn check_hash_peq<'tcx>(
180238
}
181239
}
182240

241+
/// Implementation of the `DERIVE_ORD_XOR_PARTIAL_ORD` lint.
242+
fn check_ord_partial_ord<'tcx>(
243+
cx: &LateContext<'tcx>,
244+
span: Span,
245+
trait_ref: &TraitRef<'_>,
246+
ty: Ty<'tcx>,
247+
ord_is_automatically_derived: bool,
248+
) {
249+
if_chain! {
250+
if let Some(ord_trait_def_id) = get_trait_def_id(cx, &paths::ORD);
251+
if let Some(partial_ord_trait_def_id) = cx.tcx.lang_items().partial_ord_trait();
252+
if let Some(def_id) = &trait_ref.trait_def_id();
253+
if *def_id == ord_trait_def_id;
254+
then {
255+
// Look for the PartialOrd implementations for `ty`
256+
cx.tcx.for_each_relevant_impl(partial_ord_trait_def_id, ty, |impl_id| {
257+
let partial_ord_is_automatically_derived = is_automatically_derived(&cx.tcx.get_attrs(impl_id));
258+
259+
if partial_ord_is_automatically_derived == ord_is_automatically_derived {
260+
return;
261+
}
262+
263+
let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation");
264+
265+
// Only care about `impl PartialOrd<Foo> for Foo`
266+
// For `impl PartialOrd<B> for A, input_types is [A, B]
267+
if trait_ref.substs.type_at(1) == ty {
268+
let mess = if partial_ord_is_automatically_derived {
269+
"you are implementing `Ord` explicitly but have derived `PartialOrd`"
270+
} else {
271+
"you are deriving `Ord` but have implemented `PartialOrd` explicitly"
272+
};
273+
274+
span_lint_and_then(
275+
cx,
276+
DERIVE_ORD_XOR_PARTIAL_ORD,
277+
span,
278+
mess,
279+
|diag| {
280+
if let Some(local_def_id) = impl_id.as_local() {
281+
let hir_id = cx.tcx.hir().as_local_hir_id(local_def_id);
282+
diag.span_note(
283+
cx.tcx.hir().span(hir_id),
284+
"`PartialOrd` implemented here"
285+
);
286+
}
287+
}
288+
);
289+
}
290+
});
291+
}
292+
}
293+
}
294+
183295
/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
184296
fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>) {
185297
if match_path(&trait_ref.path, &paths::CLONE_TRAIT) {
@@ -242,7 +354,9 @@ fn check_unsafe_derive_deserialize<'tcx>(
242354
if_chain! {
243355
if match_path(&trait_ref.path, &paths::SERDE_DESERIALIZE);
244356
if let ty::Adt(def, _) = ty.kind;
245-
if def.did.is_local();
357+
if let Some(local_def_id) = def.did.as_local();
358+
let adt_hir_id = cx.tcx.hir().as_local_hir_id(local_def_id);
359+
if !is_allowed(cx, UNSAFE_DERIVE_DESERIALIZE, adt_hir_id);
246360
if cx.tcx.inherent_impls(def.did)
247361
.iter()
248362
.map(|imp_did| item_from_def_id(cx, *imp_did))

src/tools/clippy/clippy_lints/src/double_comparison.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl<'tcx> DoubleComparisons {
6060
cx,
6161
DOUBLE_COMPARISONS,
6262
span,
63-
"This binary expression can be simplified",
63+
"this binary expression can be simplified",
6464
"try",
6565
sugg,
6666
applicability,

src/tools/clippy/clippy_lints/src/double_parens.rs

+5-18
Original file line numberDiff line numberDiff line change
@@ -45,41 +45,28 @@ impl EarlyLintPass for DoubleParens {
4545
return;
4646
}
4747

48+
let msg: &str = "consider removing unnecessary double parentheses";
49+
4850
match expr.kind {
4951
ExprKind::Paren(ref in_paren) => match in_paren.kind {
5052
ExprKind::Paren(_) | ExprKind::Tup(_) => {
51-
span_lint(
52-
cx,
53-
DOUBLE_PARENS,
54-
expr.span,
55-
"Consider removing unnecessary double parentheses",
56-
);
53+
span_lint(cx, DOUBLE_PARENS, expr.span, &msg);
5754
},
5855
_ => {},
5956
},
6057
ExprKind::Call(_, ref params) => {
6158
if params.len() == 1 {
6259
let param = &params[0];
6360
if let ExprKind::Paren(_) = param.kind {
64-
span_lint(
65-
cx,
66-
DOUBLE_PARENS,
67-
param.span,
68-
"Consider removing unnecessary double parentheses",
69-
);
61+
span_lint(cx, DOUBLE_PARENS, param.span, &msg);
7062
}
7163
}
7264
},
7365
ExprKind::MethodCall(_, ref params, _) => {
7466
if params.len() == 2 {
7567
let param = &params[1];
7668
if let ExprKind::Paren(_) = param.kind {
77-
span_lint(
78-
cx,
79-
DOUBLE_PARENS,
80-
param.span,
81-
"Consider removing unnecessary double parentheses",
82-
);
69+
span_lint(cx, DOUBLE_PARENS, param.span, &msg);
8370
}
8471
}
8572
},

src/tools/clippy/clippy_lints/src/drop_bounds.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ declare_clippy_lint! {
3333
/// ```
3434
pub DROP_BOUNDS,
3535
correctness,
36-
"Bounds of the form `T: Drop` are useless"
36+
"bounds of the form `T: Drop` are useless"
3737
}
3838

39-
const DROP_BOUNDS_SUMMARY: &str = "Bounds of the form `T: Drop` are useless. \
40-
Use `std::mem::needs_drop` to detect if a type has drop glue.";
39+
const DROP_BOUNDS_SUMMARY: &str = "bounds of the form `T: Drop` are useless, \
40+
use `std::mem::needs_drop` to detect if a type has drop glue";
4141

4242
declare_lint_pass!(DropBounds => [DROP_BOUNDS]);
4343

0 commit comments

Comments
 (0)