Skip to content

Commit 24b3554

Browse files
committed
Merge commit '2b030eb03d9e5837440b1ee0b98c50b97c0c5889' into clippyup
2 parents 6f97d83 + 2b030eb commit 24b3554

File tree

125 files changed

+2316
-845
lines changed

Some content is hidden

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

125 files changed

+2316
-845
lines changed

Diff for: src/tools/clippy/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -5463,6 +5463,7 @@ Released 2018-09-13
54635463
[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string
54645464
[`strlen_on_c_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#strlen_on_c_strings
54655465
[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools
5466+
[`struct_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names
54665467
[`stutter`]: https://rust-lang.github.io/rust-clippy/master/index.html#stutter
54675468
[`suboptimal_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#suboptimal_flops
54685469
[`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl
@@ -5625,6 +5626,7 @@ Released 2018-09-13
56255626
[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold
56265627
[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack
56275628
[`enum-variant-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-name-threshold
5629+
[`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold
56285630
[`enum-variant-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-size-threshold
56295631
[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold
56305632
[`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold

Diff for: src/tools/clippy/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ color-print = "0.3.4" # Sync version with Cargo
2929
anstream = "0.5.0"
3030

3131
[dev-dependencies]
32-
ui_test = "0.20"
32+
ui_test = "0.21.2"
3333
tester = "0.9"
3434
regex = "1.5"
3535
toml = "0.7.3"

Diff for: src/tools/clippy/book/src/development/adding_lints.md

+19
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ because that's clearly a non-descriptive name.
3030
- [Documentation](#documentation)
3131
- [Running rustfmt](#running-rustfmt)
3232
- [Debugging](#debugging)
33+
- [Conflicting lints](#conflicting-lints)
3334
- [PR Checklist](#pr-checklist)
3435
- [Adding configuration to a lint](#adding-configuration-to-a-lint)
3536
- [Cheat Sheet](#cheat-sheet)
@@ -612,6 +613,24 @@ output in the `stdout` part.
612613

613614
[`dbg!`]: https://doc.rust-lang.org/std/macro.dbg.html
614615

616+
## Conflicting lints
617+
618+
There are several lints that deal with the same pattern but suggest different approaches. In other words, some lints
619+
may suggest modifications that go in the opposite direction to what some other lints already propose for the same
620+
code, creating conflicting diagnostics.
621+
622+
When you are creating a lint that ends up in this scenario, the following tips should be encouraged to guide
623+
classification:
624+
625+
* The only case where they should be in the same category is if that category is `restriction`. For example,
626+
`semicolon_inside_block` and `semicolon_outside_block`.
627+
* For all the other cases, they should be in different categories with different levels of allowance. For example,
628+
`implicit_return` (restriction, allow) and `needless_return` (style, warn).
629+
630+
For lints that are in different categories, it is also recommended that at least one of them should be in the
631+
`restriction` category. The reason for this is that the `restriction` group is the only group where we don't
632+
recommend to enable the entire set, but cherry pick lints out of.
633+
615634
## PR Checklist
616635

617636
Before submitting your PR make sure you followed all the basic requirements:

Diff for: src/tools/clippy/book/src/lint_configuration.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Suppress lints whenever the suggested change would cause breakage for other crat
100100
## `msrv`
101101
The minimum rust version that the project supports
102102

103-
**Default Value:** `None` (`Option<String>`)
103+
**Default Value:** `Msrv { stack: [] }` (`crate::Msrv`)
104104

105105
---
106106
**Affected lints:**
@@ -273,6 +273,16 @@ The minimum number of enum variants for the lints about variant names to trigger
273273
* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
274274

275275

276+
## `struct-field-name-threshold`
277+
The minimum number of struct fields for the lints about field names to trigger
278+
279+
**Default Value:** `3` (`u64`)
280+
281+
---
282+
**Affected lints:**
283+
* [`struct_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_variant_names)
284+
285+
276286
## `enum-variant-size-threshold`
277287
The maximum size of an enum's variant to avoid box suggestion
278288

Diff for: src/tools/clippy/clippy_lints/src/async_yields_async.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
22
use clippy_utils::source::snippet;
33
use clippy_utils::ty::implements_trait;
44
use rustc_errors::Applicability;
5-
use rustc_hir::{AsyncCoroutineKind, Body, BodyId, ExprKind, CoroutineKind, QPath};
5+
use rustc_hir::{AsyncCoroutineKind, Body, BodyId, CoroutineKind, ExprKind, QPath};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_session::{declare_lint_pass, declare_tool_lint};
88

Diff for: src/tools/clippy/clippy_lints/src/await_holding_invalid.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -287,5 +287,8 @@ fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {
287287
}
288288

289289
fn is_refcell_ref(cx: &LateContext<'_>, def_id: DefId) -> bool {
290-
matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::RefCellRef | sym::RefCellRefMut))
290+
matches!(
291+
cx.tcx.get_diagnostic_name(def_id),
292+
Some(sym::RefCellRef | sym::RefCellRefMut)
293+
)
291294
}

Diff for: src/tools/clippy/clippy_lints/src/box_default.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use clippy_utils::macros::macro_backtrace;
33
use clippy_utils::ty::expr_sig;
44
use clippy_utils::{get_parent_node, is_default_equivalent, path_def_id};
55
use rustc_errors::Applicability;
6+
use rustc_hir::def::Res;
67
use rustc_hir::intravisit::{walk_ty, Visitor};
7-
use rustc_hir::{def::Res, Block, Expr, ExprKind, Local, Node, QPath, TyKind};
8+
use rustc_hir::{Block, Expr, ExprKind, Local, Node, QPath, TyKind};
89
use rustc_lint::{LateContext, LateLintPass, LintContext};
910
use rustc_middle::lint::in_external_macro;
1011
use rustc_middle::ty::print::with_forced_trimmed_paths;

Diff for: src/tools/clippy/clippy_lints/src/declared_lints.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
154154
crate::endian_bytes::LITTLE_ENDIAN_BYTES_INFO,
155155
crate::entry::MAP_ENTRY_INFO,
156156
crate::enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT_INFO,
157-
crate::enum_variants::ENUM_VARIANT_NAMES_INFO,
158-
crate::enum_variants::MODULE_INCEPTION_INFO,
159-
crate::enum_variants::MODULE_NAME_REPETITIONS_INFO,
160157
crate::equatable_if_let::EQUATABLE_IF_LET_INFO,
161158
crate::error_impl_error::ERROR_IMPL_ERROR_INFO,
162159
crate::escape::BOXED_LOCAL_INFO,
@@ -226,6 +223,10 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
226223
crate::instant_subtraction::UNCHECKED_DURATION_SUBTRACTION_INFO,
227224
crate::int_plus_one::INT_PLUS_ONE_INFO,
228225
crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO,
226+
crate::item_name_repetitions::ENUM_VARIANT_NAMES_INFO,
227+
crate::item_name_repetitions::MODULE_INCEPTION_INFO,
228+
crate::item_name_repetitions::MODULE_NAME_REPETITIONS_INFO,
229+
crate::item_name_repetitions::STRUCT_FIELD_NAMES_INFO,
229230
crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,
230231
crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO,
231232
crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,

Diff for: src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::source::snippet_with_context;
32
use clippy_utils::last_path_segment;
3+
use clippy_utils::source::snippet_with_context;
44
use rustc_errors::Applicability;
55
use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind};
66
use rustc_lint::{LateContext, LateLintPass};

Diff for: src/tools/clippy/clippy_lints/src/exit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::span_lint;
2-
use clippy_utils::{is_entrypoint_fn};
2+
use clippy_utils::is_entrypoint_fn;
33
use if_chain::if_chain;
44
use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
55
use rustc_lint::{LateContext, LateLintPass};

Diff for: src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
2-
use clippy_utils::ty::is_c_void;
32
use clippy_utils::path_def_id;
3+
use clippy_utils::ty::is_c_void;
44
use rustc_hir::def_id::DefId;
55
use rustc_hir::{Expr, ExprKind, QPath};
66
use rustc_lint::{LateContext, LateLintPass};

Diff for: src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs

+90-36
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,104 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::is_in_test_function;
33

4+
use rustc_hir as hir;
45
use rustc_hir::intravisit::FnKind;
5-
use rustc_hir::{Body, HirId};
6+
use rustc_hir::{Body, GenericParam, Generics, HirId, ImplItem, ImplItemKind, TraitItem, TraitItemKind};
67
use rustc_lint::LateContext;
7-
use rustc_span::Span;
8+
use rustc_span::symbol::Ident;
9+
use rustc_span::{BytePos, Span};
810

911
use super::IMPL_TRAIT_IN_PARAMS;
1012

13+
fn report(
14+
cx: &LateContext<'_>,
15+
param: &GenericParam<'_>,
16+
ident: &Ident,
17+
generics: &Generics<'_>,
18+
first_param_span: Span,
19+
) {
20+
// No generics with nested generics, and no generics like FnMut(x)
21+
span_lint_and_then(
22+
cx,
23+
IMPL_TRAIT_IN_PARAMS,
24+
param.span,
25+
"`impl Trait` used as a function parameter",
26+
|diag| {
27+
if let Some(gen_span) = generics.span_for_param_suggestion() {
28+
// If there's already a generic param with the same bound, do not lint **this** suggestion.
29+
diag.span_suggestion_with_style(
30+
gen_span,
31+
"add a type parameter",
32+
format!(", {{ /* Generic name */ }}: {}", &param.name.ident().as_str()[5..]),
33+
rustc_errors::Applicability::HasPlaceholders,
34+
rustc_errors::SuggestionStyle::ShowAlways,
35+
);
36+
} else {
37+
diag.span_suggestion_with_style(
38+
Span::new(
39+
first_param_span.lo() - rustc_span::BytePos(1),
40+
ident.span.hi(),
41+
ident.span.ctxt(),
42+
ident.span.parent(),
43+
),
44+
"add a type parameter",
45+
format!("<{{ /* Generic name */ }}: {}>", &param.name.ident().as_str()[5..]),
46+
rustc_errors::Applicability::HasPlaceholders,
47+
rustc_errors::SuggestionStyle::ShowAlways,
48+
);
49+
}
50+
},
51+
);
52+
}
53+
1154
pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: &'tcx Body<'_>, hir_id: HirId) {
12-
if cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() && !is_in_test_function(cx.tcx, hir_id)
13-
{
14-
if let FnKind::ItemFn(ident, generics, _) = kind {
55+
if_chain! {
56+
if let FnKind::ItemFn(ident, generics, _) = kind;
57+
if cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public();
58+
if !is_in_test_function(cx.tcx, hir_id);
59+
then {
1560
for param in generics.params {
1661
if param.is_impl_trait() {
17-
// No generics with nested generics, and no generics like FnMut(x)
18-
span_lint_and_then(
19-
cx,
20-
IMPL_TRAIT_IN_PARAMS,
21-
param.span,
22-
"'`impl Trait` used as a function parameter'",
23-
|diag| {
24-
if let Some(gen_span) = generics.span_for_param_suggestion() {
25-
diag.span_suggestion_with_style(
26-
gen_span,
27-
"add a type parameter",
28-
format!(", {{ /* Generic name */ }}: {}", &param.name.ident().as_str()[5..]),
29-
rustc_errors::Applicability::HasPlaceholders,
30-
rustc_errors::SuggestionStyle::ShowAlways,
31-
);
32-
} else {
33-
diag.span_suggestion_with_style(
34-
Span::new(
35-
body.params[0].span.lo() - rustc_span::BytePos(1),
36-
ident.span.hi(),
37-
ident.span.ctxt(),
38-
ident.span.parent(),
39-
),
40-
"add a type parameter",
41-
format!("<{{ /* Generic name */ }}: {}>", &param.name.ident().as_str()[5..]),
42-
rustc_errors::Applicability::HasPlaceholders,
43-
rustc_errors::SuggestionStyle::ShowAlways,
44-
);
45-
}
46-
},
47-
);
62+
report(cx, param, ident, generics, body.params[0].span);
63+
};
64+
}
65+
}
66+
}
67+
}
68+
69+
pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
70+
if_chain! {
71+
if let ImplItemKind::Fn(_, body_id) = impl_item.kind;
72+
if let hir::Node::Item(item) = cx.tcx.hir().get_parent(impl_item.hir_id());
73+
if let hir::ItemKind::Impl(impl_) = item.kind;
74+
if let hir::Impl { of_trait, .. } = *impl_;
75+
if of_trait.is_none();
76+
let body = cx.tcx.hir().body(body_id);
77+
if cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public();
78+
if !is_in_test_function(cx.tcx, impl_item.hir_id());
79+
then {
80+
for param in impl_item.generics.params {
81+
if param.is_impl_trait() {
82+
report(cx, param, &impl_item.ident, impl_item.generics, body.params[0].span);
83+
}
84+
}
85+
}
86+
}
87+
}
88+
89+
pub(super) fn check_trait_item(cx: &LateContext<'_>, trait_item: &TraitItem<'_>, avoid_breaking_exported_api: bool) {
90+
if_chain! {
91+
if !avoid_breaking_exported_api;
92+
if let TraitItemKind::Fn(_, _) = trait_item.kind;
93+
if let hir::Node::Item(item) = cx.tcx.hir().get_parent(trait_item.hir_id());
94+
// ^^ (Will always be a trait)
95+
if !item.vis_span.is_empty(); // Is public
96+
if !is_in_test_function(cx.tcx, trait_item.hir_id());
97+
then {
98+
for param in trait_item.generics.params {
99+
if param.is_impl_trait() {
100+
let sp = trait_item.ident.span.with_hi(trait_item.ident.span.hi() + BytePos(1));
101+
report(cx, param, &trait_item.ident, trait_item.generics, sp.shrink_to_hi());
48102
}
49103
}
50104
}

Diff for: src/tools/clippy/clippy_lints/src/functions/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -360,18 +360,26 @@ declare_clippy_lint! {
360360
}
361361

362362
#[derive(Copy, Clone)]
363+
#[allow(clippy::struct_field_names)]
363364
pub struct Functions {
364365
too_many_arguments_threshold: u64,
365366
too_many_lines_threshold: u64,
366367
large_error_threshold: u64,
368+
avoid_breaking_exported_api: bool,
367369
}
368370

369371
impl Functions {
370-
pub fn new(too_many_arguments_threshold: u64, too_many_lines_threshold: u64, large_error_threshold: u64) -> Self {
372+
pub fn new(
373+
too_many_arguments_threshold: u64,
374+
too_many_lines_threshold: u64,
375+
large_error_threshold: u64,
376+
avoid_breaking_exported_api: bool,
377+
) -> Self {
371378
Self {
372379
too_many_arguments_threshold,
373380
too_many_lines_threshold,
374381
large_error_threshold,
382+
avoid_breaking_exported_api,
375383
}
376384
}
377385
}
@@ -415,12 +423,14 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
415423
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
416424
must_use::check_impl_item(cx, item);
417425
result::check_impl_item(cx, item, self.large_error_threshold);
426+
impl_trait_in_params::check_impl_item(cx, item);
418427
}
419428

420429
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
421430
too_many_arguments::check_trait_item(cx, item, self.too_many_arguments_threshold);
422431
not_unsafe_ptr_arg_deref::check_trait_item(cx, item);
423432
must_use::check_trait_item(cx, item);
424433
result::check_trait_item(cx, item, self.large_error_threshold);
434+
impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api);
425435
}
426436
}

0 commit comments

Comments
 (0)