From 0c347d3d0686d8892512dcc1e13102d15afcc6dd Mon Sep 17 00:00:00 2001 From: Marc Dominik Migge Date: Sun, 17 Jan 2021 14:42:36 +0100 Subject: [PATCH 001/226] Fix false positive for unit_arg lint --- clippy_lints/src/types.rs | 11 +++++++++- tests/ui/unit_arg.rs | 20 ++++++++++++++++- tests/ui/unit_arg.stderr | 46 +++++++++++++++++++++++++++++++++++---- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 3b5a83d2a0bec..7d0eea37bc02a 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -955,7 +955,16 @@ impl<'tcx> LateLintPass<'tcx> for UnitArg { .iter() .filter(|arg| { if is_unit(cx.typeck_results().expr_ty(arg)) && !is_unit_literal(arg) { - !matches!(&arg.kind, ExprKind::Match(.., MatchSource::TryDesugar)) + match &arg.kind { + ExprKind::Block(..) + | ExprKind::Call(..) + | ExprKind::If(..) + | ExprKind::MethodCall(..) => true, + ExprKind::Match(..) => { + !matches!(&arg.kind, ExprKind::Match(.., MatchSource::TryDesugar)) + }, + _ => false, + } } else { false } diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index b6a7bc5a1cc95..79dac925f08ca 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -59,7 +59,18 @@ fn bad() { None.or(Some(foo(2))); // in this case, the suggestion can be inlined, no need for a surrounding block // foo(()); foo(()) instead of { foo(()); foo(()) } - foo(foo(())) + foo(foo(())); + foo(if true { + 1; + }); + foo(match Some(1) { + Some(_) => { + 1; + }, + None => { + 0; + }, + }); } fn ok() { @@ -71,6 +82,13 @@ fn ok() { b.bar({ 1 }); b.bar(()); question_mark(); + let named_unit_arg = (); + foo(named_unit_arg); + foo(if true { 1 } else { 0 }); + foo(match Some(1) { + Some(_) => 1, + None => 0, + }); } fn question_mark() -> Result<(), ()> { diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr index 094cff8c98591..8679706f8ec8e 100644 --- a/tests/ui/unit_arg.stderr +++ b/tests/ui/unit_arg.stderr @@ -156,17 +156,55 @@ LL | }); error: passing a unit value to a function --> $DIR/unit_arg.rs:62:5 | -LL | foo(foo(())) +LL | foo(foo(())); | ^^^^^^^^^^^^ | help: move the expression in front of the call and replace it with the unit literal `()` | LL | foo(()); -LL | foo(()) +LL | foo(()); + | + +error: passing a unit value to a function + --> $DIR/unit_arg.rs:63:5 + | +LL | / foo(if true { +LL | | 1; +LL | | }); + | |______^ + | +help: move the expression in front of the call and replace it with the unit literal `()` + | +LL | if true { +LL | 1; +LL | }; +LL | foo(()); + | + +error: passing a unit value to a function + --> $DIR/unit_arg.rs:66:5 | +LL | / foo(match Some(1) { +LL | | Some(_) => { +LL | | 1; +LL | | }, +... | +LL | | }, +LL | | }); + | |______^ + | +help: move the expression in front of the call and replace it with the unit literal `()` + | +LL | match Some(1) { +LL | Some(_) => { +LL | 1; +LL | }, +LL | None => { +LL | 0; + ... error: passing a unit value to a function - --> $DIR/unit_arg.rs:95:5 + --> $DIR/unit_arg.rs:113:5 | LL | Some(foo(1)) | ^^^^^^^^^^^^ @@ -177,5 +215,5 @@ LL | foo(1); LL | Some(()) | -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors From eb476c6c70bccb87378462e4854f8b8fa12c40be Mon Sep 17 00:00:00 2001 From: Marc Dominik Migge Date: Mon, 18 Jan 2021 20:18:56 +0100 Subject: [PATCH 002/226] Split up tests for unit arg expressions --- tests/ui/unit_arg.rs | 16 ----------- tests/ui/unit_arg.stderr | 42 ++-------------------------- tests/ui/unit_arg_expressions.rs | 35 +++++++++++++++++++++++ tests/ui/unit_arg_expressions.stderr | 41 +++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 56 deletions(-) create mode 100644 tests/ui/unit_arg_expressions.rs create mode 100644 tests/ui/unit_arg_expressions.stderr diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index 79dac925f08ca..cce543006d77f 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -60,17 +60,6 @@ fn bad() { // in this case, the suggestion can be inlined, no need for a surrounding block // foo(()); foo(()) instead of { foo(()); foo(()) } foo(foo(())); - foo(if true { - 1; - }); - foo(match Some(1) { - Some(_) => { - 1; - }, - None => { - 0; - }, - }); } fn ok() { @@ -84,11 +73,6 @@ fn ok() { question_mark(); let named_unit_arg = (); foo(named_unit_arg); - foo(if true { 1 } else { 0 }); - foo(match Some(1) { - Some(_) => 1, - None => 0, - }); } fn question_mark() -> Result<(), ()> { diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr index 8679706f8ec8e..8e3f1811c6599 100644 --- a/tests/ui/unit_arg.stderr +++ b/tests/ui/unit_arg.stderr @@ -166,45 +166,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:63:5 - | -LL | / foo(if true { -LL | | 1; -LL | | }); - | |______^ - | -help: move the expression in front of the call and replace it with the unit literal `()` - | -LL | if true { -LL | 1; -LL | }; -LL | foo(()); - | - -error: passing a unit value to a function - --> $DIR/unit_arg.rs:66:5 - | -LL | / foo(match Some(1) { -LL | | Some(_) => { -LL | | 1; -LL | | }, -... | -LL | | }, -LL | | }); - | |______^ - | -help: move the expression in front of the call and replace it with the unit literal `()` - | -LL | match Some(1) { -LL | Some(_) => { -LL | 1; -LL | }, -LL | None => { -LL | 0; - ... - -error: passing a unit value to a function - --> $DIR/unit_arg.rs:113:5 + --> $DIR/unit_arg.rs:97:5 | LL | Some(foo(1)) | ^^^^^^^^^^^^ @@ -215,5 +177,5 @@ LL | foo(1); LL | Some(()) | -error: aborting due to 12 previous errors +error: aborting due to 10 previous errors diff --git a/tests/ui/unit_arg_expressions.rs b/tests/ui/unit_arg_expressions.rs new file mode 100644 index 0000000000000..a6807cb2e973c --- /dev/null +++ b/tests/ui/unit_arg_expressions.rs @@ -0,0 +1,35 @@ +#![warn(clippy::unit_arg)] +#![allow(clippy::no_effect)] + +use std::fmt::Debug; + +fn foo(t: T) { + println!("{:?}", t); +} + +fn bad() { + foo(if true { + 1; + }); + foo(match Some(1) { + Some(_) => { + 1; + }, + None => { + 0; + }, + }); +} + +fn ok() { + foo(if true { 1 } else { 0 }); + foo(match Some(1) { + Some(_) => 1, + None => 0, + }); +} + +fn main() { + bad(); + ok(); +} diff --git a/tests/ui/unit_arg_expressions.stderr b/tests/ui/unit_arg_expressions.stderr new file mode 100644 index 0000000000000..9fb08106b7233 --- /dev/null +++ b/tests/ui/unit_arg_expressions.stderr @@ -0,0 +1,41 @@ +error: passing a unit value to a function + --> $DIR/unit_arg_expressions.rs:11:5 + | +LL | / foo(if true { +LL | | 1; +LL | | }); + | |______^ + | + = note: `-D clippy::unit-arg` implied by `-D warnings` +help: move the expression in front of the call and replace it with the unit literal `()` + | +LL | if true { +LL | 1; +LL | }; +LL | foo(()); + | + +error: passing a unit value to a function + --> $DIR/unit_arg_expressions.rs:14:5 + | +LL | / foo(match Some(1) { +LL | | Some(_) => { +LL | | 1; +LL | | }, +... | +LL | | }, +LL | | }); + | |______^ + | +help: move the expression in front of the call and replace it with the unit literal `()` + | +LL | match Some(1) { +LL | Some(_) => { +LL | 1; +LL | }, +LL | None => { +LL | 0; + ... + +error: aborting due to 2 previous errors + From 9fe9d94abda8d2698d1dede6961007e0026760ea Mon Sep 17 00:00:00 2001 From: Marc Dominik Migge Date: Wed, 24 Feb 2021 13:31:04 +0100 Subject: [PATCH 003/226] Don't lint unit args if expression kind is path --- clippy_lints/src/types.rs | 14 +++------- tests/ui/unit_arg.rs | 5 ++++ tests/ui/unit_arg.stderr | 20 +++++++------- tests/ui/unit_arg_expressions.rs | 35 ------------------------ tests/ui/unit_arg_expressions.stderr | 41 ---------------------------- 5 files changed, 19 insertions(+), 96 deletions(-) delete mode 100644 tests/ui/unit_arg_expressions.rs delete mode 100644 tests/ui/unit_arg_expressions.stderr diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 7d0eea37bc02a..77cde8b60c161 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -955,16 +955,10 @@ impl<'tcx> LateLintPass<'tcx> for UnitArg { .iter() .filter(|arg| { if is_unit(cx.typeck_results().expr_ty(arg)) && !is_unit_literal(arg) { - match &arg.kind { - ExprKind::Block(..) - | ExprKind::Call(..) - | ExprKind::If(..) - | ExprKind::MethodCall(..) => true, - ExprKind::Match(..) => { - !matches!(&arg.kind, ExprKind::Match(.., MatchSource::TryDesugar)) - }, - _ => false, - } + !matches!( + &arg.kind, + ExprKind::Match(.., MatchSource::TryDesugar) | ExprKind::Path(..) + ) } else { false } diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index cce543006d77f..5ea2e5d65c515 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -27,6 +27,10 @@ impl Bar { } } +fn baz(t: T) { + foo(t); +} + fn bad() { foo({ 1; @@ -73,6 +77,7 @@ fn ok() { question_mark(); let named_unit_arg = (); foo(named_unit_arg); + baz(()); } fn question_mark() -> Result<(), ()> { diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr index 8e3f1811c6599..b3fe9addb62f6 100644 --- a/tests/ui/unit_arg.stderr +++ b/tests/ui/unit_arg.stderr @@ -1,5 +1,5 @@ error: passing a unit value to a function - --> $DIR/unit_arg.rs:31:5 + --> $DIR/unit_arg.rs:35:5 | LL | / foo({ LL | | 1; @@ -20,7 +20,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:34:5 + --> $DIR/unit_arg.rs:38:5 | LL | foo(foo(1)); | ^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:35:5 + --> $DIR/unit_arg.rs:39:5 | LL | / foo({ LL | | foo(1); @@ -54,7 +54,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:40:5 + --> $DIR/unit_arg.rs:44:5 | LL | / b.bar({ LL | | 1; @@ -74,7 +74,7 @@ LL | b.bar(()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:43:5 + --> $DIR/unit_arg.rs:47:5 | LL | taking_multiple_units(foo(0), foo(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -87,7 +87,7 @@ LL | taking_multiple_units((), ()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:44:5 + --> $DIR/unit_arg.rs:48:5 | LL | / taking_multiple_units(foo(0), { LL | | foo(1); @@ -110,7 +110,7 @@ LL | taking_multiple_units((), ()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:48:5 + --> $DIR/unit_arg.rs:52:5 | LL | / taking_multiple_units( LL | | { @@ -140,7 +140,7 @@ LL | foo(2); ... error: passing a unit value to a function - --> $DIR/unit_arg.rs:59:13 + --> $DIR/unit_arg.rs:63:13 | LL | None.or(Some(foo(2))); | ^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | }); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:62:5 + --> $DIR/unit_arg.rs:66:5 | LL | foo(foo(())); | ^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:97:5 + --> $DIR/unit_arg.rs:102:5 | LL | Some(foo(1)) | ^^^^^^^^^^^^ diff --git a/tests/ui/unit_arg_expressions.rs b/tests/ui/unit_arg_expressions.rs deleted file mode 100644 index a6807cb2e973c..0000000000000 --- a/tests/ui/unit_arg_expressions.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![warn(clippy::unit_arg)] -#![allow(clippy::no_effect)] - -use std::fmt::Debug; - -fn foo(t: T) { - println!("{:?}", t); -} - -fn bad() { - foo(if true { - 1; - }); - foo(match Some(1) { - Some(_) => { - 1; - }, - None => { - 0; - }, - }); -} - -fn ok() { - foo(if true { 1 } else { 0 }); - foo(match Some(1) { - Some(_) => 1, - None => 0, - }); -} - -fn main() { - bad(); - ok(); -} diff --git a/tests/ui/unit_arg_expressions.stderr b/tests/ui/unit_arg_expressions.stderr deleted file mode 100644 index 9fb08106b7233..0000000000000 --- a/tests/ui/unit_arg_expressions.stderr +++ /dev/null @@ -1,41 +0,0 @@ -error: passing a unit value to a function - --> $DIR/unit_arg_expressions.rs:11:5 - | -LL | / foo(if true { -LL | | 1; -LL | | }); - | |______^ - | - = note: `-D clippy::unit-arg` implied by `-D warnings` -help: move the expression in front of the call and replace it with the unit literal `()` - | -LL | if true { -LL | 1; -LL | }; -LL | foo(()); - | - -error: passing a unit value to a function - --> $DIR/unit_arg_expressions.rs:14:5 - | -LL | / foo(match Some(1) { -LL | | Some(_) => { -LL | | 1; -LL | | }, -... | -LL | | }, -LL | | }); - | |______^ - | -help: move the expression in front of the call and replace it with the unit literal `()` - | -LL | match Some(1) { -LL | Some(_) => { -LL | 1; -LL | }, -LL | None => { -LL | 0; - ... - -error: aborting due to 2 previous errors - From f64149dd04514e850374d2b94ecc91ce18d1b39e Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 25 Feb 2021 11:25:22 +0100 Subject: [PATCH 004/226] Merge commit '928e72dd10749875cbd412f74bfbfd7765dbcd8a' into clippyup --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/false_negative.md | 2 +- .github/ISSUE_TEMPLATE/false_positive.md | 2 +- .github/ISSUE_TEMPLATE/ice.md | 2 +- .github/ISSUE_TEMPLATE/new_lint.md | 2 +- .github/workflows/clippy.yml | 12 +- .github/workflows/clippy_bors.yml | 12 +- .gitignore | 1 + CHANGELOG.md | 129 +- Cargo.toml | 7 +- README.md | 17 + clippy_dev/Cargo.toml | 3 +- clippy_dev/README.md | 73 +- clippy_dev/src/bless.rs | 3 +- clippy_dev/src/lintcheck.rs | 336 ++- clippy_dev/src/main.rs | 8 + clippy_lints/Cargo.toml | 3 +- clippy_lints/src/blocks_in_if_conditions.rs | 18 +- clippy_lints/src/collapsible_if.rs | 13 +- clippy_lints/src/collapsible_match.rs | 6 +- clippy_lints/src/consts.rs | 575 +---- clippy_lints/src/default_numeric_fallback.rs | 237 +++ clippy_lints/src/doc.rs | 33 +- clippy_lints/src/from_str_radix_10.rs | 101 + clippy_lints/src/functions.rs | 15 +- .../src/inconsistent_struct_constructor.rs | 134 ++ clippy_lints/src/inherent_to_string.rs | 1 + clippy_lints/src/lib.rs | 42 +- clippy_lints/src/manual_map.rs | 274 +++ clippy_lints/src/matches.rs | 113 +- clippy_lints/src/unnecessary_sort_by.rs | 4 +- clippy_lints/src/unnecessary_wraps.rs | 100 +- clippy_lints/src/upper_case_acronyms.rs | 38 +- clippy_lints/src/use_self.rs | 562 +++-- clippy_lints/src/utils/conf.rs | 4 +- clippy_lints/src/utils/internal_lints.rs | 23 +- clippy_lints/src/utils/mod.rs | 1832 +--------------- clippy_lints/src/vec_init_then_push.rs | 28 +- clippy_lints/src/write.rs | 3 - clippy_utils/Cargo.toml | 19 + .../utils => clippy_utils/src}/ast_utils.rs | 42 +- .../src}/ast_utils/ident_iter.rs | 0 .../src/utils => clippy_utils/src}/attrs.rs | 0 .../utils => clippy_utils/src}/camel_case.rs | 6 + .../utils => clippy_utils/src}/comparisons.rs | 0 clippy_utils/src/consts.rs | 574 +++++ .../utils => clippy_utils/src}/diagnostics.rs | 0 .../src}/eager_or_lazy.rs | 2 +- .../src/utils => clippy_utils/src}/higher.rs | 2 +- .../utils => clippy_utils/src}/hir_utils.rs | 140 +- clippy_utils/src/lib.rs | 1883 +++++++++++++++++ .../src}/numeric_literal.rs | 0 .../src/utils => clippy_utils/src}/paths.rs | 0 .../src/utils => clippy_utils/src}/ptr.rs | 2 +- .../src}/qualify_min_const_fn.rs | 0 .../src/utils => clippy_utils/src}/sugg.rs | 2 +- .../utils => clippy_utils/src}/sym_helper.rs | 0 .../src/utils => clippy_utils/src}/usage.rs | 2 +- .../utils => clippy_utils/src}/visitors.rs | 2 +- doc/adding_lints.md | 11 +- doc/common_tools_writing_lints.md | 9 +- lintcheck-logs/lintcheck_crates_logs.txt | 114 +- rust-toolchain | 2 +- tests/compile-test.rs | 16 +- .../toml_unknown_key/conf_unknown_key.stderr | 2 +- .../clippy.toml | 1 + .../upper_case_acronyms.rs | 22 + .../upper_case_acronyms.stderr | 70 + tests/ui/auxiliary/proc_macro_derive.rs | 12 + tests/ui/blocks_in_if_conditions_closure.rs | 11 +- tests/ui/collapsible_else_if.fixed | 9 + tests/ui/collapsible_else_if.rs | 9 + tests/ui/collapsible_if.fixed | 7 + tests/ui/collapsible_if.rs | 7 + tests/ui/collapsible_match.rs | 8 + tests/ui/collapsible_match.stderr | 60 +- tests/ui/collapsible_match2.stderr | 30 +- tests/ui/crashes/ice-6179.rs | 21 + tests/ui/default_numeric_fallback.rs | 135 ++ tests/ui/default_numeric_fallback.stderr | 148 ++ tests/ui/doc.rs | 12 + tests/ui/doc.stderr | 44 +- tests/ui/doc_panics.rs | 27 + tests/ui/doc_panics.stderr | 21 +- tests/ui/enum_variants.rs | 13 + tests/ui/enum_variants.stderr | 26 +- tests/ui/from_str_radix_10.rs | 52 + tests/ui/from_str_radix_10.stderr | 52 + tests/ui/if_same_then_else2.rs | 6 +- tests/ui/if_same_then_else2.stderr | 4 +- .../ui/inconsistent_struct_constructor.fixed | 61 + tests/ui/inconsistent_struct_constructor.rs | 65 + .../ui/inconsistent_struct_constructor.stderr | 20 + tests/ui/inherent_to_string.rs | 11 + tests/ui/inherent_to_string.stderr | 4 +- tests/ui/manual_map_option.fixed | 70 + tests/ui/manual_map_option.rs | 122 ++ tests/ui/manual_map_option.stderr | 158 ++ tests/ui/result_unit_error.rs | 23 +- tests/ui/result_unit_error.stderr | 18 +- tests/ui/unnecessary_wraps.rs | 45 + tests/ui/unnecessary_wraps.stderr | 64 +- tests/ui/upper_case_acronyms.rs | 7 +- tests/ui/upper_case_acronyms.stderr | 24 +- tests/ui/use_self.fixed | 224 +- tests/ui/use_self.rs | 222 +- tests/ui/use_self.stderr | 118 +- tests/ui/use_self_trait.fixed | 3 +- tests/ui/use_self_trait.rs | 1 + tests/ui/use_self_trait.stderr | 8 +- tests/ui/vec_init_then_push.rs | 25 + tests/ui/vec_init_then_push.stderr | 2 +- tests/versioncheck.rs | 25 +- 113 files changed, 6454 insertions(+), 3273 deletions(-) create mode 100644 clippy_lints/src/default_numeric_fallback.rs create mode 100644 clippy_lints/src/from_str_radix_10.rs create mode 100644 clippy_lints/src/inconsistent_struct_constructor.rs create mode 100644 clippy_lints/src/manual_map.rs create mode 100644 clippy_utils/Cargo.toml rename {clippy_lints/src/utils => clippy_utils/src}/ast_utils.rs (95%) rename {clippy_lints/src/utils => clippy_utils/src}/ast_utils/ident_iter.rs (100%) rename {clippy_lints/src/utils => clippy_utils/src}/attrs.rs (100%) rename {clippy_lints/src/utils => clippy_utils/src}/camel_case.rs (91%) rename {clippy_lints/src/utils => clippy_utils/src}/comparisons.rs (100%) create mode 100644 clippy_utils/src/consts.rs rename {clippy_lints/src/utils => clippy_utils/src}/diagnostics.rs (100%) rename {clippy_lints/src/utils => clippy_utils/src}/eager_or_lazy.rs (97%) rename {clippy_lints/src/utils => clippy_utils/src}/higher.rs (99%) rename {clippy_lints/src/utils => clippy_utils/src}/hir_utils.rs (86%) create mode 100644 clippy_utils/src/lib.rs rename {clippy_lints/src/utils => clippy_utils/src}/numeric_literal.rs (100%) rename {clippy_lints/src/utils => clippy_utils/src}/paths.rs (100%) rename {clippy_lints/src/utils => clippy_utils/src}/ptr.rs (97%) rename {clippy_lints/src/utils => clippy_utils/src}/qualify_min_const_fn.rs (100%) rename {clippy_lints/src/utils => clippy_utils/src}/sugg.rs (99%) rename {clippy_lints/src/utils => clippy_utils/src}/sym_helper.rs (100%) rename {clippy_lints/src/utils => clippy_utils/src}/usage.rs (99%) rename {clippy_lints/src/utils => clippy_utils/src}/visitors.rs (99%) create mode 100644 tests/ui-toml/upper_case_acronyms_aggressive/clippy.toml create mode 100644 tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs create mode 100644 tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr create mode 100644 tests/ui/crashes/ice-6179.rs create mode 100644 tests/ui/default_numeric_fallback.rs create mode 100644 tests/ui/default_numeric_fallback.stderr create mode 100644 tests/ui/from_str_radix_10.rs create mode 100644 tests/ui/from_str_radix_10.stderr create mode 100644 tests/ui/inconsistent_struct_constructor.fixed create mode 100644 tests/ui/inconsistent_struct_constructor.rs create mode 100644 tests/ui/inconsistent_struct_constructor.stderr create mode 100644 tests/ui/manual_map_option.fixed create mode 100644 tests/ui/manual_map_option.rs create mode 100644 tests/ui/manual_map_option.stderr diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d8f0c44148cae..2bc87db123d4d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,7 @@ --- name: Bug Report about: Create a bug report for Clippy -labels: L-bug +labels: C-bug --- $DIR/upper_case_acronyms.rs:3:8 + | +LL | struct HTTPResponse; // not linted by default, but with cfg option + | ^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `HttpResponse` + | + = note: `-D clippy::upper-case-acronyms` implied by `-D warnings` + +error: name `NS` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:8:5 + | +LL | NS, // not linted + | ^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ns` + +error: name `CWR` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:9:5 + | +LL | CWR, + | ^^^ help: consider making the acronym lowercase, except the initial letter: `Cwr` + +error: name `ECE` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:10:5 + | +LL | ECE, + | ^^^ help: consider making the acronym lowercase, except the initial letter: `Ece` + +error: name `URG` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:11:5 + | +LL | URG, + | ^^^ help: consider making the acronym lowercase, except the initial letter: `Urg` + +error: name `ACK` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:12:5 + | +LL | ACK, + | ^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ack` + +error: name `PSH` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:13:5 + | +LL | PSH, + | ^^^ help: consider making the acronym lowercase, except the initial letter: `Psh` + +error: name `RST` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:14:5 + | +LL | RST, + | ^^^ help: consider making the acronym lowercase, except the initial letter: `Rst` + +error: name `SYN` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:15:5 + | +LL | SYN, + | ^^^ help: consider making the acronym lowercase, except the initial letter: `Syn` + +error: name `FIN` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:16:5 + | +LL | FIN, + | ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin` + +error: name `GCCLLVMSomething` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:19:8 + | +LL | struct GCCLLVMSomething; // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of + | ^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GccllvmSomething` + +error: aborting due to 11 previous errors + diff --git a/tests/ui/auxiliary/proc_macro_derive.rs b/tests/ui/auxiliary/proc_macro_derive.rs index 24891682d368d..aebeaf346799d 100644 --- a/tests/ui/auxiliary/proc_macro_derive.rs +++ b/tests/ui/auxiliary/proc_macro_derive.rs @@ -41,3 +41,15 @@ pub fn derive_foo(_input: TokenStream) -> TokenStream { } } } + +#[proc_macro_derive(StructAUseSelf)] +pub fn derive_use_self(_input: TokenStream) -> proc_macro::TokenStream { + quote! { + struct A; + impl A { + fn new() -> A { + A + } + } + } +} diff --git a/tests/ui/blocks_in_if_conditions_closure.rs b/tests/ui/blocks_in_if_conditions_closure.rs index acbabfa20d737..2856943b9be80 100644 --- a/tests/ui/blocks_in_if_conditions_closure.rs +++ b/tests/ui/blocks_in_if_conditions_closure.rs @@ -44,4 +44,13 @@ fn macro_in_closure() { } } -fn main() {} +#[rustfmt::skip] +fn main() { + let mut range = 0..10; + range.all(|i| {i < 10} ); + + let v = vec![1, 2, 3]; + if v.into_iter().any(|x| {x == 4}) { + println!("contains 4!"); + } +} diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed index fa4bc30e933a2..c69a46f0a77ee 100644 --- a/tests/ui/collapsible_else_if.fixed +++ b/tests/ui/collapsible_else_if.fixed @@ -65,4 +65,13 @@ fn main() { else { println!("!") } + + if x == "hello" { + print!("Hello "); + } else { + #[cfg(not(roflol))] + if y == "world" { + println!("world!") + } + } } diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs index bf6c1d1f894d7..1359c7eb6278e 100644 --- a/tests/ui/collapsible_else_if.rs +++ b/tests/ui/collapsible_else_if.rs @@ -79,4 +79,13 @@ fn main() { println!("!") } } + + if x == "hello" { + print!("Hello "); + } else { + #[cfg(not(roflol))] + if y == "world" { + println!("world!") + } + } } diff --git a/tests/ui/collapsible_if.fixed b/tests/ui/collapsible_if.fixed index efd4187947b20..e4c088bf6f03f 100644 --- a/tests/ui/collapsible_if.fixed +++ b/tests/ui/collapsible_if.fixed @@ -138,4 +138,11 @@ fn main() { // Fix #5962 if matches!(true, true) && matches!(true, true) {} + + if true { + #[cfg(not(teehee))] + if true { + println!("Hello world!"); + } + } } diff --git a/tests/ui/collapsible_if.rs b/tests/ui/collapsible_if.rs index 657f32d38a32b..d6cf01c831940 100644 --- a/tests/ui/collapsible_if.rs +++ b/tests/ui/collapsible_if.rs @@ -154,4 +154,11 @@ fn main() { if matches!(true, true) { if matches!(true, true) {} } + + if true { + #[cfg(not(teehee))] + if true { + println!("Hello world!"); + } + } } diff --git a/tests/ui/collapsible_match.rs b/tests/ui/collapsible_match.rs index 3294da7e8146f..55467cf4229de 100644 --- a/tests/ui/collapsible_match.rs +++ b/tests/ui/collapsible_match.rs @@ -232,6 +232,14 @@ fn negative_cases(res_opt: Result, String>, res_res: Result match e { + Some(e) => e, + e => e, + }, + // else branch looks the same but the binding is different + e => e, + }; } fn make() -> T { diff --git a/tests/ui/collapsible_match.stderr b/tests/ui/collapsible_match.stderr index 63ac6a1613dc6..7797888490089 100644 --- a/tests/ui/collapsible_match.stderr +++ b/tests/ui/collapsible_match.stderr @@ -1,4 +1,4 @@ -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:7:20 | LL | Ok(val) => match val { @@ -9,15 +9,15 @@ LL | | }, | |_________^ | = note: `-D clippy::collapsible-match` implied by `-D warnings` -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:7:12 | LL | Ok(val) => match val { - | ^^^ Replace this binding + | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:16:20 | LL | Ok(val) => match val { @@ -27,15 +27,15 @@ LL | | _ => return, LL | | }, | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:16:12 | LL | Ok(val) => match val { - | ^^^ Replace this binding + | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:25:9 | LL | / if let Some(n) = val { @@ -43,15 +43,15 @@ LL | | take(n); LL | | } | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:24:15 | LL | if let Ok(val) = res_opt { - | ^^^ Replace this binding + | ^^^ replace this binding LL | if let Some(n) = val { | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:32:9 | LL | / if let Some(n) = val { @@ -61,15 +61,15 @@ LL | | return; LL | | } | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:31:15 | LL | if let Ok(val) = res_opt { - | ^^^ Replace this binding + | ^^^ replace this binding LL | if let Some(n) = val { | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:43:9 | LL | / match val { @@ -78,16 +78,16 @@ LL | | _ => (), LL | | } | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:42:15 | LL | if let Ok(val) = res_opt { - | ^^^ Replace this binding + | ^^^ replace this binding LL | match val { LL | Some(n) => foo(n), | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:52:13 | LL | / if let Some(n) = val { @@ -95,15 +95,15 @@ LL | | take(n); LL | | } | |_____________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:51:12 | LL | Ok(val) => { - | ^^^ Replace this binding + | ^^^ replace this binding LL | if let Some(n) = val { | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:61:9 | LL | / match val { @@ -112,16 +112,16 @@ LL | | _ => return, LL | | } | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:60:15 | LL | if let Ok(val) = res_opt { - | ^^^ Replace this binding + | ^^^ replace this binding LL | match val { LL | Some(n) => foo(n), | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:72:13 | LL | / if let Some(n) = val { @@ -131,15 +131,15 @@ LL | | return; LL | | } | |_____________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:71:12 | LL | Ok(val) => { - | ^^^ Replace this binding + | ^^^ replace this binding LL | if let Some(n) = val { | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:83:20 | LL | Ok(val) => match val { @@ -149,15 +149,15 @@ LL | | None => return, LL | | }, | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:83:12 | LL | Ok(val) => match val { - | ^^^ Replace this binding + | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match.rs:92:22 | LL | Some(val) => match val { @@ -167,11 +167,11 @@ LL | | _ => return, LL | | }, | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:92:14 | LL | Some(val) => match val { - | ^^^ Replace this binding + | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern diff --git a/tests/ui/collapsible_match2.stderr b/tests/ui/collapsible_match2.stderr index b2eb457d17326..c8a445ef369d9 100644 --- a/tests/ui/collapsible_match2.stderr +++ b/tests/ui/collapsible_match2.stderr @@ -1,4 +1,4 @@ -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match2.rs:8:34 | LL | Ok(val) if make() => match val { @@ -9,15 +9,15 @@ LL | | }, | |_____________^ | = note: `-D clippy::collapsible-match` implied by `-D warnings` -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match2.rs:8:16 | LL | Ok(val) if make() => match val { - | ^^^ Replace this binding + | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match2.rs:15:24 | LL | Ok(val) => match val { @@ -27,15 +27,15 @@ LL | | _ => return, LL | | }, | |_____________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match2.rs:15:16 | LL | Ok(val) => match val { - | ^^^ Replace this binding + | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match2.rs:29:29 | LL | $pat => match $e { @@ -48,16 +48,16 @@ LL | | }, LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); | ------------------------------------------------- in this macro invocation | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match2.rs:41:28 | LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); | ^^^ ^^^^^^^ with this pattern | | - | Replace this binding + | replace this binding = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match2.rs:46:20 | LL | Some(s) => match *s { @@ -67,15 +67,15 @@ LL | | _ => (), LL | | }, | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match2.rs:46:14 | LL | Some(s) => match *s { - | ^ Replace this binding + | ^ replace this binding LL | [n] => foo(n), | ^^^ with this pattern -error: Unnecessary nested match +error: unnecessary nested match --> $DIR/collapsible_match2.rs:55:24 | LL | Some(ref s) => match &*s { @@ -85,11 +85,11 @@ LL | | _ => (), LL | | }, | |_________^ | -help: The outer pattern can be modified to include the inner pattern. +help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match2.rs:55:14 | LL | Some(ref s) => match &*s { - | ^^^^^ Replace this binding + | ^^^^^ replace this binding LL | [n] => foo(n), | ^^^ with this pattern diff --git a/tests/ui/crashes/ice-6179.rs b/tests/ui/crashes/ice-6179.rs new file mode 100644 index 0000000000000..f8c866a49aa20 --- /dev/null +++ b/tests/ui/crashes/ice-6179.rs @@ -0,0 +1,21 @@ +//! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179. +//! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details. + +#![warn(clippy::use_self)] +#![allow(dead_code)] + +struct Foo {} + +impl Foo { + fn foo() -> Self { + impl Foo { + fn bar() {} + } + + let _: _ = 1; + + Self {} + } +} + +fn main() {} diff --git a/tests/ui/default_numeric_fallback.rs b/tests/ui/default_numeric_fallback.rs new file mode 100644 index 0000000000000..0b3758952ac6d --- /dev/null +++ b/tests/ui/default_numeric_fallback.rs @@ -0,0 +1,135 @@ +#![warn(clippy::default_numeric_fallback)] +#![allow(unused)] +#![allow(clippy::never_loop)] +#![allow(clippy::no_effect)] +#![allow(clippy::unnecessary_operation)] + +mod basic_expr { + fn test() { + // Should lint unsuffixed literals typed `i32`. + let x = 22; + let x = [1, 2, 3]; + let x = if true { (1, 2) } else { (3, 4) }; + let x = match 1 { + 1 => 1, + _ => 2, + }; + + // Should lint unsuffixed literals typed `f64`. + let x = 0.12; + + // Should NOT lint suffixed literals. + let x = 22_i32; + let x = 0.12_f64; + + // Should NOT lint literals in init expr if `Local` has a type annotation. + let x: f64 = 0.1; + let x: [i32; 3] = [1, 2, 3]; + let x: (i32, i32) = if true { (1, 2) } else { (3, 4) }; + let x: _ = 1; + } +} + +mod nested_local { + fn test() { + let x: _ = { + // Should lint this because this literal is not bound to any types. + let y = 1; + + // Should NOT lint this because this literal is bound to `_` of outer `Local`. + 1 + }; + + let x: _ = if true { + // Should lint this because this literal is not bound to any types. + let y = 1; + + // Should NOT lint this because this literal is bound to `_` of outer `Local`. + 1 + } else { + // Should lint this because this literal is not bound to any types. + let y = 1; + + // Should NOT lint this because this literal is bound to `_` of outer `Local`. + 2 + }; + } +} + +mod function_def { + fn ret_i32() -> i32 { + // Even though the output type is specified, + // this unsuffixed literal is linted to reduce heuristics and keep codebase simple. + 1 + } + + fn test() { + // Should lint this because return type is inferred to `i32` and NOT bound to a concrete + // type. + let f = || -> _ { 1 }; + + // Even though the output type is specified, + // this unsuffixed literal is linted to reduce heuristics and keep codebase simple. + let f = || -> i32 { 1 }; + } +} + +mod function_calls { + fn concrete_arg(x: i32) {} + + fn generic_arg(t: T) {} + + fn test() { + // Should NOT lint this because the argument type is bound to a concrete type. + concrete_arg(1); + + // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type. + generic_arg(1); + + // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type. + let x: _ = generic_arg(1); + } +} + +mod struct_ctor { + struct ConcreteStruct { + x: i32, + } + + struct GenericStruct { + x: T, + } + + fn test() { + // Should NOT lint this because the field type is bound to a concrete type. + ConcreteStruct { x: 1 }; + + // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. + GenericStruct { x: 1 }; + + // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. + let _ = GenericStruct { x: 1 }; + } +} + +mod method_calls { + struct StructForMethodCallTest {} + + impl StructForMethodCallTest { + fn concrete_arg(&self, x: i32) {} + + fn generic_arg(&self, t: T) {} + } + + fn test() { + let s = StructForMethodCallTest {}; + + // Should NOT lint this because the argument type is bound to a concrete type. + s.concrete_arg(1); + + // Should lint this because the argument type is bound to a concrete type. + s.generic_arg(1); + } +} + +fn main() {} diff --git a/tests/ui/default_numeric_fallback.stderr b/tests/ui/default_numeric_fallback.stderr new file mode 100644 index 0000000000000..b31aa4ebcf8e4 --- /dev/null +++ b/tests/ui/default_numeric_fallback.stderr @@ -0,0 +1,148 @@ +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:10:17 + | +LL | let x = 22; + | ^^ help: consider adding suffix: `22_i32` + | + = note: `-D clippy::default-numeric-fallback` implied by `-D warnings` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:11:18 + | +LL | let x = [1, 2, 3]; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:11:21 + | +LL | let x = [1, 2, 3]; + | ^ help: consider adding suffix: `2_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:11:24 + | +LL | let x = [1, 2, 3]; + | ^ help: consider adding suffix: `3_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:12:28 + | +LL | let x = if true { (1, 2) } else { (3, 4) }; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:12:31 + | +LL | let x = if true { (1, 2) } else { (3, 4) }; + | ^ help: consider adding suffix: `2_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:12:44 + | +LL | let x = if true { (1, 2) } else { (3, 4) }; + | ^ help: consider adding suffix: `3_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:12:47 + | +LL | let x = if true { (1, 2) } else { (3, 4) }; + | ^ help: consider adding suffix: `4_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:13:23 + | +LL | let x = match 1 { + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:14:13 + | +LL | 1 => 1, + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:14:18 + | +LL | 1 => 1, + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:15:18 + | +LL | _ => 2, + | ^ help: consider adding suffix: `2_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:19:17 + | +LL | let x = 0.12; + | ^^^^ help: consider adding suffix: `0.12_f64` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:37:21 + | +LL | let y = 1; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:45:21 + | +LL | let y = 1; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:51:21 + | +LL | let y = 1; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:63:9 + | +LL | 1 + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:69:27 + | +LL | let f = || -> _ { 1 }; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:73:29 + | +LL | let f = || -> i32 { 1 }; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:87:21 + | +LL | generic_arg(1); + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:90:32 + | +LL | let x: _ = generic_arg(1); + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:108:28 + | +LL | GenericStruct { x: 1 }; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:111:36 + | +LL | let _ = GenericStruct { x: 1 }; + | ^ help: consider adding suffix: `1_i32` + +error: default numeric fallback might occur + --> $DIR/default_numeric_fallback.rs:131:23 + | +LL | s.generic_arg(1); + | ^ help: consider adding suffix: `1_i32` + +error: aborting due to 24 previous errors + diff --git a/tests/ui/doc.rs b/tests/ui/doc.rs index e30970ed95273..d2c666bd2901c 100644 --- a/tests/ui/doc.rs +++ b/tests/ui/doc.rs @@ -50,11 +50,23 @@ fn test_units() { } /// This tests allowed identifiers. +/// KiB MiB GiB TiB PiB EiB /// DirectX /// ECMAScript +/// GPLv2 GPLv3 +/// GitHub GitLab +/// IPv4 IPv6 +/// ClojureScript CoffeeScript JavaScript PureScript TypeScript +/// NaN NaNs /// OAuth GraphQL +/// OCaml +/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS /// WebGL +/// TensorFlow +/// TrueType +/// iOS macOS /// TeX LaTeX BibTeX BibLaTeX +/// MinGW /// CamelCase (see also #2395) /// be_sure_we_got_to_the_end_of_it fn test_allowed() { diff --git a/tests/ui/doc.stderr b/tests/ui/doc.stderr index e1c1aa85a60e1..7eab8a85f093d 100644 --- a/tests/ui/doc.stderr +++ b/tests/ui/doc.stderr @@ -55,133 +55,133 @@ LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:59:5 + --> $DIR/doc.rs:71:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `link_with_underscores` between ticks in the documentation - --> $DIR/doc.rs:63:22 + --> $DIR/doc.rs:75:22 | LL | /// This test has [a link_with_underscores][chunked-example] inside it. See #823. | ^^^^^^^^^^^^^^^^^^^^^ error: you should put `inline_link2` between ticks in the documentation - --> $DIR/doc.rs:66:21 + --> $DIR/doc.rs:78:21 | LL | /// It can also be [inline_link2]. | ^^^^^^^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:76:5 + --> $DIR/doc.rs:88:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `CamelCaseThing` between ticks in the documentation - --> $DIR/doc.rs:84:8 + --> $DIR/doc.rs:96:8 | LL | /// ## CamelCaseThing | ^^^^^^^^^^^^^^ error: you should put `CamelCaseThing` between ticks in the documentation - --> $DIR/doc.rs:87:7 + --> $DIR/doc.rs:99:7 | LL | /// # CamelCaseThing | ^^^^^^^^^^^^^^ error: you should put `CamelCaseThing` between ticks in the documentation - --> $DIR/doc.rs:89:22 + --> $DIR/doc.rs:101:22 | LL | /// Not a title #897 CamelCaseThing | ^^^^^^^^^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:90:5 + --> $DIR/doc.rs:102:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:97:5 + --> $DIR/doc.rs:109:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:110:5 + --> $DIR/doc.rs:122:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `FooBar` between ticks in the documentation - --> $DIR/doc.rs:121:43 + --> $DIR/doc.rs:133:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ error: you should put `BarQuz` between ticks in the documentation - --> $DIR/doc.rs:126:5 + --> $DIR/doc.rs:138:5 | LL | And BarQuz too. | ^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:127:1 + --> $DIR/doc.rs:139:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `FooBar` between ticks in the documentation - --> $DIR/doc.rs:132:43 + --> $DIR/doc.rs:144:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ error: you should put `BarQuz` between ticks in the documentation - --> $DIR/doc.rs:137:5 + --> $DIR/doc.rs:149:5 | LL | And BarQuz too. | ^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:138:1 + --> $DIR/doc.rs:150:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation - --> $DIR/doc.rs:149:5 + --> $DIR/doc.rs:161:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put bare URLs between `<`/`>` or make a proper Markdown link - --> $DIR/doc.rs:176:13 + --> $DIR/doc.rs:188:13 | LL | /// Not ok: http://www.unicode.org | ^^^^^^^^^^^^^^^^^^^^^^ error: you should put bare URLs between `<`/`>` or make a proper Markdown link - --> $DIR/doc.rs:177:13 + --> $DIR/doc.rs:189:13 | LL | /// Not ok: https://www.unicode.org | ^^^^^^^^^^^^^^^^^^^^^^^ error: you should put bare URLs between `<`/`>` or make a proper Markdown link - --> $DIR/doc.rs:178:13 + --> $DIR/doc.rs:190:13 | LL | /// Not ok: http://www.unicode.org/ | ^^^^^^^^^^^^^^^^^^^^^^ error: you should put bare URLs between `<`/`>` or make a proper Markdown link - --> $DIR/doc.rs:179:13 + --> $DIR/doc.rs:191:13 | LL | /// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you should put `mycrate::Collection` between ticks in the documentation - --> $DIR/doc.rs:182:22 + --> $DIR/doc.rs:194:22 | LL | /// An iterator over mycrate::Collection's values. | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/doc_panics.rs b/tests/ui/doc_panics.rs index 7ef932f367b10..3008c2d5b8538 100644 --- a/tests/ui/doc_panics.rs +++ b/tests/ui/doc_panics.rs @@ -28,6 +28,15 @@ pub fn inner_body(opt: Option) { }); } +/// This needs to be documented +pub fn unreachable_and_panic() { + if true { + unreachable!() + } else { + panic!() + } +} + /// This is documented /// /// # Panics @@ -69,6 +78,19 @@ pub fn todo_documented() { todo!() } +/// This is documented +/// +/// # Panics +/// +/// We still need to do this part +pub fn unreachable_amd_panic_documented() { + if true { + unreachable!() + } else { + panic!() + } +} + /// This is okay because it is private fn unwrap_private() { let result = Err("Hi"); @@ -93,3 +115,8 @@ fn inner_body_private(opt: Option) { } }); } + +/// This is okay because unreachable +pub fn unreachable() { + unreachable!("This function panics") +} diff --git a/tests/ui/doc_panics.stderr b/tests/ui/doc_panics.stderr index c0c4e9e4fa7ee..287148690d27a 100644 --- a/tests/ui/doc_panics.stderr +++ b/tests/ui/doc_panics.stderr @@ -63,5 +63,24 @@ LL | panic!() | ^^^^^^^^ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error: docs for function which may panic missing `# Panics` section + --> $DIR/doc_panics.rs:32:1 + | +LL | / pub fn unreachable_and_panic() { +LL | | if true { +LL | | unreachable!() +LL | | } else { +LL | | panic!() +LL | | } +LL | | } + | |_^ + | +note: first possible panic found here + --> $DIR/doc_panics.rs:36:9 + | +LL | panic!() + | ^^^^^^^^ + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 5 previous errors diff --git a/tests/ui/enum_variants.rs b/tests/ui/enum_variants.rs index 89d99dcf0c867..4fefc0b43f1d9 100644 --- a/tests/ui/enum_variants.rs +++ b/tests/ui/enum_variants.rs @@ -133,4 +133,17 @@ pub enum NetworkLayer { Layer3, } +// should lint suggesting `IData`, not only `Data` (see #4639) +enum IDataRequest { + PutIData(String), + GetIData(String), + DeleteUnpubIData(String), +} + +enum HIDataRequest { + PutHIData(String), + GetHIData(String), + DeleteUnpubHIData(String), +} + fn main() {} diff --git a/tests/ui/enum_variants.stderr b/tests/ui/enum_variants.stderr index b1d481190ff53..ab7fff4507aaa 100644 --- a/tests/ui/enum_variants.stderr +++ b/tests/ui/enum_variants.stderr @@ -97,5 +97,29 @@ LL | | } = note: `-D clippy::pub-enum-variant-names` implied by `-D warnings` = help: remove the prefixes and use full paths to the variants instead of glob imports -error: aborting due to 10 previous errors +error: all variants have the same postfix: `IData` + --> $DIR/enum_variants.rs:137:1 + | +LL | / enum IDataRequest { +LL | | PutIData(String), +LL | | GetIData(String), +LL | | DeleteUnpubIData(String), +LL | | } + | |_^ + | + = help: remove the postfixes and use full paths to the variants instead of glob imports + +error: all variants have the same postfix: `HIData` + --> $DIR/enum_variants.rs:143:1 + | +LL | / enum HIDataRequest { +LL | | PutHIData(String), +LL | | GetHIData(String), +LL | | DeleteUnpubHIData(String), +LL | | } + | |_^ + | + = help: remove the postfixes and use full paths to the variants instead of glob imports + +error: aborting due to 12 previous errors diff --git a/tests/ui/from_str_radix_10.rs b/tests/ui/from_str_radix_10.rs new file mode 100644 index 0000000000000..2f2ea04847a98 --- /dev/null +++ b/tests/ui/from_str_radix_10.rs @@ -0,0 +1,52 @@ +#![warn(clippy::from_str_radix_10)] + +mod some_mod { + // fake function that shouldn't trigger the lint + pub fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> { + unimplemented!() + } +} + +// fake function that shouldn't trigger the lint +fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> { + unimplemented!() +} + +// to test parenthesis addition +struct Test; + +impl std::ops::Add for Test { + type Output = &'static str; + + fn add(self, _: Self) -> Self::Output { + "304" + } +} + +fn main() -> Result<(), Box> { + // all of these should trigger the lint + u32::from_str_radix("30", 10)?; + i64::from_str_radix("24", 10)?; + isize::from_str_radix("100", 10)?; + u8::from_str_radix("7", 10)?; + u16::from_str_radix(&("10".to_owned() + "5"), 10)?; + i128::from_str_radix(Test + Test, 10)?; + + let string = "300"; + i32::from_str_radix(string, 10)?; + + let stringier = "400".to_string(); + i32::from_str_radix(&stringier, 10)?; + + // none of these should trigger the lint + u16::from_str_radix("20", 3)?; + i32::from_str_radix("45", 12)?; + usize::from_str_radix("10", 16)?; + i128::from_str_radix("10", 13)?; + some_mod::from_str_radix("50", 10)?; + some_mod::from_str_radix("50", 6)?; + from_str_radix("50", 10)?; + from_str_radix("50", 6)?; + + Ok(()) +} diff --git a/tests/ui/from_str_radix_10.stderr b/tests/ui/from_str_radix_10.stderr new file mode 100644 index 0000000000000..471bf52a9a7ed --- /dev/null +++ b/tests/ui/from_str_radix_10.stderr @@ -0,0 +1,52 @@ +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:28:5 + | +LL | u32::from_str_radix("30", 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"30".parse::()` + | + = note: `-D clippy::from-str-radix-10` implied by `-D warnings` + +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:29:5 + | +LL | i64::from_str_radix("24", 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"24".parse::()` + +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:30:5 + | +LL | isize::from_str_radix("100", 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"100".parse::()` + +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:31:5 + | +LL | u8::from_str_radix("7", 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"7".parse::()` + +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:32:5 + | +LL | u16::from_str_radix(&("10".to_owned() + "5"), 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(("10".to_owned() + "5")).parse::()` + +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:33:5 + | +LL | i128::from_str_radix(Test + Test, 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(Test + Test).parse::()` + +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:36:5 + | +LL | i32::from_str_radix(string, 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.parse::()` + +error: this call to `from_str_radix` can be replaced with a call to `str::parse` + --> $DIR/from_str_radix_10.rs:39:5 + | +LL | i32::from_str_radix(&stringier, 10)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `stringier.parse::()` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/if_same_then_else2.rs b/tests/ui/if_same_then_else2.rs index e83ce47e56308..a2ff1b741ca25 100644 --- a/tests/ui/if_same_then_else2.rs +++ b/tests/ui/if_same_then_else2.rs @@ -12,7 +12,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> { if true { for _ in &[42] { let foo: &Option<_> = &Some::(42); - if true { + if foo.is_some() { break; } else { continue; @@ -21,8 +21,8 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } else { //~ ERROR same body as `if` block for _ in &[42] { - let foo: &Option<_> = &Some::(42); - if true { + let bar: &Option<_> = &Some::(42); + if bar.is_some() { break; } else { continue; diff --git a/tests/ui/if_same_then_else2.stderr b/tests/ui/if_same_then_else2.stderr index f98e30fa376fe..454322d8aacda 100644 --- a/tests/ui/if_same_then_else2.stderr +++ b/tests/ui/if_same_then_else2.stderr @@ -5,7 +5,7 @@ LL | } else { | ____________^ LL | | //~ ERROR same body as `if` block LL | | for _ in &[42] { -LL | | let foo: &Option<_> = &Some::(42); +LL | | let bar: &Option<_> = &Some::(42); ... | LL | | } LL | | } @@ -19,7 +19,7 @@ LL | if true { | _____________^ LL | | for _ in &[42] { LL | | let foo: &Option<_> = &Some::(42); -LL | | if true { +LL | | if foo.is_some() { ... | LL | | } LL | | } else { diff --git a/tests/ui/inconsistent_struct_constructor.fixed b/tests/ui/inconsistent_struct_constructor.fixed new file mode 100644 index 0000000000000..8d9c311003508 --- /dev/null +++ b/tests/ui/inconsistent_struct_constructor.fixed @@ -0,0 +1,61 @@ +// run-rustfix +// edition:2018 +#![warn(clippy::inconsistent_struct_constructor)] +#![allow(clippy::redundant_field_names)] +#![allow(clippy::unnecessary_operation)] +#![allow(clippy::no_effect)] +#![allow(dead_code)] + +#[derive(Default)] +struct Foo { + x: i32, + y: i32, + z: i32, +} + +mod without_base { + use super::Foo; + + fn test() { + let x = 1; + let y = 1; + let z = 1; + + // Should lint. + Foo { x, y, z }; + + // Shoule NOT lint because the order is the same as in the definition. + Foo { x, y, z }; + + // Should NOT lint because z is not a shorthand init. + Foo { y, x, z: z }; + } +} + +mod with_base { + use super::Foo; + + fn test() { + let x = 1; + let z = 1; + + // Should lint. + Foo { x, z, ..Default::default() }; + + // Should NOT lint because the order is consistent with the definition. + Foo { + x, + z, + ..Default::default() + }; + + // Should NOT lint because z is not a shorthand init. + Foo { + z: z, + x, + ..Default::default() + }; + } +} + +fn main() {} diff --git a/tests/ui/inconsistent_struct_constructor.rs b/tests/ui/inconsistent_struct_constructor.rs new file mode 100644 index 0000000000000..63fac9105015d --- /dev/null +++ b/tests/ui/inconsistent_struct_constructor.rs @@ -0,0 +1,65 @@ +// run-rustfix +// edition:2018 +#![warn(clippy::inconsistent_struct_constructor)] +#![allow(clippy::redundant_field_names)] +#![allow(clippy::unnecessary_operation)] +#![allow(clippy::no_effect)] +#![allow(dead_code)] + +#[derive(Default)] +struct Foo { + x: i32, + y: i32, + z: i32, +} + +mod without_base { + use super::Foo; + + fn test() { + let x = 1; + let y = 1; + let z = 1; + + // Should lint. + Foo { y, x, z }; + + // Shoule NOT lint because the order is the same as in the definition. + Foo { x, y, z }; + + // Should NOT lint because z is not a shorthand init. + Foo { y, x, z: z }; + } +} + +mod with_base { + use super::Foo; + + fn test() { + let x = 1; + let z = 1; + + // Should lint. + Foo { + z, + x, + ..Default::default() + }; + + // Should NOT lint because the order is consistent with the definition. + Foo { + x, + z, + ..Default::default() + }; + + // Should NOT lint because z is not a shorthand init. + Foo { + z: z, + x, + ..Default::default() + }; + } +} + +fn main() {} diff --git a/tests/ui/inconsistent_struct_constructor.stderr b/tests/ui/inconsistent_struct_constructor.stderr new file mode 100644 index 0000000000000..d7abe44f25408 --- /dev/null +++ b/tests/ui/inconsistent_struct_constructor.stderr @@ -0,0 +1,20 @@ +error: inconsistent struct constructor + --> $DIR/inconsistent_struct_constructor.rs:25:9 + | +LL | Foo { y, x, z }; + | ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }` + | + = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings` + +error: inconsistent struct constructor + --> $DIR/inconsistent_struct_constructor.rs:43:9 + | +LL | / Foo { +LL | | z, +LL | | x, +LL | | ..Default::default() +LL | | }; + | |_________^ help: try: `Foo { x, z, ..Default::default() }` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/inherent_to_string.rs b/tests/ui/inherent_to_string.rs index e6cf337d1bb1b..6e65fdbd04e7d 100644 --- a/tests/ui/inherent_to_string.rs +++ b/tests/ui/inherent_to_string.rs @@ -14,6 +14,7 @@ struct C; struct D; struct E; struct F; +struct G; impl A { // Should be detected; emit warning @@ -73,6 +74,13 @@ impl F { } } +impl G { + // Should not be detected, as it does not match the function signature + fn to_string(&self) -> String { + "G.to_string()".to_string() + } +} + fn main() { let a = A; a.to_string(); @@ -93,4 +101,7 @@ fn main() { let f = F; f.to_string(1); + + let g = G; + g.to_string::<1>(); } diff --git a/tests/ui/inherent_to_string.stderr b/tests/ui/inherent_to_string.stderr index 4f331f5bec9e6..f5fcc193b4d8a 100644 --- a/tests/ui/inherent_to_string.stderr +++ b/tests/ui/inherent_to_string.stderr @@ -1,5 +1,5 @@ error: implementation of inherent method `to_string(&self) -> String` for type `A` - --> $DIR/inherent_to_string.rs:20:5 + --> $DIR/inherent_to_string.rs:21:5 | LL | / fn to_string(&self) -> String { LL | | "A.to_string()".to_string() @@ -10,7 +10,7 @@ LL | | } = help: implement trait `Display` for type `A` instead error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display` - --> $DIR/inherent_to_string.rs:44:5 + --> $DIR/inherent_to_string.rs:45:5 | LL | / fn to_string(&self) -> String { LL | | "C.to_string()".to_string() diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed new file mode 100644 index 0000000000000..1935090675825 --- /dev/null +++ b/tests/ui/manual_map_option.fixed @@ -0,0 +1,70 @@ +// run-rustfix + +#![warn(clippy::manual_map)] +#![allow(clippy::no_effect, clippy::map_identity, clippy::unit_arg, clippy::match_ref_pats)] + +fn main() { + Some(0).map(|_| 2); + + Some(0).map(|x| x + 1); + + Some("").map(|x| x.is_empty()); + + Some(0).map(|x| !x); + + #[rustfmt::skip] + Some(0).map(std::convert::identity); + + Some(&String::new()).map(|x| str::len(x)); + + match Some(0) { + Some(x) if false => Some(x + 1), + _ => None, + }; + + Some([0, 1]).as_ref().map(|x| x[0]); + + Some(0).map(|x| x * 2); + + Some(String::new()).as_ref().map(|x| x.is_empty()); + + Some(String::new()).as_ref().map(|x| x.len()); + + Some(0).map(|x| x + x); + + #[warn(clippy::option_map_unit_fn)] + match &mut Some(String::new()) { + Some(x) => Some(x.push_str("")), + None => None, + }; + + #[allow(clippy::option_map_unit_fn)] + { + Some(String::new()).as_mut().map(|x| x.push_str("")); + } + + Some(String::new()).as_ref().map(|x| x.len()); + + Some(String::new()).as_ref().map(|x| x.is_empty()); + + Some((0, 1, 2)).map(|(x, y, z)| x + y + z); + + Some([1, 2, 3]).map(|[first, ..]| first); + + Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x)); + + match Some((String::new(), 0)) { + Some((ref x, y)) => Some((y, x)), + None => None, + }; + + match Some(Some(0)) { + Some(Some(_)) | Some(None) => Some(0), + None => None, + }; + + match Some(Some((0, 1))) { + Some(Some((x, 1))) => Some(x), + _ => None, + }; +} diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs new file mode 100644 index 0000000000000..8b8187db0a979 --- /dev/null +++ b/tests/ui/manual_map_option.rs @@ -0,0 +1,122 @@ +// run-rustfix + +#![warn(clippy::manual_map)] +#![allow(clippy::no_effect, clippy::map_identity, clippy::unit_arg, clippy::match_ref_pats)] + +fn main() { + match Some(0) { + Some(_) => Some(2), + None:: => None, + }; + + match Some(0) { + Some(x) => Some(x + 1), + _ => None, + }; + + match Some("") { + Some(x) => Some(x.is_empty()), + None => None, + }; + + if let Some(x) = Some(0) { + Some(!x) + } else { + None + }; + + #[rustfmt::skip] + match Some(0) { + Some(x) => { Some(std::convert::identity(x)) } + None => { None } + }; + + match Some(&String::new()) { + Some(x) => Some(str::len(x)), + None => None, + }; + + match Some(0) { + Some(x) if false => Some(x + 1), + _ => None, + }; + + match &Some([0, 1]) { + Some(x) => Some(x[0]), + &None => None, + }; + + match &Some(0) { + &Some(x) => Some(x * 2), + None => None, + }; + + match Some(String::new()) { + Some(ref x) => Some(x.is_empty()), + _ => None, + }; + + match &&Some(String::new()) { + Some(x) => Some(x.len()), + _ => None, + }; + + match &&Some(0) { + &&Some(x) => Some(x + x), + &&_ => None, + }; + + #[warn(clippy::option_map_unit_fn)] + match &mut Some(String::new()) { + Some(x) => Some(x.push_str("")), + None => None, + }; + + #[allow(clippy::option_map_unit_fn)] + { + match &mut Some(String::new()) { + Some(x) => Some(x.push_str("")), + None => None, + }; + } + + match &mut Some(String::new()) { + Some(ref x) => Some(x.len()), + None => None, + }; + + match &mut &Some(String::new()) { + Some(x) => Some(x.is_empty()), + &mut _ => None, + }; + + match Some((0, 1, 2)) { + Some((x, y, z)) => Some(x + y + z), + None => None, + }; + + match Some([1, 2, 3]) { + Some([first, ..]) => Some(first), + None => None, + }; + + match &Some((String::new(), "test")) { + Some((x, y)) => Some((y, x)), + None => None, + }; + + match Some((String::new(), 0)) { + Some((ref x, y)) => Some((y, x)), + None => None, + }; + + match Some(Some(0)) { + Some(Some(_)) | Some(None) => Some(0), + None => None, + }; + + match Some(Some((0, 1))) { + Some(Some((x, 1))) => Some(x), + _ => None, + }; +} diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr new file mode 100644 index 0000000000000..210a30d05d40f --- /dev/null +++ b/tests/ui/manual_map_option.stderr @@ -0,0 +1,158 @@ +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:7:5 + | +LL | / match Some(0) { +LL | | Some(_) => Some(2), +LL | | None:: => None, +LL | | }; + | |_____^ help: try this: `Some(0).map(|_| 2)` + | + = note: `-D clippy::manual-map` implied by `-D warnings` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:12:5 + | +LL | / match Some(0) { +LL | | Some(x) => Some(x + 1), +LL | | _ => None, +LL | | }; + | |_____^ help: try this: `Some(0).map(|x| x + 1)` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:17:5 + | +LL | / match Some("") { +LL | | Some(x) => Some(x.is_empty()), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some("").map(|x| x.is_empty())` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:22:5 + | +LL | / if let Some(x) = Some(0) { +LL | | Some(!x) +LL | | } else { +LL | | None +LL | | }; + | |_____^ help: try this: `Some(0).map(|x| !x)` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:29:5 + | +LL | / match Some(0) { +LL | | Some(x) => { Some(std::convert::identity(x)) } +LL | | None => { None } +LL | | }; + | |_____^ help: try this: `Some(0).map(std::convert::identity)` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:34:5 + | +LL | / match Some(&String::new()) { +LL | | Some(x) => Some(str::len(x)), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some(&String::new()).map(|x| str::len(x))` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:44:5 + | +LL | / match &Some([0, 1]) { +LL | | Some(x) => Some(x[0]), +LL | | &None => None, +LL | | }; + | |_____^ help: try this: `Some([0, 1]).as_ref().map(|x| x[0])` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:49:5 + | +LL | / match &Some(0) { +LL | | &Some(x) => Some(x * 2), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some(0).map(|x| x * 2)` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:54:5 + | +LL | / match Some(String::new()) { +LL | | Some(ref x) => Some(x.is_empty()), +LL | | _ => None, +LL | | }; + | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:59:5 + | +LL | / match &&Some(String::new()) { +LL | | Some(x) => Some(x.len()), +LL | | _ => None, +LL | | }; + | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:64:5 + | +LL | / match &&Some(0) { +LL | | &&Some(x) => Some(x + x), +LL | | &&_ => None, +LL | | }; + | |_____^ help: try this: `Some(0).map(|x| x + x)` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:77:9 + | +LL | / match &mut Some(String::new()) { +LL | | Some(x) => Some(x.push_str("")), +LL | | None => None, +LL | | }; + | |_________^ help: try this: `Some(String::new()).as_mut().map(|x| x.push_str(""))` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:83:5 + | +LL | / match &mut Some(String::new()) { +LL | | Some(ref x) => Some(x.len()), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:88:5 + | +LL | / match &mut &Some(String::new()) { +LL | | Some(x) => Some(x.is_empty()), +LL | | &mut _ => None, +LL | | }; + | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:93:5 + | +LL | / match Some((0, 1, 2)) { +LL | | Some((x, y, z)) => Some(x + y + z), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:98:5 + | +LL | / match Some([1, 2, 3]) { +LL | | Some([first, ..]) => Some(first), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some([1, 2, 3]).map(|[first, ..]| first)` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:103:5 + | +LL | / match &Some((String::new(), "test")) { +LL | | Some((x, y)) => Some((y, x)), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` + +error: aborting due to 17 previous errors + diff --git a/tests/ui/result_unit_error.rs b/tests/ui/result_unit_error.rs index 5e57c752b5a03..a4ec803024edf 100644 --- a/tests/ui/result_unit_error.rs +++ b/tests/ui/result_unit_error.rs @@ -1,6 +1,4 @@ -#![allow(clippy::unnecessary_wraps)] -#[warn(clippy::result_unit_err)] -#[allow(unused)] +#![warn(clippy::result_unit_err)] pub fn returns_unit_error() -> Result { Err(()) @@ -36,4 +34,23 @@ impl UnitErrorHolder { } } +// https://github.com/rust-lang/rust-clippy/issues/6546 +pub mod issue_6546 { + type ResInv = Result; + + pub fn should_lint() -> ResInv<(), usize> { + Ok(0) + } + + pub fn should_not_lint() -> ResInv { + Ok(()) + } + + type MyRes = Result<(A, B), Box>; + + pub fn should_not_lint2(x: i32) -> MyRes { + Ok((x, ())) + } +} + fn main() {} diff --git a/tests/ui/result_unit_error.stderr b/tests/ui/result_unit_error.stderr index 12901b354f916..41d8b0a7cb7f8 100644 --- a/tests/ui/result_unit_error.stderr +++ b/tests/ui/result_unit_error.stderr @@ -1,5 +1,5 @@ error: this returns a `Result<_, ()> - --> $DIR/result_unit_error.rs:5:1 + --> $DIR/result_unit_error.rs:3:1 | LL | pub fn returns_unit_error() -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | pub fn returns_unit_error() -> Result { = help: use a custom Error type instead error: this returns a `Result<_, ()> - --> $DIR/result_unit_error.rs:14:5 + --> $DIR/result_unit_error.rs:12:5 | LL | fn get_that_error(&self) -> Result; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | fn get_that_error(&self) -> Result; = help: use a custom Error type instead error: this returns a `Result<_, ()> - --> $DIR/result_unit_error.rs:16:5 + --> $DIR/result_unit_error.rs:14:5 | LL | fn get_this_one_too(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,12 +24,20 @@ LL | fn get_this_one_too(&self) -> Result { = help: use a custom Error type instead error: this returns a `Result<_, ()> - --> $DIR/result_unit_error.rs:34:5 + --> $DIR/result_unit_error.rs:32:5 | LL | pub fn unit_error(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a custom Error type instead -error: aborting due to 4 previous errors +error: this returns a `Result<_, ()> + --> $DIR/result_unit_error.rs:41:5 + | +LL | pub fn should_lint() -> ResInv<(), usize> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use a custom Error type instead + +error: aborting due to 5 previous errors diff --git a/tests/ui/unnecessary_wraps.rs b/tests/ui/unnecessary_wraps.rs index a4570098d7167..a510263e67da1 100644 --- a/tests/ui/unnecessary_wraps.rs +++ b/tests/ui/unnecessary_wraps.rs @@ -116,8 +116,53 @@ fn issue_6384(s: &str) -> Option<&str> { }) } +// should be linted +fn issue_6640_1(a: bool, b: bool) -> Option<()> { + if a && b { + return Some(()); + } + if a { + Some(()); + Some(()) + } else { + return Some(()); + } +} + +// should be linted +fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { + if a && b { + return Ok(()); + } + if a { + Ok(()) + } else { + return Ok(()); + } +} + +// should not be linted +fn issue_6640_3() -> Option<()> { + if true { + Some(()) + } else { + None + } +} + +// should not be linted +fn issue_6640_4() -> Result<(), ()> { + if true { + Ok(()) + } else { + Err(()) + } +} + fn main() { // method calls are not linted func1(true, true); func2(true, true); + issue_6640_1(true, true); + issue_6640_2(true, true); } diff --git a/tests/ui/unnecessary_wraps.stderr b/tests/ui/unnecessary_wraps.stderr index 410f054b8efca..9a861c61a4679 100644 --- a/tests/ui/unnecessary_wraps.stderr +++ b/tests/ui/unnecessary_wraps.stderr @@ -15,7 +15,7 @@ help: remove `Option` from the return type... | LL | fn func1(a: bool, b: bool) -> i32 { | ^^^ -help: ...and change the returning expressions +help: ...and then change returning expressions | LL | return 42; LL | } @@ -41,7 +41,7 @@ help: remove `Option` from the return type... | LL | fn func2(a: bool, b: bool) -> i32 { | ^^^ -help: ...and change the returning expressions +help: ...and then change returning expressions | LL | return 10; LL | } @@ -63,7 +63,7 @@ help: remove `Option` from the return type... | LL | fn func5() -> i32 { | ^^^ -help: ...and change the returning expressions +help: ...and then change returning expressions | LL | 1 | @@ -80,7 +80,7 @@ help: remove `Result` from the return type... | LL | fn func7() -> i32 { | ^^^ -help: ...and change the returning expressions +help: ...and then change returning expressions | LL | 1 | @@ -97,10 +97,62 @@ help: remove `Option` from the return type... | LL | fn func12() -> i32 { | ^^^ -help: ...and change the returning expressions +help: ...and then change returning expressions | LL | 1 | -error: aborting due to 5 previous errors +error: this function's return value is unnecessary + --> $DIR/unnecessary_wraps.rs:120:1 + | +LL | / fn issue_6640_1(a: bool, b: bool) -> Option<()> { +LL | | if a && b { +LL | | return Some(()); +LL | | } +... | +LL | | } +LL | | } + | |_^ + | +help: remove the return type... + | +LL | fn issue_6640_1(a: bool, b: bool) -> Option<()> { + | ^^^^^^^^^^ +help: ...and then remove returned values + | +LL | return ; +LL | } +LL | if a { +LL | Some(()); +LL | +LL | } else { + ... + +error: this function's return value is unnecessary + --> $DIR/unnecessary_wraps.rs:133:1 + | +LL | / fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { +LL | | if a && b { +LL | | return Ok(()); +LL | | } +... | +LL | | } +LL | | } + | |_^ + | +help: remove the return type... + | +LL | fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { + | ^^^^^^^^^^^^^^^ +help: ...and then remove returned values + | +LL | return ; +LL | } +LL | if a { +LL | +LL | } else { +LL | return ; + | + +error: aborting due to 7 previous errors diff --git a/tests/ui/upper_case_acronyms.rs b/tests/ui/upper_case_acronyms.rs index af0b577634863..fdf8905f812f6 100644 --- a/tests/ui/upper_case_acronyms.rs +++ b/tests/ui/upper_case_acronyms.rs @@ -1,11 +1,11 @@ #![warn(clippy::upper_case_acronyms)] -struct HTTPResponse; // linted +struct HTTPResponse; // not linted by default, but with cfg option struct CString; // not linted enum Flags { - NS, // linted + NS, // not linted CWR, ECE, URG, @@ -16,6 +16,7 @@ enum Flags { FIN, } -struct GCCLLVMSomething; // linted, beware that lint suggests `GccllvmSomething` instead of `GccLlvmSomething` +struct GCCLLVMSomething; // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of + // `GccLlvmSomething` fn main() {} diff --git a/tests/ui/upper_case_acronyms.stderr b/tests/ui/upper_case_acronyms.stderr index 2065fe10bb151..bbe38991e5271 100644 --- a/tests/ui/upper_case_acronyms.stderr +++ b/tests/ui/upper_case_acronyms.stderr @@ -1,22 +1,10 @@ -error: name `HTTPResponse` contains a capitalized acronym - --> $DIR/upper_case_acronyms.rs:3:8 - | -LL | struct HTTPResponse; // linted - | ^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `HttpResponse` - | - = note: `-D clippy::upper-case-acronyms` implied by `-D warnings` - -error: name `NS` contains a capitalized acronym - --> $DIR/upper_case_acronyms.rs:8:5 - | -LL | NS, // linted - | ^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ns` - error: name `CWR` contains a capitalized acronym --> $DIR/upper_case_acronyms.rs:9:5 | LL | CWR, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Cwr` + | + = note: `-D clippy::upper-case-acronyms` implied by `-D warnings` error: name `ECE` contains a capitalized acronym --> $DIR/upper_case_acronyms.rs:10:5 @@ -60,11 +48,5 @@ error: name `FIN` contains a capitalized acronym LL | FIN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin` -error: name `GCCLLVMSomething` contains a capitalized acronym - --> $DIR/upper_case_acronyms.rs:19:8 - | -LL | struct GCCLLVMSomething; // linted, beware that lint suggests `GccllvmSomething` instead of `GccLlvmSomething` - | ^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GccllvmSomething` - -error: aborting due to 11 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index bb2012441d90c..95e7bc754310f 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -1,9 +1,13 @@ // run-rustfix // edition:2018 +// aux-build:proc_macro_derive.rs #![warn(clippy::use_self)] #![allow(dead_code)] -#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms)] +#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)] + +#[macro_use] +extern crate proc_macro_derive; fn main() {} @@ -71,13 +75,12 @@ mod lifetimes { mod issue2894 { trait IntoBytes { - #[allow(clippy::wrong_self_convention)] - fn into_bytes(&self) -> Vec; + fn to_bytes(&self) -> Vec; } // This should not be linted impl IntoBytes for u8 { - fn into_bytes(&self) -> Vec { + fn to_bytes(&self) -> Vec { vec![*self] } } @@ -110,8 +113,8 @@ mod tuple_structs { mod macros { macro_rules! use_self_expand { () => { - fn new() -> Self { - Self {} + fn new() -> Foo { + Foo {} } }; } @@ -119,8 +122,11 @@ mod macros { struct Foo {} impl Foo { - use_self_expand!(); // Should lint in local macros + use_self_expand!(); // Should not lint in local macros } + + #[derive(StructAUseSelf)] // Should not lint in derives + struct A; } mod nesting { @@ -177,11 +183,22 @@ mod issue3410 { struct B; trait Trait { - fn a(v: T); + fn a(v: T) -> Self; } impl Trait> for Vec { - fn a(_: Vec) {} + fn a(_: Vec) -> Self { + unimplemented!() + } + } + + impl Trait> for Vec + where + T: Trait, + { + fn a(v: Vec) -> Self { + >::a(v).into_iter().map(Trait::a).collect() + } } } @@ -252,3 +269,192 @@ mod paths_created_by_lowering { } } } + +// reused from #1997 +mod generics { + struct Foo { + value: T, + } + + impl Foo { + // `Self` is applicable here + fn foo(value: T) -> Self { + Self { value } + } + + // `Cannot` use `Self` as a return type as the generic types are different + fn bar(value: i32) -> Foo { + Foo { value } + } + } +} + +mod issue4140 { + pub struct Error { + _from: From, + _too: To, + } + + pub trait From { + type From; + type To; + + fn from(value: T) -> Self; + } + + pub trait TryFrom + where + Self: Sized, + { + type From; + type To; + + fn try_from(value: T) -> Result>; + } + + impl TryFrom for T + where + T: From, + { + type From = Self; + type To = Self; + + fn try_from(value: F) -> Result> { + Ok(From::from(value)) + } + } + + impl From for i64 { + type From = bool; + type To = Self; + + fn from(value: bool) -> Self { + if value { + 100 + } else { + 0 + } + } + } +} + +mod issue2843 { + trait Foo { + type Bar; + } + + impl Foo for usize { + type Bar = u8; + } + + impl Foo for Option { + type Bar = Option; + } +} + +mod issue3859 { + pub struct Foo; + pub struct Bar([usize; 3]); + + impl Foo { + pub const BAR: usize = 3; + + pub fn foo() { + const _X: usize = Foo::BAR; + // const _Y: usize = Self::BAR; + } + } +} + +mod issue4305 { + trait Foo: 'static {} + + struct Bar; + + impl Foo for Bar {} + + impl From for Box { + fn from(t: T) -> Self { + Box::new(t) + } + } +} + +mod lint_at_item_level { + struct Foo {} + + #[allow(clippy::use_self)] + impl Foo { + fn new() -> Foo { + Foo {} + } + } + + #[allow(clippy::use_self)] + impl Default for Foo { + fn default() -> Foo { + Foo::new() + } + } +} + +mod lint_at_impl_item_level { + struct Foo {} + + impl Foo { + #[allow(clippy::use_self)] + fn new() -> Foo { + Foo {} + } + } + + impl Default for Foo { + #[allow(clippy::use_self)] + fn default() -> Foo { + Foo::new() + } + } +} + +mod issue4734 { + #[repr(C, packed)] + pub struct X { + pub x: u32, + } + + impl From for u32 { + fn from(c: X) -> Self { + unsafe { core::mem::transmute(c) } + } + } +} + +mod nested_paths { + use std::convert::Into; + mod submod { + pub struct B {} + pub struct C {} + + impl Into for B { + fn into(self) -> C { + C {} + } + } + } + + struct A { + t: T, + } + + impl A { + fn new>(v: V) -> Self { + Self { t: Into::into(v) } + } + } + + impl A { + fn test() -> Self { + Self::new::(submod::B {}) + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index ddfd2beba3107..75424f341597d 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -1,9 +1,13 @@ // run-rustfix // edition:2018 +// aux-build:proc_macro_derive.rs #![warn(clippy::use_self)] #![allow(dead_code)] -#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms)] +#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)] + +#[macro_use] +extern crate proc_macro_derive; fn main() {} @@ -71,13 +75,12 @@ mod lifetimes { mod issue2894 { trait IntoBytes { - #[allow(clippy::wrong_self_convention)] - fn into_bytes(&self) -> Vec; + fn to_bytes(&self) -> Vec; } // This should not be linted impl IntoBytes for u8 { - fn into_bytes(&self) -> Vec { + fn to_bytes(&self) -> Vec { vec![*self] } } @@ -87,7 +90,7 @@ mod existential { struct Foo; impl Foo { - fn bad(foos: &[Self]) -> impl Iterator { + fn bad(foos: &[Foo]) -> impl Iterator { foos.iter() } @@ -119,8 +122,11 @@ mod macros { struct Foo {} impl Foo { - use_self_expand!(); // Should lint in local macros + use_self_expand!(); // Should not lint in local macros } + + #[derive(StructAUseSelf)] // Should not lint in derives + struct A; } mod nesting { @@ -177,11 +183,22 @@ mod issue3410 { struct B; trait Trait { - fn a(v: T); + fn a(v: T) -> Self; } impl Trait> for Vec { - fn a(_: Vec) {} + fn a(_: Vec) -> Self { + unimplemented!() + } + } + + impl Trait> for Vec + where + T: Trait, + { + fn a(v: Vec) -> Self { + >::a(v).into_iter().map(Trait::a).collect() + } } } @@ -252,3 +269,192 @@ mod paths_created_by_lowering { } } } + +// reused from #1997 +mod generics { + struct Foo { + value: T, + } + + impl Foo { + // `Self` is applicable here + fn foo(value: T) -> Foo { + Foo { value } + } + + // `Cannot` use `Self` as a return type as the generic types are different + fn bar(value: i32) -> Foo { + Foo { value } + } + } +} + +mod issue4140 { + pub struct Error { + _from: From, + _too: To, + } + + pub trait From { + type From; + type To; + + fn from(value: T) -> Self; + } + + pub trait TryFrom + where + Self: Sized, + { + type From; + type To; + + fn try_from(value: T) -> Result>; + } + + impl TryFrom for T + where + T: From, + { + type From = T::From; + type To = T::To; + + fn try_from(value: F) -> Result> { + Ok(From::from(value)) + } + } + + impl From for i64 { + type From = bool; + type To = Self; + + fn from(value: bool) -> Self { + if value { + 100 + } else { + 0 + } + } + } +} + +mod issue2843 { + trait Foo { + type Bar; + } + + impl Foo for usize { + type Bar = u8; + } + + impl Foo for Option { + type Bar = Option; + } +} + +mod issue3859 { + pub struct Foo; + pub struct Bar([usize; 3]); + + impl Foo { + pub const BAR: usize = 3; + + pub fn foo() { + const _X: usize = Foo::BAR; + // const _Y: usize = Self::BAR; + } + } +} + +mod issue4305 { + trait Foo: 'static {} + + struct Bar; + + impl Foo for Bar {} + + impl From for Box { + fn from(t: T) -> Self { + Box::new(t) + } + } +} + +mod lint_at_item_level { + struct Foo {} + + #[allow(clippy::use_self)] + impl Foo { + fn new() -> Foo { + Foo {} + } + } + + #[allow(clippy::use_self)] + impl Default for Foo { + fn default() -> Foo { + Foo::new() + } + } +} + +mod lint_at_impl_item_level { + struct Foo {} + + impl Foo { + #[allow(clippy::use_self)] + fn new() -> Foo { + Foo {} + } + } + + impl Default for Foo { + #[allow(clippy::use_self)] + fn default() -> Foo { + Foo::new() + } + } +} + +mod issue4734 { + #[repr(C, packed)] + pub struct X { + pub x: u32, + } + + impl From for u32 { + fn from(c: X) -> Self { + unsafe { core::mem::transmute(c) } + } + } +} + +mod nested_paths { + use std::convert::Into; + mod submod { + pub struct B {} + pub struct C {} + + impl Into for B { + fn into(self) -> C { + C {} + } + } + } + + struct A { + t: T, + } + + impl A { + fn new>(v: V) -> Self { + Self { t: Into::into(v) } + } + } + + impl A { + fn test() -> Self { + A::new::(submod::B {}) + } + } +} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 80e1bfc75e80a..37dfef7cfe0e5 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -1,5 +1,5 @@ error: unnecessary structure name repetition - --> $DIR/use_self.rs:14:21 + --> $DIR/use_self.rs:18:21 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -7,158 +7,172 @@ LL | fn new() -> Foo { = note: `-D clippy::use-self` implied by `-D warnings` error: unnecessary structure name repetition - --> $DIR/use_self.rs:15:13 + --> $DIR/use_self.rs:19:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:17:22 + --> $DIR/use_self.rs:21:22 | LL | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:18:13 + --> $DIR/use_self.rs:22:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:23:25 + --> $DIR/use_self.rs:27:25 | LL | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:24:13 + --> $DIR/use_self.rs:28:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:90:56 + --> $DIR/use_self.rs:93:24 | -LL | fn bad(foos: &[Self]) -> impl Iterator { - | ^^^ help: use the applicable keyword: `Self` +LL | fn bad(foos: &[Foo]) -> impl Iterator { + | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:105:13 + --> $DIR/use_self.rs:93:55 + | +LL | fn bad(foos: &[Foo]) -> impl Iterator { + | ^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> $DIR/use_self.rs:108:13 | LL | TS(0) | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:113:25 - | -LL | fn new() -> Foo { - | ^^^ help: use the applicable keyword: `Self` -... -LL | use_self_expand!(); // Should lint in local macros - | ------------------- in this macro invocation + --> $DIR/use_self.rs:143:29 | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) +LL | fn bar() -> Bar { + | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:114:17 - | -LL | Foo {} - | ^^^ help: use the applicable keyword: `Self` -... -LL | use_self_expand!(); // Should lint in local macros - | ------------------- in this macro invocation + --> $DIR/use_self.rs:144:21 | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) +LL | Bar { foo: Foo {} } + | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:149:21 + --> $DIR/use_self.rs:155:21 | LL | fn baz() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:150:13 + --> $DIR/use_self.rs:156:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:137:29 - | -LL | fn bar() -> Bar { - | ^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> $DIR/use_self.rs:138:21 - | -LL | Bar { foo: Foo {} } - | ^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> $DIR/use_self.rs:167:21 + --> $DIR/use_self.rs:173:21 | LL | let _ = Enum::B(42); | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:168:21 + --> $DIR/use_self.rs:174:21 | LL | let _ = Enum::C { field: true }; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:169:21 + --> $DIR/use_self.rs:175:21 | LL | let _ = Enum::A; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:200:13 + --> $DIR/use_self.rs:217:13 | LL | nested::A::fun_1(); | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:201:13 + --> $DIR/use_self.rs:218:13 | LL | nested::A::A; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:203:13 + --> $DIR/use_self.rs:220:13 | LL | nested::A {}; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:222:13 + --> $DIR/use_self.rs:239:13 | LL | TestStruct::from_something() | ^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:236:25 + --> $DIR/use_self.rs:253:25 | LL | async fn g() -> S { | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:237:13 + --> $DIR/use_self.rs:254:13 | LL | S {} | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:241:16 + --> $DIR/use_self.rs:258:16 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:241:22 + --> $DIR/use_self.rs:258:22 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` -error: aborting due to 25 previous errors +error: unnecessary structure name repetition + --> $DIR/use_self.rs:281:29 + | +LL | fn foo(value: T) -> Foo { + | ^^^^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> $DIR/use_self.rs:282:13 + | +LL | Foo { value } + | ^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> $DIR/use_self.rs:319:21 + | +LL | type From = T::From; + | ^^^^^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> $DIR/use_self.rs:320:19 + | +LL | type To = T::To; + | ^^^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> $DIR/use_self.rs:457:13 + | +LL | A::new::(submod::B {}) + | ^ help: use the applicable keyword: `Self` + +error: aborting due to 29 previous errors diff --git a/tests/ui/use_self_trait.fixed b/tests/ui/use_self_trait.fixed index 1582ae114bf4c..9bcd692fb3511 100644 --- a/tests/ui/use_self_trait.fixed +++ b/tests/ui/use_self_trait.fixed @@ -47,7 +47,8 @@ impl Mul for Bad { impl Clone for Bad { fn clone(&self) -> Self { - Self + // FIXME: applicable here + Bad } } diff --git a/tests/ui/use_self_trait.rs b/tests/ui/use_self_trait.rs index 70667b9797e76..de305d40f330b 100644 --- a/tests/ui/use_self_trait.rs +++ b/tests/ui/use_self_trait.rs @@ -47,6 +47,7 @@ impl Mul for Bad { impl Clone for Bad { fn clone(&self) -> Self { + // FIXME: applicable here Bad } } diff --git a/tests/ui/use_self_trait.stderr b/tests/ui/use_self_trait.stderr index 4f2506cc1192f..55af3ff2a93d9 100644 --- a/tests/ui/use_self_trait.stderr +++ b/tests/ui/use_self_trait.stderr @@ -84,11 +84,5 @@ error: unnecessary structure name repetition LL | fn mul(self, rhs: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` -error: unnecessary structure name repetition - --> $DIR/use_self_trait.rs:50:9 - | -LL | Bad - | ^^^ help: use the applicable keyword: `Self` - -error: aborting due to 15 previous errors +error: aborting due to 14 previous errors diff --git a/tests/ui/vec_init_then_push.rs b/tests/ui/vec_init_then_push.rs index 642ce5040096e..5099aad83bcbc 100644 --- a/tests/ui/vec_init_then_push.rs +++ b/tests/ui/vec_init_then_push.rs @@ -12,10 +12,35 @@ fn main() { cap_err.push(0); cap_err.push(1); cap_err.push(2); + if true { + // don't include this one + cap_err.push(3); + } let mut cap_ok = Vec::with_capacity(10); cap_ok.push(0); new_err = Vec::new(); new_err.push(0); + + let mut vec = Vec::new(); + // control flow at block final expression + if true { + // no lint + vec.push(1); + } +} + +pub fn no_lint() -> Vec { + let mut p = Some(1); + let mut vec = Vec::new(); + loop { + match p { + None => return vec, + Some(i) => { + vec.push(i); + p = None; + }, + } + } } diff --git a/tests/ui/vec_init_then_push.stderr b/tests/ui/vec_init_then_push.stderr index 819ed47d09919..9ec3e10e62470 100644 --- a/tests/ui/vec_init_then_push.stderr +++ b/tests/ui/vec_init_then_push.stderr @@ -24,7 +24,7 @@ LL | | cap_err.push(2); | |____________________^ help: consider using the `vec![]` macro: `let mut cap_err = vec![..];` error: calls to `push` immediately after creation - --> $DIR/vec_init_then_push.rs:19:5 + --> $DIR/vec_init_then_push.rs:23:5 | LL | / new_err = Vec::new(); LL | | new_err.push(0); diff --git a/tests/versioncheck.rs b/tests/versioncheck.rs index bc5ed0816cc81..1c954c57a8549 100644 --- a/tests/versioncheck.rs +++ b/tests/versioncheck.rs @@ -2,21 +2,24 @@ use rustc_tools_util::VersionInfo; #[test] -fn check_that_clippy_lints_has_the_same_version_as_clippy() { +fn check_that_clippy_lints_and_clippy_utils_have_the_same_version_as_clippy() { let clippy_meta = cargo_metadata::MetadataCommand::new() .no_deps() .exec() .expect("could not obtain cargo metadata"); - std::env::set_current_dir(std::env::current_dir().unwrap().join("clippy_lints")).unwrap(); - let clippy_lints_meta = cargo_metadata::MetadataCommand::new() - .no_deps() - .exec() - .expect("could not obtain cargo metadata"); - assert_eq!(clippy_lints_meta.packages[0].version, clippy_meta.packages[0].version); - for package in &clippy_meta.packages[0].dependencies { - if package.name == "clippy_lints" { - assert!(package.req.matches(&clippy_lints_meta.packages[0].version)); - return; + + for krate in &["clippy_lints", "clippy_utils"] { + let krate_meta = clippy_meta + .packages + .iter() + .find(|package| package.name == *krate) + .expect("could not obtain cargo metadata"); + assert_eq!(krate_meta.version, clippy_meta.packages[0].version); + for package in &clippy_meta.packages[0].dependencies { + if package.name == *krate { + assert!(package.req.matches(&krate_meta.version)); + break; + } } } } From b303f7d6f9bcd3f0fbb7c3cec5dc3e0afdc84ac4 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 25 Feb 2021 11:25:45 +0100 Subject: [PATCH 005/226] Fix Clippy build and test --- Cargo.toml | 3 --- tests/versioncheck.rs | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1d6bf1ea0eb96..ea32a8edd1ffb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,6 @@ build = "build.rs" edition = "2018" publish = false -[workspace] -exclude = ["clippy_dev", "mini-macro", "target/lintcheck/crates"] - [[bin]] name = "cargo-clippy" test = false diff --git a/tests/versioncheck.rs b/tests/versioncheck.rs index 1c954c57a8549..922a8207cea86 100644 --- a/tests/versioncheck.rs +++ b/tests/versioncheck.rs @@ -3,6 +3,12 @@ use rustc_tools_util::VersionInfo; #[test] fn check_that_clippy_lints_and_clippy_utils_have_the_same_version_as_clippy() { + // do not run this test inside the upstream rustc repo: + // https://github.com/rust-lang/rust-clippy/issues/6683 + if option_env!("RUSTC_TEST_SUITE").is_some() { + return; + } + let clippy_meta = cargo_metadata::MetadataCommand::new() .no_deps() .exec() From 2f0e9f7d3afb3cb169e58d65261f04215b017561 Mon Sep 17 00:00:00 2001 From: Mateusz Gacek <96mateusz.gacek@gmail.com> Date: Wed, 24 Feb 2021 21:06:26 +0100 Subject: [PATCH 006/226] or_fun_call: fix suggestion for `or_insert(vec![])` Applies for `std::collections::hash_map::Entry` and `std::collections::btree_map::Entry` Example: Previously, for the following code: `let _ = hash_map.entry("test".to_owned()).or_insert(vec![]);` clippy would suggest to use: `or_insert_with(vec![])`, which causes a compiler error (E0277). Now clippy suggests: `or_insert_with(Vec::new)` --- clippy_lints/src/methods/mod.rs | 16 +++++++++++++++- tests/ui/or_fun_call.fixed | 6 ++++++ tests/ui/or_fun_call.rs | 6 ++++++ tests/ui/or_fun_call.stderr | 26 +++++++++++++++++++------- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 433f513b1a8bf..26878d5bba928 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2005,12 +2005,26 @@ fn lint_or_fun_call<'tcx>( if poss.contains(&name); then { + let macro_expanded_snipped; let sugg: Cow<'_, str> = { let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) { (false, Some(fun_span)) => (fun_span, false), _ => (arg.span, true), }; - let snippet = snippet_with_macro_callsite(cx, snippet_span, ".."); + let snippet = { + let not_macro_argument_snippet = snippet_with_macro_callsite(cx, snippet_span, ".."); + if not_macro_argument_snippet == "vec![]" { + macro_expanded_snipped = snippet(cx, snippet_span, ".."); + match macro_expanded_snipped.strip_prefix("$crate::vec::") { + Some(stripped) => Cow::from(stripped), + None => macro_expanded_snipped + } + } + else { + not_macro_argument_snippet + } + }; + if use_lambda { let l_arg = if fn_has_arguments { "_" } else { "" }; format!("|{}| {}", l_arg, snippet).into() diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index 2a63318c8c7a8..64347cae5da38 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -62,9 +62,15 @@ fn or_fun_call() { let mut map = HashMap::::new(); map.entry(42).or_insert_with(String::new); + let mut map_vec = HashMap::>::new(); + map_vec.entry(42).or_insert_with(Vec::new); + let mut btree = BTreeMap::::new(); btree.entry(42).or_insert_with(String::new); + let mut btree_vec = BTreeMap::>::new(); + btree_vec.entry(42).or_insert_with(Vec::new); + let stringy = Some(String::from("")); let _ = stringy.unwrap_or_else(|| "".to_owned()); diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 026ef437caa1a..7faab0017b2e8 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -62,9 +62,15 @@ fn or_fun_call() { let mut map = HashMap::::new(); map.entry(42).or_insert(String::new()); + let mut map_vec = HashMap::>::new(); + map_vec.entry(42).or_insert(vec![]); + let mut btree = BTreeMap::::new(); btree.entry(42).or_insert(String::new()); + let mut btree_vec = BTreeMap::>::new(); + btree_vec.entry(42).or_insert(vec![]); + let stringy = Some(String::from("")); let _ = stringy.unwrap_or("".to_owned()); diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index fb8bf339828f4..1e2bfd490e099 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -67,40 +67,52 @@ LL | map.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)` error: use of `or_insert` followed by a function call - --> $DIR/or_fun_call.rs:66:21 + --> $DIR/or_fun_call.rs:66:23 + | +LL | map_vec.entry(42).or_insert(vec![]); + | ^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(Vec::new)` + +error: use of `or_insert` followed by a function call + --> $DIR/or_fun_call.rs:69:21 | LL | btree.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)` +error: use of `or_insert` followed by a function call + --> $DIR/or_fun_call.rs:72:25 + | +LL | btree_vec.entry(42).or_insert(vec![]); + | ^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(Vec::new)` + error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:69:21 + --> $DIR/or_fun_call.rs:75:21 | LL | let _ = stringy.unwrap_or("".to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:77:21 + --> $DIR/or_fun_call.rs:83:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| map[&1])` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:79:21 + --> $DIR/or_fun_call.rs:85:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| map[&1])` error: use of `or` followed by a function call - --> $DIR/or_fun_call.rs:103:35 + --> $DIR/or_fun_call.rs:109:35 | LL | let _ = Some("a".to_string()).or(Some("b".to_string())); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some("b".to_string()))` error: use of `or` followed by a function call - --> $DIR/or_fun_call.rs:107:10 + --> $DIR/or_fun_call.rs:113:10 | LL | .or(Some(Bar(b, Duration::from_secs(2)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some(Bar(b, Duration::from_secs(2))))` -error: aborting due to 17 previous errors +error: aborting due to 19 previous errors From cbe6eec3e67347af130769ad4a3bd2168997b411 Mon Sep 17 00:00:00 2001 From: Marc Dominik Migge Date: Thu, 25 Feb 2021 22:03:11 +0100 Subject: [PATCH 007/226] Add original test case from issue --- tests/ui/unit_arg.rs | 21 +++++++++++++++++++++ tests/ui/unit_arg.stderr | 20 ++++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index 5ea2e5d65c515..938cc3c785978 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -31,6 +31,26 @@ fn baz(t: T) { foo(t); } +trait Tr { + type Args; + fn do_it(args: Self::Args); +} + +struct A; +impl Tr for A { + type Args = (); + fn do_it(_: Self::Args) {} +} + +struct B; +impl Tr for B { + type Args = ::Args; + + fn do_it(args: Self::Args) { + A::do_it(args) + } +} + fn bad() { foo({ 1; @@ -78,6 +98,7 @@ fn ok() { let named_unit_arg = (); foo(named_unit_arg); baz(()); + B::do_it(()); } fn question_mark() -> Result<(), ()> { diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr index b3fe9addb62f6..354fd51cd6b60 100644 --- a/tests/ui/unit_arg.stderr +++ b/tests/ui/unit_arg.stderr @@ -1,5 +1,5 @@ error: passing a unit value to a function - --> $DIR/unit_arg.rs:35:5 + --> $DIR/unit_arg.rs:55:5 | LL | / foo({ LL | | 1; @@ -20,7 +20,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:38:5 + --> $DIR/unit_arg.rs:58:5 | LL | foo(foo(1)); | ^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:39:5 + --> $DIR/unit_arg.rs:59:5 | LL | / foo({ LL | | foo(1); @@ -54,7 +54,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:44:5 + --> $DIR/unit_arg.rs:64:5 | LL | / b.bar({ LL | | 1; @@ -74,7 +74,7 @@ LL | b.bar(()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:47:5 + --> $DIR/unit_arg.rs:67:5 | LL | taking_multiple_units(foo(0), foo(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -87,7 +87,7 @@ LL | taking_multiple_units((), ()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:48:5 + --> $DIR/unit_arg.rs:68:5 | LL | / taking_multiple_units(foo(0), { LL | | foo(1); @@ -110,7 +110,7 @@ LL | taking_multiple_units((), ()); | error: passing unit values to a function - --> $DIR/unit_arg.rs:52:5 + --> $DIR/unit_arg.rs:72:5 | LL | / taking_multiple_units( LL | | { @@ -140,7 +140,7 @@ LL | foo(2); ... error: passing a unit value to a function - --> $DIR/unit_arg.rs:63:13 + --> $DIR/unit_arg.rs:83:13 | LL | None.or(Some(foo(2))); | ^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | }); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:66:5 + --> $DIR/unit_arg.rs:86:5 | LL | foo(foo(())); | ^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | foo(()); | error: passing a unit value to a function - --> $DIR/unit_arg.rs:102:5 + --> $DIR/unit_arg.rs:123:5 | LL | Some(foo(1)) | ^^^^^^^^^^^^ From 5dbd45cbc1c213a4e796a85b281f5bc397bf9000 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Thu, 25 Feb 2021 19:51:49 -0600 Subject: [PATCH 008/226] Improve needless_borrowed_ref docs --- clippy_lints/src/needless_borrowed_ref.rs | 47 +++++++++-------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index 85184fdea4779..f449f397e7d61 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -1,7 +1,3 @@ -//! Checks for useless borrowed references. -//! -//! This lint is **warn** by default - use crate::utils::{snippet_with_applicability, span_lint_and_then}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -10,44 +6,37 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// **What it does:** Checks for useless borrowed references. - /// - /// **Why is this bad?** It is mostly useless and make the code look more - /// complex than it - /// actually is. + /// **What it does:** Checks for bindings that destructure a reference and borrow the inner + /// value with `&ref`. /// - /// **Known problems:** It seems that the `&ref` pattern is sometimes useful. - /// For instance in the following snippet: - /// ```rust,ignore - /// enum Animal { - /// Cat(u64), - /// Dog(u64), - /// } + /// **Why is this bad?** This pattern has no effect in almost all cases. /// - /// fn foo(a: &Animal, b: &Animal) { + /// **Known problems:** In some cases, `&ref` is needed to avoid a lifetime mismatch error. + /// Example: + /// ```rust + /// fn foo(a: &Option, b: &Option) { /// match (a, b) { - /// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime mismatch error - /// (&Animal::Dog(ref c), &Animal::Dog(_)) => () - /// } + /// (None, &ref c) | (&ref c, None) => (), + /// (&Some(ref c), _) => (), + /// }; /// } /// ``` - /// There is a lifetime mismatch error for `k` (indeed a and b have distinct - /// lifetime). - /// This can be fixed by using the `&ref` pattern. - /// However, the code can also be fixed by much cleaner ways /// /// **Example:** + /// Bad: /// ```rust /// let mut v = Vec::::new(); /// let _ = v.iter_mut().filter(|&ref a| a.is_empty()); /// ``` - /// This closure takes a reference on something that has been matched as a - /// reference and - /// de-referenced. - /// As such, it could just be |a| a.is_empty() + /// + /// Good: + /// ```rust + /// let mut v = Vec::::new(); + /// let _ = v.iter_mut().filter(|a| a.is_empty()); + /// ``` pub NEEDLESS_BORROWED_REFERENCE, complexity, - "taking a needless borrowed reference" + "destructuring a reference and borrowing the inner value" } declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]); From 8f47a4214e66b67bbcbcc0a1c1fd3f3d481ed85e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 25 Feb 2021 20:31:24 -0800 Subject: [PATCH 009/226] Downgrade manual_map to nursery --- clippy_lints/src/lib.rs | 3 +-- clippy_lints/src/manual_map.rs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 176eeadcc630a..faec9ec31f32c 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1540,7 +1540,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&loops::WHILE_LET_ON_ITERATOR), LintId::of(&main_recursion::MAIN_RECURSION), LintId::of(&manual_async_fn::MANUAL_ASYNC_FN), - LintId::of(&manual_map::MANUAL_MAP), LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE), LintId::of(&manual_strip::MANUAL_STRIP), LintId::of(&manual_unwrap_or::MANUAL_UNWRAP_OR), @@ -1771,7 +1770,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&loops::WHILE_LET_ON_ITERATOR), LintId::of(&main_recursion::MAIN_RECURSION), LintId::of(&manual_async_fn::MANUAL_ASYNC_FN), - LintId::of(&manual_map::MANUAL_MAP), LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE), LintId::of(&map_clone::MAP_CLONE), LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH), @@ -2047,6 +2045,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&floating_point_arithmetic::SUBOPTIMAL_FLOPS), LintId::of(&future_not_send::FUTURE_NOT_SEND), LintId::of(&let_if_seq::USELESS_LET_IF_SEQ), + LintId::of(&manual_map::MANUAL_MAP), LintId::of(&missing_const_for_fn::MISSING_CONST_FOR_FN), LintId::of(&mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL), LintId::of(&mutex_atomic::MUTEX_INTEGER), diff --git a/clippy_lints/src/manual_map.rs b/clippy_lints/src/manual_map.rs index a50a3943bab7b..78dc0d54f28d3 100644 --- a/clippy_lints/src/manual_map.rs +++ b/clippy_lints/src/manual_map.rs @@ -19,7 +19,7 @@ declare_clippy_lint! { /// /// **Why is this bad?** Using the `map` method is clearer and more concise. /// - /// **Known problems:** None. + /// **Known problems:** `map` is not capable of representing some control flow which works fine in `match`. /// /// **Example:** /// @@ -34,7 +34,7 @@ declare_clippy_lint! { /// Some(0).map(|x| x + 1); /// ``` pub MANUAL_MAP, - style, + nursery, "reimplementation of `map`" } From 12dc03033f9d441f1382a7684480c4a863b33bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 23 Feb 2021 21:27:32 +0100 Subject: [PATCH 010/226] lintcheck: fix bug when getting the config toml path. In order to check if we need to recheck crates, I was getting the path from clap only which is None if we don't pass it via cmdline args. Use the dedicated lintcheck_config_toml() fnuction instead! --- clippy_dev/src/lintcheck.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index b806f54528465..a4e6fe76c3222 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -336,8 +336,8 @@ fn build_clippy() { } /// Read a `toml` file and return a list of `CrateSources` that we want to check with clippy -fn read_crates(toml_path: Option<&str>) -> (String, Vec) { - let toml_path = lintcheck_config_toml(toml_path); +fn read_crates(clap_toml_path: Option<&str>) -> (String, Vec) { + let toml_path = lintcheck_config_toml(clap_toml_path); // save it so that we can use the name of the sources.toml as name for the logfile later. let toml_filename = toml_path.file_stem().unwrap().to_str().unwrap().to_string(); let toml_content: String = @@ -478,7 +478,8 @@ pub fn run(clap_config: &ArgMatches) { build_clippy(); println!("Done compiling"); - let clap_toml_path = clap_config.value_of("crates-toml"); + let clap_toml_path: Option<&str> = clap_config.value_of("crates-toml"); + let toml_path = lintcheck_config_toml(clap_toml_path); // if the clippy bin is newer than our logs, throw away target dirs to force clippy to // refresh the logs From 3e1eea6c97ea71c43ebde4a171e5085947634155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 23 Feb 2021 21:23:36 +0100 Subject: [PATCH 011/226] lintcheck: print stats how lint counts have changed between runs --- clippy_dev/src/lintcheck.rs | 118 ++++++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 18 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index a4e6fe76c3222..601e88387b982 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -336,8 +336,7 @@ fn build_clippy() { } /// Read a `toml` file and return a list of `CrateSources` that we want to check with clippy -fn read_crates(clap_toml_path: Option<&str>) -> (String, Vec) { - let toml_path = lintcheck_config_toml(clap_toml_path); +fn read_crates(toml_path: &PathBuf) -> (String, Vec) { // save it so that we can use the name of the sources.toml as name for the logfile later. let toml_filename = toml_path.file_stem().unwrap().to_str().unwrap().to_string(); let toml_content: String = @@ -428,7 +427,7 @@ fn parse_json_message(json_message: &str, krate: &Crate) -> ClippyWarning { } /// Generate a short list of occuring lints-types and their count -fn gather_stats(clippy_warnings: &[ClippyWarning]) -> String { +fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String, usize>) { // count lint type occurrences let mut counter: HashMap<&String, usize> = HashMap::new(); clippy_warnings @@ -441,15 +440,17 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> String { // to not have a lint with 200 and 2 warnings take the same spot stats.sort_by_key(|(lint, count)| format!("{:0>4}, {}", count, lint)); - stats + let stats_string = stats .iter() .map(|(lint, count)| format!("{} {}\n", lint, count)) - .collect::() + .collect::(); + + (stats_string, counter) } /// check if the latest modification of the logfile is older than the modification date of the /// clippy binary, if this is true, we should clean the lintchec shared target directory and recheck -fn lintcheck_needs_rerun(toml_path: Option<&str>) -> bool { +fn lintcheck_needs_rerun(toml_path: &PathBuf) -> bool { let clippy_modified: std::time::SystemTime = { let mut times = ["target/debug/clippy-driver", "target/debug/cargo-clippy"] .iter() @@ -459,17 +460,18 @@ fn lintcheck_needs_rerun(toml_path: Option<&str>) -> bool { .modified() .expect("failed to get modification date") }); - // the lates modification of either of the binaries - std::cmp::max(times.next().unwrap(), times.next().unwrap()) + // the oldest modification of either of the binaries + std::cmp::min(times.next().unwrap(), times.next().unwrap()) }; - let logs_modified: std::time::SystemTime = std::fs::metadata(lintcheck_config_toml(toml_path)) + let logs_modified: std::time::SystemTime = std::fs::metadata(toml_path) .expect("failed to get metadata of file") .modified() .expect("failed to get modification date"); - // if clippys modification time is bigger (older) than the logs mod time, we need to rerun lintcheck - clippy_modified > logs_modified + // if clippys modification time is smaller (older) than the logs mod time, we need to rerun + // lintcheck + dbg!(clippy_modified < logs_modified) } /// lintchecks `main()` function @@ -479,11 +481,11 @@ pub fn run(clap_config: &ArgMatches) { println!("Done compiling"); let clap_toml_path: Option<&str> = clap_config.value_of("crates-toml"); - let toml_path = lintcheck_config_toml(clap_toml_path); + let toml_path: PathBuf = lintcheck_config_toml(clap_toml_path); // if the clippy bin is newer than our logs, throw away target dirs to force clippy to // refresh the logs - if lintcheck_needs_rerun(clap_toml_path) { + if dbg!(lintcheck_needs_rerun(&toml_path)) { let shared_target_dir = "target/lintcheck/shared_target_dir"; match std::fs::metadata(&shared_target_dir) { Ok(metadata) => { @@ -518,7 +520,9 @@ pub fn run(clap_config: &ArgMatches) { // download and extract the crates, then run clippy on them and collect clippys warnings // flatten into one big list of warnings - let (filename, crates) = read_crates(clap_toml_path); + let (filename, crates) = read_crates(&toml_path); + let file = format!("lintcheck-logs/{}_logs.txt", filename); + let old_stats = read_stats_from_file(&file); let clippy_warnings: Vec = if let Some(only_one_crate) = clap_config.value_of("only") { // if we don't have the specified crate in the .toml, throw an error @@ -587,7 +591,7 @@ pub fn run(clap_config: &ArgMatches) { }; // generate some stats - let stats_formatted = gather_stats(&clippy_warnings); + let (stats_formatted, new_stats) = gather_stats(&clippy_warnings); // grab crashes/ICEs, save the crate name and the ice message let ices: Vec<(&String, &String)> = clippy_warnings @@ -598,7 +602,7 @@ pub fn run(clap_config: &ArgMatches) { let mut all_msgs: Vec = clippy_warnings.iter().map(|warning| warning.to_string()).collect(); all_msgs.sort(); - all_msgs.push("\n\n\n\nStats\n\n".into()); + all_msgs.push("\n\n\n\nStats:\n".into()); all_msgs.push(stats_formatted); // save the text into lintcheck-logs/logs.txt @@ -608,7 +612,85 @@ pub fn run(clap_config: &ArgMatches) { ices.iter() .for_each(|(cratename, msg)| text.push_str(&format!("{}: '{}'", cratename, msg))); - let file = format!("lintcheck-logs/{}_logs.txt", filename); println!("Writing logs to {}", file); - write(file, text).unwrap(); + write(&file, text).unwrap(); + + print_stats(old_stats, new_stats); +} + +/// read the previous stats from the lintcheck-log file +fn read_stats_from_file(file_path: &String) -> HashMap { + let file_path = PathBuf::from(file_path); + dbg!(&file_path); + let file_content: String = match std::fs::read_to_string(file_path).ok() { + Some(content) => content, + None => { + eprintln!("RETURND"); + return HashMap::new(); + }, + }; + + let lines: Vec = file_content.lines().map(|l| l.to_string()).collect(); + + // search for the beginning "Stats:" and the end "ICEs:" of the section we want + let start = lines.iter().position(|line| line == "Stats:").unwrap(); + let end = lines.iter().position(|line| line == "ICEs:").unwrap(); + + let stats_lines = &lines[start + 1..=end - 1]; + + stats_lines + .into_iter() + .map(|line| { + let mut spl = line.split(" ").into_iter(); + ( + spl.next().unwrap().to_string(), + spl.next().unwrap().parse::().unwrap(), + ) + }) + .collect::>() +} + +/// print how lint counts changed between runs +fn print_stats(old_stats: HashMap, new_stats: HashMap<&String, usize>) { + let same_in_both_hashmaps = old_stats + .iter() + .filter(|(old_key, old_val)| new_stats.get::<&String>(&old_key) == Some(old_val)) + .map(|(k, v)| (k.to_string(), *v)) + .collect::>(); + + let mut old_stats_deduped = old_stats; + let mut new_stats_deduped = new_stats; + + // remove duplicates from both hashmaps + same_in_both_hashmaps.iter().for_each(|(k, v)| { + assert!(old_stats_deduped.remove(k) == Some(*v)); + assert!(new_stats_deduped.remove(k) == Some(*v)); + }); + + println!("\nStats:"); + + // list all new counts (key is in new stats but not in old stats) + new_stats_deduped + .iter() + .filter(|(new_key, _)| old_stats_deduped.get::(&new_key).is_none()) + .for_each(|(new_key, new_value)| { + println!("{} 0 => {}", new_key, new_value); + }); + + // list all changed counts (key is in both maps but value differs) + new_stats_deduped + .iter() + .filter(|(new_key, _new_val)| old_stats_deduped.get::(&new_key).is_some()) + .for_each(|(new_key, new_val)| { + let old_val = old_stats_deduped.get::(&new_key).unwrap(); + println!("{} {} => {}", new_key, old_val, new_val); + }); + + // list all gone counts (key is in old status but not in new stats) + old_stats_deduped + .iter() + .filter(|(old_key, _)| new_stats_deduped.get::<&String>(&old_key).is_none()) + .for_each(|(old_key, old_value)| { + println!("{} {} => 0", old_key, old_value); + }); } From 90cf27e9f6f4573ff1938744e87dab9f413002a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 26 Feb 2021 11:18:59 +0100 Subject: [PATCH 012/226] lintcheck: update logs and do minor fixes --- clippy_dev/src/lintcheck.rs | 5 ++-- lintcheck-logs/lintcheck_crates_logs.txt | 36 +++++++++++------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 601e88387b982..65e438bc0e8d6 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -471,7 +471,7 @@ fn lintcheck_needs_rerun(toml_path: &PathBuf) -> bool { // if clippys modification time is smaller (older) than the logs mod time, we need to rerun // lintcheck - dbg!(clippy_modified < logs_modified) + clippy_modified < logs_modified } /// lintchecks `main()` function @@ -485,7 +485,7 @@ pub fn run(clap_config: &ArgMatches) { // if the clippy bin is newer than our logs, throw away target dirs to force clippy to // refresh the logs - if dbg!(lintcheck_needs_rerun(&toml_path)) { + if lintcheck_needs_rerun(&toml_path) { let shared_target_dir = "target/lintcheck/shared_target_dir"; match std::fs::metadata(&shared_target_dir) { Ok(metadata) => { @@ -621,7 +621,6 @@ pub fn run(clap_config: &ArgMatches) { /// read the previous stats from the lintcheck-log file fn read_stats_from_file(file_path: &String) -> HashMap { let file_path = PathBuf::from(file_path); - dbg!(&file_path); let file_content: String = match std::fs::read_to_string(file_path).ok() { Some(content) => content, None => { diff --git a/lintcheck-logs/lintcheck_crates_logs.txt b/lintcheck-logs/lintcheck_crates_logs.txt index c23dd926f621d..e3aeb76657f26 100644 --- a/lintcheck-logs/lintcheck_crates_logs.txt +++ b/lintcheck-logs/lintcheck_crates_logs.txt @@ -1,4 +1,4 @@ -clippy 0.1.52 (697f3b6d4 2021-02-22) +clippy 0.1.52 (5c6cd87b9 2021-02-25) cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" @@ -77,6 +77,7 @@ cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multi cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" cargo-0.49.0/src/bin/cargo/main.rs:72:22 clippy::redundant_closure_for_method_calls "redundant closure found" +cargo-0.49.0/src/bin/cargo/main.rs:79:40 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/bin/cargo/main.rs:94:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" cargo-0.49.0/src/bin/cargo/main.rs:96:41 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/bin/cargo/main.rs:98:60 clippy::redundant_closure_for_method_calls "redundant closure found" @@ -199,6 +200,7 @@ cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1966:22 clippy::cast_possibl cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:17 clippy::similar_names "binding's name is too similar to existing binding" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:24 clippy::manual_strip "stripping a prefix manually" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1986:17 clippy::similar_names "binding's name is too similar to existing binding" +cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1986:27 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:2016:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:61:5 clippy::doc_markdown "you should put `CompileMode` between ticks in the documentation" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:63:12 clippy::doc_markdown "you should put `CompileKind` between ticks in the documentation" @@ -480,6 +482,7 @@ cargo-0.49.0/src/cargo/core/package_id_spec.rs:212:9 clippy::items_after_stateme cargo-0.49.0/src/cargo/core/package_id_spec.rs:231:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +cargo-0.49.0/src/cargo/core/package_id_spec.rs:64:23 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/core/package_id_spec.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/package_id_spec.rs:88:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/core/profiles.rs:1004:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -757,6 +760,7 @@ cargo-0.49.0/src/cargo/core/workspace.rs:329:37 clippy::doc_markdown "you should cargo-0.49.0/src/cargo/core/workspace.rs:410:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/workspace.rs:440:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" cargo-0.49.0/src/cargo/core/workspace.rs:511:32 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +cargo-0.49.0/src/cargo/core/workspace.rs:531:13 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/core/workspace.rs:561:25 clippy::non_ascii_literal "literal non-ASCII character detected" cargo-0.49.0/src/cargo/core/workspace.rs:613:13 clippy::filter_map "called `filter_map(..).map(..)` on an `Iterator`" cargo-0.49.0/src/cargo/core/workspace.rs:615:22 clippy::redundant_closure_for_method_calls "redundant closure found" @@ -1001,6 +1005,7 @@ cargo-0.49.0/src/cargo/sources/directory.rs:14:1 clippy::module_name_repetitions cargo-0.49.0/src/cargo/sources/directory.rs:90:56 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/cargo/sources/git/source.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name" cargo-0.49.0/src/cargo/sources/git/source.rs:25:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +cargo-0.49.0/src/cargo/sources/git/source.rs:34:25 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/sources/git/source.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" @@ -1008,7 +1013,6 @@ cargo-0.49.0/src/cargo/sources/git/source.rs:69:20 clippy::comparison_to_empty " cargo-0.49.0/src/cargo/sources/git/utils.rs:1025:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" cargo-0.49.0/src/cargo/sources/git/utils.rs:1157:36 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" cargo-0.49.0/src/cargo/sources/git/utils.rs:1158:9 clippy::manual_strip "stripping a suffix manually" -cargo-0.49.0/src/cargo/sources/git/utils.rs:134:12 clippy::upper_case_acronyms "name `GitShortID` contains a capitalized acronym" cargo-0.49.0/src/cargo/sources/git/utils.rs:176:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/sources/git/utils.rs:180:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/sources/git/utils.rs:184:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1061,6 +1065,7 @@ cargo-0.49.0/src/cargo/sources/registry/local.rs:12:1 clippy::module_name_repeti cargo-0.49.0/src/cargo/sources/registry/mod.rs:192:1 clippy::module_name_repetitions "item name starts with its containing module's name" cargo-0.49.0/src/cargo/sources/registry/mod.rs:203:1 clippy::module_name_repetitions "item name starts with its containing module's name" cargo-0.49.0/src/cargo/sources/registry/mod.rs:229:1 clippy::module_name_repetitions "item name starts with its containing module's name" +cargo-0.49.0/src/cargo/sources/registry/mod.rs:340:24 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/sources/registry/mod.rs:372:1 clippy::module_name_repetitions "item name starts with its containing module's name" cargo-0.49.0/src/cargo/sources/registry/mod.rs:373:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/sources/registry/mod.rs:375:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1085,6 +1090,7 @@ cargo-0.49.0/src/cargo/util/command_prelude.rs:222:1 clippy::must_use_candidate cargo-0.49.0/src/cargo/util/command_prelude.rs:234:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/command_prelude.rs:249:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/command_prelude.rs:264:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +cargo-0.49.0/src/cargo/util/command_prelude.rs:265:19 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/command_prelude.rs:279:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/command_prelude.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/command_prelude.rs:320:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1166,6 +1172,7 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:1901:5 clippy::doc_markdown "you shoul cargo-0.49.0/src/cargo/util/config/mod.rs:214:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" cargo-0.49.0/src/cargo/util/config/mod.rs:259:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +cargo-0.49.0/src/cargo/util/config/mod.rs:299:12 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/config/mod.rs:311:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:318:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:353:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1183,6 +1190,7 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:689:20 clippy::unused_self "unused `se cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure found" +cargo-0.49.0/src/cargo/util/config/mod.rs:748:30 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/config/mod.rs:816:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/path.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" cargo-0.49.0/src/cargo/util/config/path.rs:14:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -1241,6 +1249,7 @@ cargo-0.49.0/src/cargo/util/flock.rs:335:23 clippy::cast_sign_loss "casting `i64 cargo-0.49.0/src/cargo/util/flock.rs:335:44 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value" cargo-0.49.0/src/cargo/util/flock.rs:379:35 clippy::match_same_arms "this `match` has identical arm bodies" cargo-0.49.0/src/cargo/util/flock.rs:37:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" @@ -1267,6 +1276,7 @@ cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::missing_panics_doc "docs f cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/interning.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/into_url.rs:10:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +cargo-0.49.0/src/cargo/util/into_url_with_base.rs:14:24 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/into_url_with_base.rs:9:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/job.rs:20:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/lev_distance.rs:3:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" @@ -2232,16 +2242,13 @@ rand-0.7.3/src/distributions/uniform.rs:943:54 clippy::cast_possible_truncation rand-0.7.3/src/distributions/unit_circle.rs:30:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" rand-0.7.3/src/distributions/unit_sphere.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name" rand-0.7.3/src/distributions/unit_sphere.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/utils.rs:218:18 clippy::upper_case_acronyms "name `FloatSIMDUtils` contains a capitalized acronym" rand-0.7.3/src/distributions/utils.rs:247:15 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" rand-0.7.3/src/distributions/utils.rs:248:20 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" rand-0.7.3/src/distributions/utils.rs:249:18 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" -rand-0.7.3/src/distributions/utils.rs:253:18 clippy::upper_case_acronyms "name `FloatAsSIMD` contains a capitalized acronym" rand-0.7.3/src/distributions/utils.rs:254:5 clippy::inline_always "you have declared `#[inline(always)]` on `lanes`. This is usually a bad idea" rand-0.7.3/src/distributions/utils.rs:258:5 clippy::inline_always "you have declared `#[inline(always)]` on `splat`. This is usually a bad idea" rand-0.7.3/src/distributions/utils.rs:262:5 clippy::inline_always "you have declared `#[inline(always)]` on `extract`. This is usually a bad idea" rand-0.7.3/src/distributions/utils.rs:267:5 clippy::inline_always "you have declared `#[inline(always)]` on `replace`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:274:18 clippy::upper_case_acronyms "name `BoolAsSIMD` contains a capitalized acronym" rand-0.7.3/src/distributions/utils.rs:281:5 clippy::inline_always "you have declared `#[inline(always)]` on `any`. This is usually a bad idea" rand-0.7.3/src/distributions/utils.rs:286:5 clippy::inline_always "you have declared `#[inline(always)]` on `all`. This is usually a bad idea" rand-0.7.3/src/distributions/utils.rs:291:5 clippy::inline_always "you have declared `#[inline(always)]` on `none`. This is usually a bad idea" @@ -2820,7 +2827,6 @@ regex-1.3.2/src/exec.rs:1270:17 clippy::doc_markdown "you should put `RegexSet` regex-1.3.2/src/exec.rs:1280:17 clippy::doc_markdown "you should put `RegexSet` between ticks in the documentation" regex-1.3.2/src/exec.rs:137:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" regex-1.3.2/src/exec.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:1493:5 clippy::upper_case_acronyms "name `PikeVM` contains a capitalized acronym" regex-1.3.2/src/exec.rs:158:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" regex-1.3.2/src/exec.rs:168:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" regex-1.3.2/src/exec.rs:181:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -2910,10 +2916,8 @@ regex-1.3.2/src/literal/imp.rs:160:30 clippy::match_same_arms "this `match` has regex-1.3.2/src/literal/imp.rs:167:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" regex-1.3.2/src/literal/imp.rs:168:13 clippy::enum_glob_use "usage of wildcard import for enum variants" regex-1.3.2/src/literal/imp.rs:211:20 clippy::redundant_else "redundant else block" -regex-1.3.2/src/literal/imp.rs:239:5 clippy::upper_case_acronyms "name `AC` contains a capitalized acronym" regex-1.3.2/src/literal/imp.rs:276:50 clippy::match_same_arms "this `match` has identical arm bodies" regex-1.3.2/src/literal/imp.rs:342:41 clippy::inline_always "you have declared `#[inline(always)]` on `find`. This is usually a bad idea" -regex-1.3.2/src/literal/imp.rs:34:5 clippy::upper_case_acronyms "name `AC` contains a capitalized acronym" regex-1.3.2/src/literal/imp.rs:435:13 clippy::redundant_field_names "redundant field names in struct initialization" regex-1.3.2/src/literal/imp.rs:436:13 clippy::redundant_field_names "redundant field names in struct initialization" regex-1.3.2/src/literal/imp.rs:437:13 clippy::redundant_field_names "redundant field names in struct initialization" @@ -2954,7 +2958,6 @@ regex-1.3.2/src/pikevm.rs:224:5 clippy::too_many_arguments "this function has to regex-1.3.2/src/pikevm.rs:234:13 clippy::enum_glob_use "usage of wildcard import for enum variants" regex-1.3.2/src/pikevm.rs:303:13 clippy::enum_glob_use "usage of wildcard import for enum variants" regex-1.3.2/src/pikevm.rs:331:29 clippy::mut_mut "this expression mutably borrows a mutable reference. Consider reborrowing" -regex-1.3.2/src/pikevm.rs:70:5 clippy::upper_case_acronyms "name `IP` contains a capitalized acronym" regex-1.3.2/src/pikevm.rs:88:5 clippy::too_many_arguments "this function has too many arguments (8/7)" regex-1.3.2/src/prog.rs:102:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" regex-1.3.2/src/prog.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -3089,8 +3092,6 @@ ripgrep-12.1.1/crates/core/app.rs:156:39 clippy::doc_markdown "you should put `c ripgrep-12.1.1/crates/core/app.rs:156:39 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" ripgrep-12.1.1/crates/core/app.rs:156:5 clippy::doc_markdown "you should put `RGArg` between ticks in the documentation" ripgrep-12.1.1/crates/core/app.rs:156:5 clippy::doc_markdown "you should put `RGArg` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:164:12 clippy::upper_case_acronyms "name `RGArg` contains a capitalized acronym" -ripgrep-12.1.1/crates/core/app.rs:164:12 clippy::upper_case_acronyms "name `RGArg` contains a capitalized acronym" ripgrep-12.1.1/crates/core/app.rs:1668:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" ripgrep-12.1.1/crates/core/app.rs:1668:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" ripgrep-12.1.1/crates/core/app.rs:1669:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" @@ -3099,8 +3100,6 @@ ripgrep-12.1.1/crates/core/app.rs:1821:5 clippy::items_after_statements "adding ripgrep-12.1.1/crates/core/app.rs:1821:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" ripgrep-12.1.1/crates/core/app.rs:1822:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" ripgrep-12.1.1/crates/core/app.rs:1822:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:212:10 clippy::upper_case_acronyms "name `RGArgKind` contains a capitalized acronym" -ripgrep-12.1.1/crates/core/app.rs:212:10 clippy::upper_case_acronyms "name `RGArgKind` contains a capitalized acronym" ripgrep-12.1.1/crates/core/app.rs:2999:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" ripgrep-12.1.1/crates/core/app.rs:2999:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" ripgrep-12.1.1/crates/core/app.rs:3000:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" @@ -3138,7 +3137,6 @@ ripgrep-12.1.1/crates/core/args.rs:410:14 clippy::trivially_copy_pass_by_ref "th ripgrep-12.1.1/crates/core/args.rs:475:18 clippy::match_same_arms "this `match` has identical arm bodies" ripgrep-12.1.1/crates/core/args.rs:512:19 clippy::doc_markdown "you should put `ArgMatches` between ticks in the documentation" ripgrep-12.1.1/crates/core/args.rs:549:16 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" -ripgrep-12.1.1/crates/core/args.rs:71:5 clippy::upper_case_acronyms "name `PCRE2Version` contains a capitalized acronym" ripgrep-12.1.1/crates/core/args.rs:76:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" ripgrep-12.1.1/crates/core/args.rs:77:13 clippy::enum_glob_use "usage of wildcard import for enum variants" ripgrep-12.1.1/crates/core/args.rs:923:42 clippy::doc_markdown "you should put `BinaryDetection::quit` between ticks in the documentation" @@ -3188,8 +3186,8 @@ syn-1.0.54/src/lib.rs:1:null clippy::cargo_common_metadata "package `syn` is mis syn-1.0.54/src/lit.rs:1397:40 clippy::redundant_else "redundant else block" syn-1.0.54/src/lit.rs:1405:28 clippy::redundant_else "redundant else block" syn-1.0.54/src/lit.rs:1485:32 clippy::redundant_else "redundant else block" +syn-1.0.54/src/token.rs:974:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" unicode-xid-0.2.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `unicode-xid` is missing `package.categories` metadata" -unicode-xid-0.2.1/src/lib.rs:56:11 clippy::upper_case_acronyms "name `UnicodeXID` contains a capitalized acronym" unicode-xid-0.2.1/src/lib.rs:57:64 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" unicode-xid-0.2.1/src/lib.rs:60:10 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" unicode-xid-0.2.1/src/lib.rs:62:27 clippy::doc_markdown "you should put `ID_Start` between ticks in the documentation" @@ -3375,8 +3373,7 @@ xsv-0.13.0/src/util.rs:90:1 clippy::needless_lifetimes "explicit lifetimes given -Stats - +Stats: clippy::clone_on_copy 1 clippy::comparison_chain 1 clippy::expect_fun_call 1 @@ -3424,6 +3421,7 @@ clippy::mut_mut 3 clippy::ptr_arg 3 clippy::zero_ptr 3 clippy::too_many_arguments 4 +clippy::upper_case_acronyms 4 clippy::explicit_iter_loop 5 clippy::field_reassign_with_default 5 clippy::identity_op 5 @@ -3445,6 +3443,7 @@ clippy::invalid_upcast_comparisons 8 clippy::needless_question_mark 8 clippy::wrong_self_convention 8 clippy::multiple_crate_versions 9 +clippy::manual_map 10 clippy::manual_range_contains 10 clippy::match_wildcard_for_single_variants 10 clippy::missing_safety_doc 10 @@ -3456,7 +3455,6 @@ clippy::linkedlist 14 clippy::single_char_add_str 14 clippy::option_if_let_else 15 clippy::needless_pass_by_value 18 -clippy::upper_case_acronyms 18 clippy::cast_possible_wrap 19 clippy::cast_sign_loss 19 clippy::unnecessary_wraps 19 @@ -3476,7 +3474,7 @@ clippy::enum_glob_use 40 clippy::unseparated_literal_suffix 41 clippy::cast_precision_loss 44 clippy::single_match_else 45 -clippy::missing_panics_doc 54 +clippy::missing_panics_doc 56 clippy::inline_always 59 clippy::match_same_arms 60 clippy::similar_names 78 From 1368cb34d1b3cbcb6a26f3e337cb94cbe9e8ae5f Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 12:10:24 -0600 Subject: [PATCH 013/226] Revert "Test workspace at once" This reverts commit e355652fec704f307b50d42fb6a08172dc1e08bf. --- .github/workflows/clippy.yml | 12 ++++++++++-- .github/workflows/clippy_bors.yml | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index f6ac936df4d6b..9d5e12aac5f7b 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -53,8 +53,16 @@ jobs: - name: Test "--fix -Zunstable-options" run: cargo run --features deny-warnings,internal-lints --bin cargo-clippy -- clippy --fix -Zunstable-options - - name: Test Workspace - run: cargo test --all --features deny-warnings,internal-lints + - name: Test + run: cargo test --features deny-warnings,internal-lints + + - name: Test clippy_lints + run: cargo test --features deny-warnings,internal-lints + working-directory: clippy_lints + + - name: Test rustc_tools_util + run: cargo test --features deny-warnings + working-directory: rustc_tools_util - name: Test clippy_dev run: cargo test --features deny-warnings diff --git a/.github/workflows/clippy_bors.yml b/.github/workflows/clippy_bors.yml index 9d24b0293c4a7..5d846eb64c78e 100644 --- a/.github/workflows/clippy_bors.yml +++ b/.github/workflows/clippy_bors.yml @@ -112,8 +112,16 @@ jobs: - name: Build run: cargo build --features deny-warnings,internal-lints - - name: Test Workspace - run: cargo test --all --features deny-warnings,internal-lints + - name: Test + run: cargo test --features deny-warnings,internal-lints + + - name: Test clippy_lints + run: cargo test --features deny-warnings,internal-lints + working-directory: clippy_lints + + - name: Test rustc_tools_util + run: cargo test --features deny-warnings + working-directory: rustc_tools_util - name: Test clippy_dev run: cargo test --features deny-warnings From 814b006d03187c8ec41fad0f654cde2a6dfea4c7 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 12:11:35 -0600 Subject: [PATCH 014/226] Revert "Fix lintcheck by excluding checked crates from workspace" This reverts commit aea55d2c6239e42a0a337d610d19061521565615. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1d6bf1ea0eb96..b996e55c7795f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ edition = "2018" publish = false [workspace] -exclude = ["clippy_dev", "mini-macro", "target/lintcheck/crates"] +exclude = ["clippy_dev", "mini-macro"] [[bin]] name = "cargo-clippy" From fb905dffb48cde2eeae55a44db15719517af5842 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 12:11:47 -0600 Subject: [PATCH 015/226] Revert "Add workspace to manifest" This reverts commit 9bcb257985d5a16355bdd62998935f16d09b42e2. --- Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b996e55c7795f..ea32a8edd1ffb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,6 @@ build = "build.rs" edition = "2018" publish = false -[workspace] -exclude = ["clippy_dev", "mini-macro"] - [[bin]] name = "cargo-clippy" test = false From aef6dc23eed7cc20bff2fe7cdea058cd7c1346f7 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 12:12:33 -0600 Subject: [PATCH 016/226] Add package arguments to dogfood test This is necessary after migrating to RUSTC_WORKSPACE_WRAPPER. --- tests/dogfood.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 052223d6d6ff7..8fe48a67beb57 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -26,6 +26,7 @@ fn dogfood_clippy() { .arg("clippy-preview") .arg("--all-targets") .arg("--all-features") + .args(&["-p", "clippy_lints", "-p", "clippy_utils", "-p", "rustc_tools_util"]) .arg("--") .args(&["-D", "clippy::all"]) .args(&["-D", "clippy::pedantic"]) From d71ed26fd24d8121fcb08f7d4a5e00ce62e6e1fd Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 12:30:43 -0600 Subject: [PATCH 017/226] Revert "Fix versioncheck test" This reverts commit 1e7b1ccb2a05f80ae0a580401e7565fb1c0a4917. --- tests/versioncheck.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/versioncheck.rs b/tests/versioncheck.rs index 1c954c57a8549..aadd2c1fb7fdb 100644 --- a/tests/versioncheck.rs +++ b/tests/versioncheck.rs @@ -9,15 +9,15 @@ fn check_that_clippy_lints_and_clippy_utils_have_the_same_version_as_clippy() { .expect("could not obtain cargo metadata"); for krate in &["clippy_lints", "clippy_utils"] { - let krate_meta = clippy_meta - .packages - .iter() - .find(|package| package.name == *krate) + let krate_meta = cargo_metadata::MetadataCommand::new() + .current_dir(std::env::current_dir().unwrap().join(krate)) + .no_deps() + .exec() .expect("could not obtain cargo metadata"); - assert_eq!(krate_meta.version, clippy_meta.packages[0].version); + assert_eq!(krate_meta.packages[0].version, clippy_meta.packages[0].version); for package in &clippy_meta.packages[0].dependencies { if package.name == *krate { - assert!(package.req.matches(&krate_meta.version)); + assert!(package.req.matches(&krate_meta.packages[0].version)); break; } } From ef87e58993ace9e607a43b5581d40b4c0a2e71f6 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 26 Feb 2021 11:50:12 -0500 Subject: [PATCH 018/226] Fix `manual_map`: don't lint when partially moved values are used. Fix `manual_map`: don't lint when `return`, `break`, and `continue` are used. --- clippy_lints/src/manual_map.rs | 54 +++++++++++++++++++++++++++++-- clippy_utils/src/lib.rs | 12 +++++++ tests/ui/manual_map_option.fixed | 45 +++++++++++++++++++++++++- tests/ui/manual_map_option.rs | 45 +++++++++++++++++++++++++- tests/ui/manual_map_option.stderr | 34 +++++++++---------- 5 files changed, 168 insertions(+), 22 deletions(-) diff --git a/clippy_lints/src/manual_map.rs b/clippy_lints/src/manual_map.rs index 78dc0d54f28d3..bc6544ee79eae 100644 --- a/clippy_lints/src/manual_map.rs +++ b/clippy_lints/src/manual_map.rs @@ -2,13 +2,17 @@ use crate::{ map_unit_fn::OPTION_MAP_UNIT_FN, matches::MATCH_AS_REF, utils::{ - is_allowed, is_type_diagnostic_item, match_def_path, match_var, paths, peel_hir_expr_refs, - peel_mid_ty_refs_is_mutable, snippet_with_applicability, span_lint_and_sugg, + can_partially_move_ty, is_allowed, is_type_diagnostic_item, match_def_path, match_var, paths, + peel_hir_expr_refs, peel_mid_ty_refs_is_mutable, snippet_with_applicability, span_lint_and_sugg, }, }; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::Applicability; -use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, Mutability, Pat, PatKind, QPath}; +use rustc_hir::{ + def::Res, + intravisit::{walk_expr, ErasedMap, NestedVisitorMap, Visitor}, + Arm, BindingAnnotation, Block, Expr, ExprKind, Mutability, Pat, PatKind, Path, QPath, +}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -99,6 +103,10 @@ impl LateLintPass<'_> for ManualMap { return; } + if !can_move_expr_to_closure(cx, some_expr) { + return; + } + // Determine which binding mode to use. let explicit_ref = some_pat.contains_explicit_ref_binding(); let binding_ref = explicit_ref.or_else(|| (ty_ref_count != pat_ref_count).then(|| ty_mutability)); @@ -171,6 +179,46 @@ impl LateLintPass<'_> for ManualMap { } } +// Checks if the expression can be moved into a closure as is. +fn can_move_expr_to_closure(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { + struct V<'cx, 'tcx> { + cx: &'cx LateContext<'tcx>, + make_closure: bool, + } + impl Visitor<'tcx> for V<'_, 'tcx> { + type Map = ErasedMap<'tcx>; + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } + + fn visit_expr(&mut self, e: &'tcx Expr<'_>) { + match e.kind { + ExprKind::Break(..) | ExprKind::Continue(_) | ExprKind::Ret(_) => { + self.make_closure = false; + }, + // Accessing a field of a local value can only be done if the type isn't + // partially moved. + ExprKind::Field(base_expr, _) + if matches!( + base_expr.kind, + ExprKind::Path(QPath::Resolved(_, Path { res: Res::Local(_), .. })) + ) && can_partially_move_ty(self.cx, self.cx.typeck_results().expr_ty(base_expr)) => + { + // TODO: check if the local has been partially moved. Assume it has for now. + self.make_closure = false; + return; + } + _ => (), + }; + walk_expr(self, e); + } + } + + let mut v = V { cx, make_closure: true }; + v.visit_expr(expr); + v.make_closure +} + // Checks whether the expression could be passed as a function, or whether a closure is needed. // Returns the function to be passed to `map` if it exists. fn can_pass_as_func(cx: &LateContext<'tcx>, binding: Ident, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 8e5cf5dc6545d..0552394351198 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -456,6 +456,18 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { } } +/// Checks whether a type can be partially moved. +pub fn can_partially_move_ty(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + if has_drop(cx, ty) || is_copy(cx, ty) { + return false; + } + match ty.kind() { + ty::Param(_) => false, + ty::Adt(def, subs) => def.all_fields().any(|f| !is_copy(cx, f.ty(cx.tcx, subs))), + _ => true, + } +} + /// Returns the method names and argument list of nested method call expressions that make up /// `expr`. method/span lists are sorted with the most recent call first. pub fn method_calls<'tcx>( diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed index 1935090675825..428aac4394079 100644 --- a/tests/ui/manual_map_option.fixed +++ b/tests/ui/manual_map_option.fixed @@ -1,7 +1,13 @@ // run-rustfix #![warn(clippy::manual_map)] -#![allow(clippy::no_effect, clippy::map_identity, clippy::unit_arg, clippy::match_ref_pats)] +#![allow( + clippy::no_effect, + clippy::map_identity, + clippy::unit_arg, + clippy::match_ref_pats, + dead_code +)] fn main() { Some(0).map(|_| 2); @@ -67,4 +73,41 @@ fn main() { Some(Some((x, 1))) => Some(x), _ => None, }; + + // #6795 + fn f1() -> Result<(), ()> { + let _ = match Some(Ok(())) { + Some(x) => Some(x?), + None => None, + }; + Ok(()) + } + + for &x in Some(Some(true)).iter() { + let _ = match x { + Some(x) => Some(if x { continue } else { x }), + None => None, + }; + } + + // #6797 + let x1 = (Some(String::new()), 0); + let x2 = x1.0; + match x2 { + Some(x) => Some((x, x1.1)), + None => None, + }; + + struct S1 { + x: Option, + y: u32, + } + impl S1 { + fn f(self) -> Option<(String, u32)> { + match self.x { + Some(x) => Some((x, self.y)), + None => None, + } + } + } } diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index 8b8187db0a979..0f4a5bb2eb76d 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -1,7 +1,13 @@ // run-rustfix #![warn(clippy::manual_map)] -#![allow(clippy::no_effect, clippy::map_identity, clippy::unit_arg, clippy::match_ref_pats)] +#![allow( + clippy::no_effect, + clippy::map_identity, + clippy::unit_arg, + clippy::match_ref_pats, + dead_code +)] fn main() { match Some(0) { @@ -119,4 +125,41 @@ fn main() { Some(Some((x, 1))) => Some(x), _ => None, }; + + // #6795 + fn f1() -> Result<(), ()> { + let _ = match Some(Ok(())) { + Some(x) => Some(x?), + None => None, + }; + Ok(()) + } + + for &x in Some(Some(true)).iter() { + let _ = match x { + Some(x) => Some(if x { continue } else { x }), + None => None, + }; + } + + // #6797 + let x1 = (Some(String::new()), 0); + let x2 = x1.0; + match x2 { + Some(x) => Some((x, x1.1)), + None => None, + }; + + struct S1 { + x: Option, + y: u32, + } + impl S1 { + fn f(self) -> Option<(String, u32)> { + match self.x { + Some(x) => Some((x, self.y)), + None => None, + } + } + } } diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr index 210a30d05d40f..49a5173778433 100644 --- a/tests/ui/manual_map_option.stderr +++ b/tests/ui/manual_map_option.stderr @@ -1,5 +1,5 @@ error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:7:5 + --> $DIR/manual_map_option.rs:13:5 | LL | / match Some(0) { LL | | Some(_) => Some(2), @@ -10,7 +10,7 @@ LL | | }; = note: `-D clippy::manual-map` implied by `-D warnings` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:12:5 + --> $DIR/manual_map_option.rs:18:5 | LL | / match Some(0) { LL | | Some(x) => Some(x + 1), @@ -19,7 +19,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x + 1)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:17:5 + --> $DIR/manual_map_option.rs:23:5 | LL | / match Some("") { LL | | Some(x) => Some(x.is_empty()), @@ -28,7 +28,7 @@ LL | | }; | |_____^ help: try this: `Some("").map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:22:5 + --> $DIR/manual_map_option.rs:28:5 | LL | / if let Some(x) = Some(0) { LL | | Some(!x) @@ -38,7 +38,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| !x)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:29:5 + --> $DIR/manual_map_option.rs:35:5 | LL | / match Some(0) { LL | | Some(x) => { Some(std::convert::identity(x)) } @@ -47,7 +47,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(std::convert::identity)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:34:5 + --> $DIR/manual_map_option.rs:40:5 | LL | / match Some(&String::new()) { LL | | Some(x) => Some(str::len(x)), @@ -56,7 +56,7 @@ LL | | }; | |_____^ help: try this: `Some(&String::new()).map(|x| str::len(x))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:44:5 + --> $DIR/manual_map_option.rs:50:5 | LL | / match &Some([0, 1]) { LL | | Some(x) => Some(x[0]), @@ -65,7 +65,7 @@ LL | | }; | |_____^ help: try this: `Some([0, 1]).as_ref().map(|x| x[0])` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:49:5 + --> $DIR/manual_map_option.rs:55:5 | LL | / match &Some(0) { LL | | &Some(x) => Some(x * 2), @@ -74,7 +74,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x * 2)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:54:5 + --> $DIR/manual_map_option.rs:60:5 | LL | / match Some(String::new()) { LL | | Some(ref x) => Some(x.is_empty()), @@ -83,7 +83,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:59:5 + --> $DIR/manual_map_option.rs:65:5 | LL | / match &&Some(String::new()) { LL | | Some(x) => Some(x.len()), @@ -92,7 +92,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:64:5 + --> $DIR/manual_map_option.rs:70:5 | LL | / match &&Some(0) { LL | | &&Some(x) => Some(x + x), @@ -101,7 +101,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x + x)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:77:9 + --> $DIR/manual_map_option.rs:83:9 | LL | / match &mut Some(String::new()) { LL | | Some(x) => Some(x.push_str("")), @@ -110,7 +110,7 @@ LL | | }; | |_________^ help: try this: `Some(String::new()).as_mut().map(|x| x.push_str(""))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:83:5 + --> $DIR/manual_map_option.rs:89:5 | LL | / match &mut Some(String::new()) { LL | | Some(ref x) => Some(x.len()), @@ -119,7 +119,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:88:5 + --> $DIR/manual_map_option.rs:94:5 | LL | / match &mut &Some(String::new()) { LL | | Some(x) => Some(x.is_empty()), @@ -128,7 +128,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:93:5 + --> $DIR/manual_map_option.rs:99:5 | LL | / match Some((0, 1, 2)) { LL | | Some((x, y, z)) => Some(x + y + z), @@ -137,7 +137,7 @@ LL | | }; | |_____^ help: try this: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:98:5 + --> $DIR/manual_map_option.rs:104:5 | LL | / match Some([1, 2, 3]) { LL | | Some([first, ..]) => Some(first), @@ -146,7 +146,7 @@ LL | | }; | |_____^ help: try this: `Some([1, 2, 3]).map(|[first, ..]| first)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:103:5 + --> $DIR/manual_map_option.rs:109:5 | LL | / match &Some((String::new(), "test")) { LL | | Some((x, y)) => Some((y, x)), From 09a827ac735b138a06f3ac140a1c465b05a92ed1 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 26 Feb 2021 16:27:41 -0500 Subject: [PATCH 019/226] Revert #6796: Downgrade manual_map to nursery --- clippy_lints/src/lib.rs | 3 ++- clippy_lints/src/manual_map.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index faec9ec31f32c..176eeadcc630a 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1540,6 +1540,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&loops::WHILE_LET_ON_ITERATOR), LintId::of(&main_recursion::MAIN_RECURSION), LintId::of(&manual_async_fn::MANUAL_ASYNC_FN), + LintId::of(&manual_map::MANUAL_MAP), LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE), LintId::of(&manual_strip::MANUAL_STRIP), LintId::of(&manual_unwrap_or::MANUAL_UNWRAP_OR), @@ -1770,6 +1771,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&loops::WHILE_LET_ON_ITERATOR), LintId::of(&main_recursion::MAIN_RECURSION), LintId::of(&manual_async_fn::MANUAL_ASYNC_FN), + LintId::of(&manual_map::MANUAL_MAP), LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE), LintId::of(&map_clone::MAP_CLONE), LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH), @@ -2045,7 +2047,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&floating_point_arithmetic::SUBOPTIMAL_FLOPS), LintId::of(&future_not_send::FUTURE_NOT_SEND), LintId::of(&let_if_seq::USELESS_LET_IF_SEQ), - LintId::of(&manual_map::MANUAL_MAP), LintId::of(&missing_const_for_fn::MISSING_CONST_FOR_FN), LintId::of(&mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL), LintId::of(&mutex_atomic::MUTEX_INTEGER), diff --git a/clippy_lints/src/manual_map.rs b/clippy_lints/src/manual_map.rs index bc6544ee79eae..e6e70004527e4 100644 --- a/clippy_lints/src/manual_map.rs +++ b/clippy_lints/src/manual_map.rs @@ -23,7 +23,7 @@ declare_clippy_lint! { /// /// **Why is this bad?** Using the `map` method is clearer and more concise. /// - /// **Known problems:** `map` is not capable of representing some control flow which works fine in `match`. + /// **Known problems:** None. /// /// **Example:** /// @@ -38,7 +38,7 @@ declare_clippy_lint! { /// Some(0).map(|x| x + 1); /// ``` pub MANUAL_MAP, - nursery, + style, "reimplementation of `map`" } From 3d3cfd3754d616db959015eb7bd3c6238961320a Mon Sep 17 00:00:00 2001 From: Andrea Nall Date: Fri, 12 Feb 2021 04:27:04 +0000 Subject: [PATCH 020/226] added new lint `implicit_clone` --- CHANGELOG.md | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/methods/implicit_clone.rs | 32 ++++++ clippy_lints/src/methods/mod.rs | 32 ++++++ clippy_utils/src/lib.rs | 16 +++ tests/ui/cmp_owned/without_suggestion.rs | 1 + tests/ui/cmp_owned/without_suggestion.stderr | 6 +- tests/ui/implicit_clone.rs | 108 +++++++++++++++++++ tests/ui/implicit_clone.stderr | 64 +++++++++++ tests/ui/redundant_clone.fixed | 1 + tests/ui/redundant_clone.rs | 1 + tests/ui/redundant_clone.stderr | 56 +++++----- 12 files changed, 289 insertions(+), 31 deletions(-) create mode 100644 clippy_lints/src/methods/implicit_clone.rs create mode 100644 tests/ui/implicit_clone.rs create mode 100644 tests/ui/implicit_clone.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index d96c74b6e4126..687f744720202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2104,6 +2104,7 @@ Released 2018-09-13 [`if_not_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else [`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else [`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond +[`implicit_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_clone [`implicit_hasher`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_hasher [`implicit_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_return [`implicit_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_sub diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index faec9ec31f32c..fa8f03eb4453e 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -769,6 +769,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &methods::FLAT_MAP_IDENTITY, &methods::FROM_ITER_INSTEAD_OF_COLLECT, &methods::GET_UNWRAP, + &methods::IMPLICIT_CLONE, &methods::INEFFICIENT_TO_STRING, &methods::INSPECT_FOR_EACH, &methods::INTO_ITER_ON_REF, @@ -1380,6 +1381,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&matches::SINGLE_MATCH_ELSE), LintId::of(&methods::FILTER_MAP), LintId::of(&methods::FILTER_MAP_NEXT), + LintId::of(&methods::IMPLICIT_CLONE), LintId::of(&methods::INEFFICIENT_TO_STRING), LintId::of(&methods::MAP_FLATTEN), LintId::of(&methods::MAP_UNWRAP_OR), diff --git a/clippy_lints/src/methods/implicit_clone.rs b/clippy_lints/src/methods/implicit_clone.rs new file mode 100644 index 0000000000000..a769493d11d3f --- /dev/null +++ b/clippy_lints/src/methods/implicit_clone.rs @@ -0,0 +1,32 @@ +use crate::utils::span_lint_and_sugg; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_hir::ExprKind; +use rustc_lint::LateContext; +use rustc_middle::ty::TyS; +use rustc_span::symbol::Symbol; + +use super::IMPLICIT_CLONE; +use clippy_utils::is_diagnostic_assoc_item; + +pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, trait_diagnostic: Symbol) { + if_chain! { + if let ExprKind::MethodCall(method_path, _, [arg], _) = &expr.kind; + let return_type = cx.typeck_results().expr_ty(&expr); + let input_type = cx.typeck_results().expr_ty(arg).peel_refs(); + if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); + if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did)); + if TyS::same_type(return_type, input_type); + if is_diagnostic_assoc_item(cx, expr_def_id, trait_diagnostic); + then { + span_lint_and_sugg( + cx,IMPLICIT_CLONE,method_path.ident.span, + &format!("implicitly cloning a `{}` by calling `{}` on its dereferenced type", ty_name, method_path.ident.name), + "consider using", + "clone".to_string(), + Applicability::MachineApplicable + ); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 5fb3ae1890df1..6f491144435ac 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1,6 +1,7 @@ mod bind_instead_of_map; mod bytes_nth; mod filter_map_identity; +mod implicit_clone; mod inefficient_to_string; mod inspect_for_each; mod manual_saturating_arithmetic; @@ -1513,6 +1514,32 @@ declare_clippy_lint! { "replace `.bytes().nth()` with `.as_bytes().get()`" } +declare_clippy_lint! { + /// **What it does:** Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer. + /// + /// **Why is this bad?** These methods do the same thing as `_.clone()` but may be confusing as + /// to why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// let a = vec![1, 2, 3]; + /// let b = a.to_vec(); + /// let c = a.to_owned(); + /// ``` + /// Use instead: + /// ```rust + /// let a = vec![1, 2, 3]; + /// let b = a.clone(); + /// let c = a.clone(); + /// ``` + pub IMPLICIT_CLONE, + pedantic, + "implicitly cloning a value by invoking a function on its dereferenced type" +} + pub struct Methods { msrv: Option, } @@ -1579,6 +1606,7 @@ impl_lint_pass!(Methods => [ MAP_COLLECT_RESULT_UNIT, FROM_ITER_INSTEAD_OF_COLLECT, INSPECT_FOR_EACH, + IMPLICIT_CLONE ]); impl<'tcx> LateLintPass<'tcx> for Methods { @@ -1670,6 +1698,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["ok_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "ok_or"), ["collect", "map"] => lint_map_collect(cx, expr, arg_lists[1], arg_lists[0]), ["for_each", "inspect"] => inspect_for_each::lint(cx, expr, method_spans[1]), + ["to_owned", ..] => implicit_clone::check(cx, expr, sym::ToOwned), + ["to_os_string", ..] => implicit_clone::check(cx, expr, sym::OsStr), + ["to_path_buf", ..] => implicit_clone::check(cx, expr, sym::Path), + ["to_vec", ..] => implicit_clone::check(cx, expr, sym::slice), _ => {}, } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 8e5cf5dc6545d..2380ea4c7bfae 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -237,6 +237,22 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) trt_id.map_or(false, |trt_id| match_def_path(cx, trt_id, path)) } +/// Checks if the method call given in `expr` belongs to a trait or other container with a given +/// diagnostic item +pub fn is_diagnostic_assoc_item(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool { + cx.tcx + .opt_associated_item(def_id) + .and_then(|associated_item| match associated_item.container { + ty::TraitContainer(assoc_def_id) => Some(assoc_def_id), + ty::ImplContainer(assoc_def_id) => match cx.tcx.type_of(assoc_def_id).kind() { + ty::Adt(adt, _) => Some(adt.did), + ty::Slice(_) => cx.tcx.get_diagnostic_item(sym::slice), // this isn't perfect but it works + _ => None, + }, + }) + .map_or(false, |assoc_def_id| cx.tcx.is_diagnostic_item(diag_item, assoc_def_id)) +} + /// Checks if an expression references a variable of the given name. pub fn match_var(expr: &Expr<'_>, var: Symbol) -> bool { if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.kind { diff --git a/tests/ui/cmp_owned/without_suggestion.rs b/tests/ui/cmp_owned/without_suggestion.rs index 9ab8795474c67..f44a3901fb487 100644 --- a/tests/ui/cmp_owned/without_suggestion.rs +++ b/tests/ui/cmp_owned/without_suggestion.rs @@ -1,4 +1,5 @@ #[allow(clippy::unnecessary_operation)] +#[allow(clippy::implicit_clone)] fn main() { let x = &Baz; diff --git a/tests/ui/cmp_owned/without_suggestion.stderr b/tests/ui/cmp_owned/without_suggestion.stderr index 6e8a5ad2a17b5..2ea3d8fac0d1a 100644 --- a/tests/ui/cmp_owned/without_suggestion.stderr +++ b/tests/ui/cmp_owned/without_suggestion.stderr @@ -1,5 +1,5 @@ error: this creates an owned instance just for comparison - --> $DIR/without_suggestion.rs:6:5 + --> $DIR/without_suggestion.rs:7:5 | LL | y.to_owned() == *x; | ^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating @@ -7,13 +7,13 @@ LL | y.to_owned() == *x; = note: `-D clippy::cmp-owned` implied by `-D warnings` error: this creates an owned instance just for comparison - --> $DIR/without_suggestion.rs:10:5 + --> $DIR/without_suggestion.rs:11:5 | LL | y.to_owned() == **x; | ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating error: this creates an owned instance just for comparison - --> $DIR/without_suggestion.rs:17:9 + --> $DIR/without_suggestion.rs:18:9 | LL | self.to_owned() == *other | ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating diff --git a/tests/ui/implicit_clone.rs b/tests/ui/implicit_clone.rs new file mode 100644 index 0000000000000..19101522163f9 --- /dev/null +++ b/tests/ui/implicit_clone.rs @@ -0,0 +1,108 @@ +#![warn(clippy::implicit_clone)] +#![allow(clippy::redundant_clone)] +use std::borrow::Borrow; +use std::ffi::{OsStr, OsString}; +use std::path::PathBuf; + +fn return_owned_from_slice(slice: &[u32]) -> Vec { + slice.to_owned() +} + +pub fn own_same(v: T) -> T +where + T: ToOwned, +{ + v.to_owned() +} + +pub fn own_same_from_ref(v: &T) -> T +where + T: ToOwned, +{ + v.to_owned() +} + +pub fn own_different(v: T) -> U +where + T: ToOwned, +{ + v.to_owned() +} + +#[derive(Copy, Clone)] +struct Kitten {} +impl Kitten { + // badly named method + fn to_vec(self) -> Kitten { + Kitten {} + } +} +impl Borrow for Kitten { + fn borrow(&self) -> &BorrowedKitten { + static VALUE: BorrowedKitten = BorrowedKitten {}; + &VALUE + } +} + +struct BorrowedKitten {} +impl ToOwned for BorrowedKitten { + type Owned = Kitten; + fn to_owned(&self) -> Kitten { + Kitten {} + } +} + +mod weird { + #[allow(clippy::ptr_arg)] + pub fn to_vec(v: &Vec) -> Vec { + v.clone() + } +} + +fn main() { + let vec = vec![5]; + let _ = return_owned_from_slice(&vec); + let _ = vec.to_owned(); + let _ = vec.to_vec(); + + let vec_ref = &vec; + let _ = return_owned_from_slice(&vec_ref); + let _ = vec_ref.to_owned(); + let _ = vec_ref.to_vec(); + + // we expect no lint for this + let _ = weird::to_vec(&vec); + + // we expect no lints for this + let slice: &[u32] = &[1, 2, 3, 4, 5]; + let _ = return_owned_from_slice(slice); + let _ = slice.to_owned(); + let _ = slice.to_vec(); + + let str = "hello world".to_string(); + let _ = str.to_owned(); + + // testing w/ an arbitrary type + let kitten = Kitten {}; + let _ = kitten.to_owned(); + let _ = own_same_from_ref(&kitten); + // this shouln't lint + let _ = kitten.to_vec(); + + // we expect no lints for this + let borrowed = BorrowedKitten {}; + let _ = borrowed.to_owned(); + + let pathbuf = PathBuf::new(); + let _ = pathbuf.to_owned(); + let _ = pathbuf.to_path_buf(); + + let os_string = OsString::from("foo"); + let _ = os_string.to_owned(); + let _ = os_string.to_os_string(); + + // we expect no lints for this + let os_str = OsStr::new("foo"); + let _ = os_str.to_owned(); + let _ = os_str.to_os_string(); +} diff --git a/tests/ui/implicit_clone.stderr b/tests/ui/implicit_clone.stderr new file mode 100644 index 0000000000000..e6f7527b67219 --- /dev/null +++ b/tests/ui/implicit_clone.stderr @@ -0,0 +1,64 @@ +error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:65:17 + | +LL | let _ = vec.to_owned(); + | ^^^^^^^^ help: consider using: `clone` + | + = note: `-D clippy::implicit-clone` implied by `-D warnings` + +error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type + --> $DIR/implicit_clone.rs:66:17 + | +LL | let _ = vec.to_vec(); + | ^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:70:21 + | +LL | let _ = vec_ref.to_owned(); + | ^^^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type + --> $DIR/implicit_clone.rs:71:21 + | +LL | let _ = vec_ref.to_vec(); + | ^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:83:17 + | +LL | let _ = str.to_owned(); + | ^^^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `Kitten` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:87:20 + | +LL | let _ = kitten.to_owned(); + | ^^^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `PathBuf` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:97:21 + | +LL | let _ = pathbuf.to_owned(); + | ^^^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type + --> $DIR/implicit_clone.rs:98:21 + | +LL | let _ = pathbuf.to_path_buf(); + | ^^^^^^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `OsString` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:101:23 + | +LL | let _ = os_string.to_owned(); + | ^^^^^^^^ help: consider using: `clone` + +error: implicitly cloning a `OsString` by calling `to_os_string` on its dereferenced type + --> $DIR/implicit_clone.rs:102:23 + | +LL | let _ = os_string.to_os_string(); + | ^^^^^^^^^^^^ help: consider using: `clone` + +error: aborting due to 10 previous errors + diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed index cdeefda4c234c..a5847e37c976e 100644 --- a/tests/ui/redundant_clone.fixed +++ b/tests/ui/redundant_clone.fixed @@ -1,6 +1,7 @@ // run-rustfix // rustfix-only-machine-applicable +#![allow(clippy::implicit_clone)] use std::ffi::OsString; use std::path::Path; diff --git a/tests/ui/redundant_clone.rs b/tests/ui/redundant_clone.rs index acb7ffb305f2a..dab8d7fb1c727 100644 --- a/tests/ui/redundant_clone.rs +++ b/tests/ui/redundant_clone.rs @@ -1,6 +1,7 @@ // run-rustfix // rustfix-only-machine-applicable +#![allow(clippy::implicit_clone)] use std::ffi::OsString; use std::path::Path; diff --git a/tests/ui/redundant_clone.stderr b/tests/ui/redundant_clone.stderr index 89b3925429910..87c219316ce4b 100644 --- a/tests/ui/redundant_clone.stderr +++ b/tests/ui/redundant_clone.stderr @@ -1,168 +1,168 @@ error: redundant clone - --> $DIR/redundant_clone.rs:8:42 + --> $DIR/redundant_clone.rs:9:42 | LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^ help: remove this | = note: `-D clippy::redundant-clone` implied by `-D warnings` note: this value is dropped without further use - --> $DIR/redundant_clone.rs:8:14 + --> $DIR/redundant_clone.rs:9:14 | LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:11:15 + --> $DIR/redundant_clone.rs:12:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:11:14 + --> $DIR/redundant_clone.rs:12:14 | LL | let _s = s.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:14:15 + --> $DIR/redundant_clone.rs:15:15 | LL | let _s = s.to_string(); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:14:14 + --> $DIR/redundant_clone.rs:15:14 | LL | let _s = s.to_string(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:17:15 + --> $DIR/redundant_clone.rs:18:15 | LL | let _s = s.to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:17:14 + --> $DIR/redundant_clone.rs:18:14 | LL | let _s = s.to_owned(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:19:42 + --> $DIR/redundant_clone.rs:20:42 | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:19:14 + --> $DIR/redundant_clone.rs:20:14 | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:21:42 + --> $DIR/redundant_clone.rs:22:42 | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:21:14 + --> $DIR/redundant_clone.rs:22:14 | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:23:29 + --> $DIR/redundant_clone.rs:24:29 | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:23:14 + --> $DIR/redundant_clone.rs:24:14 | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:25:29 + --> $DIR/redundant_clone.rs:26:29 | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:25:14 + --> $DIR/redundant_clone.rs:26:14 | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:32:19 + --> $DIR/redundant_clone.rs:33:19 | LL | let _t = tup.0.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:32:14 + --> $DIR/redundant_clone.rs:33:14 | LL | let _t = tup.0.clone(); | ^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:62:22 + --> $DIR/redundant_clone.rs:63:22 | LL | (a.clone(), a.clone()) | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:62:21 + --> $DIR/redundant_clone.rs:63:21 | LL | (a.clone(), a.clone()) | ^ error: redundant clone - --> $DIR/redundant_clone.rs:122:15 + --> $DIR/redundant_clone.rs:123:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:122:14 + --> $DIR/redundant_clone.rs:123:14 | LL | let _s = s.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:123:15 + --> $DIR/redundant_clone.rs:124:15 | LL | let _t = t.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:123:14 + --> $DIR/redundant_clone.rs:124:14 | LL | let _t = t.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:133:19 + --> $DIR/redundant_clone.rs:134:19 | LL | let _f = f.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:133:18 + --> $DIR/redundant_clone.rs:134:18 | LL | let _f = f.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:145:14 + --> $DIR/redundant_clone.rs:146:14 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^ help: remove this | note: cloned value is neither consumed nor mutated - --> $DIR/redundant_clone.rs:145:13 + --> $DIR/redundant_clone.rs:146:13 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^^ From 2b3a731e1cc8ad0e05149989ee40d4c1a407890b Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 22:04:02 -0600 Subject: [PATCH 021/226] Add missing diagnostic item Symbols --- clippy_lints/src/entry.rs | 3 ++- clippy_lints/src/loops.rs | 16 ++++++++-------- clippy_lints/src/methods/mod.rs | 6 +++--- clippy_lints/src/swap.rs | 2 +- clippy_lints/src/types.rs | 4 ++-- clippy_lints/src/zero_sized_map_values.rs | 3 ++- clippy_utils/src/eager_or_lazy.rs | 3 ++- 7 files changed, 20 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 6b9f9a5675481..55575969927ba 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -9,6 +9,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; +use rustc_span::sym; declare_clippy_lint! { /// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap` @@ -111,7 +112,7 @@ fn check_cond<'a>(cx: &LateContext<'_>, check: &'a Expr<'a>) -> Option<(&'static return if match_type(cx, obj_ty, &paths::BTREEMAP) { Some(("BTreeMap", map, key)) } - else if is_type_diagnostic_item(cx, obj_ty, sym!(hashmap_type)) { + else if is_type_diagnostic_item(cx, obj_ty, sym::hashmap_type) { Some(("HashMap", map, key)) } else { diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 1c9373a756c88..63d9b7f864597 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -1010,7 +1010,7 @@ fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'_>) -> bool { _ => false, }; - is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) + is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym::vecdeque_type) } fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { @@ -1908,7 +1908,7 @@ fn check_for_loop_over_map_kv<'tcx>( _ => arg, }; - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP) { + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP) { span_lint_and_then( cx, FOR_KV_MAP, @@ -2386,9 +2386,9 @@ fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { is_iterable_array(ty, cx) || is_type_diagnostic_item(cx, ty, sym::vec_type) || match_type(cx, ty, &paths::LINKED_LIST) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || - is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::hashmap_type) || + is_type_diagnostic_item(cx, ty, sym::hashset_type) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::BINARY_HEAP) || match_type(cx, ty, &paths::BTREEMAP) || match_type(cx, ty, &paths::BTREESET) @@ -2922,9 +2922,9 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont then { let ty = cx.typeck_results().node_type(ty.hir_id); if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::BTREEMAP) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { + is_type_diagnostic_item(cx, ty, sym::hashmap_type) { if method.ident.name == sym!(len) { let span = shorten_needless_collect_span(expr); span_lint_and_sugg( @@ -2992,7 +2992,7 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); if let ty = cx.typeck_results().node_type(ty.hir_id); if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::LINKED_LIST); if let Some(iter_calls) = detect_iter_and_into_iters(block, *ident); if iter_calls.len() == 1; diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index ebd8af93dd0fb..f101b6476f508 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2598,7 +2598,7 @@ fn lint_iter_nth<'tcx>( "slice" } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { "Vec" - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vecdeque_type) { "VecDeque" } else { let nth_args = nth_and_iter_args[0]; @@ -2652,10 +2652,10 @@ fn lint_get_unwrap<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args: } else if is_type_diagnostic_item(cx, expr_ty, sym::vec_type) { needs_ref = get_args_str.parse::().is_ok(); "Vec" - } else if is_type_diagnostic_item(cx, expr_ty, sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, expr_ty, sym::vecdeque_type) { needs_ref = get_args_str.parse::().is_ok(); "VecDeque" - } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym!(hashmap_type)) { + } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::hashmap_type) { needs_ref = true; "HashMap" } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) { diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 699fd51ccc194..9d8a0c248334f 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -199,7 +199,7 @@ fn check_for_slice<'a>(cx: &LateContext<'_>, lhs1: &'a Expr<'_>, lhs2: &'a Expr< if matches!(ty.kind(), ty::Slice(_)) || matches!(ty.kind(), ty::Array(_, _)) || is_type_diagnostic_item(cx, ty, sym::vec_type) - || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) + || is_type_diagnostic_item(cx, ty, sym::vecdeque_type) { return Slice::Swappable(lhs1, idx1, idx2); } diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 05754503163bd..eb2016db3dc2c 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -2680,14 +2680,14 @@ impl<'tcx> ImplicitHasherType<'tcx> { let ty = hir_ty_to_ty(cx.tcx, hir_ty); - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) && params_len == 2 { + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) && params_len == 2 { Some(ImplicitHasherType::HashMap( hir_ty.span, ty, snippet(cx, params[0].span, "K"), snippet(cx, params[1].span, "V"), )) - } else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) && params_len == 1 { + } else if is_type_diagnostic_item(cx, ty, sym::hashset_type) && params_len == 1 { Some(ImplicitHasherType::HashSet( hir_ty.span, ty, diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index 319b85ac42a80..316b8d820a715 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -5,6 +5,7 @@ use rustc_middle::ty::{Adt, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_target::abi::LayoutOf as _; use rustc_typeck::hir_ty_to_ty; +use rustc_span::sym; use crate::utils::{is_normalizable, is_type_diagnostic_item, match_type, paths, span_lint_and_help}; @@ -47,7 +48,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { if !hir_ty.span.from_expansion(); if !in_trait_impl(cx, hir_ty.hir_id); let ty = ty_from_hir_ty(cx, hir_ty); - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP); + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP); if let Adt(_, ref substs) = ty.kind(); let ty = substs.type_at(1); // Do this to prevent `layout_of` crashing, being unable to fully normalize `ty`. diff --git a/clippy_utils/src/eager_or_lazy.rs b/clippy_utils/src/eager_or_lazy.rs index 52a33e9b1704c..81cd99c0558dc 100644 --- a/clippy_utils/src/eager_or_lazy.rs +++ b/clippy_utils/src/eager_or_lazy.rs @@ -18,6 +18,7 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor}; use rustc_hir::{Block, Expr, ExprKind, Path, QPath}; use rustc_lint::LateContext; use rustc_middle::hir::map::Map; +use rustc_span::sym; /// Is the expr pure (is it free from side-effects)? /// This function is named so to stress that it isn't exhaustive and returns FNs. @@ -99,7 +100,7 @@ fn identify_some_potentially_expensive_patterns<'tcx>(cx: &LateContext<'tcx>, ex ExprKind::Call(..) => !is_ctor_or_promotable_const_function(self.cx, expr), ExprKind::Index(obj, _) => { let ty = self.cx.typeck_results().expr_ty(obj); - is_type_diagnostic_item(self.cx, ty, sym!(hashmap_type)) + is_type_diagnostic_item(self.cx, ty, sym::hashmap_type) || match_type(self.cx, ty, &paths::BTREEMAP) }, ExprKind::MethodCall(..) => true, From 51617b83a18b2a0b1f0f2cae8c43e42043a86b76 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 25 Feb 2021 23:06:50 +0900 Subject: [PATCH 022/226] new lint: iter_count --- CHANGELOG.md | 1 + clippy_lints/src/lib.rs | 3 ++ clippy_lints/src/methods/mod.rs | 62 ++++++++++++++++++++++++++++ tests/ui/auxiliary/option_helpers.rs | 4 ++ tests/ui/iter_count.fixed | 58 ++++++++++++++++++++++++++ tests/ui/iter_count.rs | 58 ++++++++++++++++++++++++++ tests/ui/iter_count.stderr | 52 +++++++++++++++++++++++ 7 files changed, 238 insertions(+) create mode 100644 tests/ui/iter_count.fixed create mode 100644 tests/ui/iter_count.rs create mode 100644 tests/ui/iter_count.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 687f744720202..41c334c68169b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2135,6 +2135,7 @@ Released 2018-09-13 [`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters [`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements [`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect +[`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count [`iter_next_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_loop [`iter_next_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_slice [`iter_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index fa8f03eb4453e..1ace4c8a10c91 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -775,6 +775,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &methods::INTO_ITER_ON_REF, &methods::ITERATOR_STEP_BY_ZERO, &methods::ITER_CLONED_COLLECT, + &methods::ITER_COUNT, &methods::ITER_NEXT_SLICE, &methods::ITER_NTH, &methods::ITER_NTH_ZERO, @@ -1577,6 +1578,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&methods::INTO_ITER_ON_REF), LintId::of(&methods::ITERATOR_STEP_BY_ZERO), LintId::of(&methods::ITER_CLONED_COLLECT), + LintId::of(&methods::ITER_COUNT), LintId::of(&methods::ITER_NEXT_SLICE), LintId::of(&methods::ITER_NTH), LintId::of(&methods::ITER_NTH_ZERO), @@ -1881,6 +1883,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&methods::FILTER_NEXT), LintId::of(&methods::FLAT_MAP_IDENTITY), LintId::of(&methods::INSPECT_FOR_EACH), + LintId::of(&methods::ITER_COUNT), LintId::of(&methods::MANUAL_FILTER_MAP), LintId::of(&methods::MANUAL_FIND_MAP), LintId::of(&methods::OPTION_AS_REF_DEREF), diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 6f491144435ac..17e7f6f662db5 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1540,6 +1540,32 @@ declare_clippy_lint! { "implicitly cloning a value by invoking a function on its dereferenced type" } +declare_clippy_lint! { + /// **What it does:** Checks for the use of `.iter().count()`. + /// + /// **Why is this bad?** `.len()` is more efficient and more + /// readable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// // Bad + /// let some_vec = vec![0, 1, 2, 3]; + /// let _ = some_vec.iter().count(); + /// let _ = &some_vec[..].iter().count(); + /// + /// // Good + /// let some_vec = vec![0, 1, 2, 3]; + /// let _ = some_vec.len(); + /// let _ = &some_vec[..].len(); + /// ``` + pub ITER_COUNT, + complexity, + "replace `.iter().count()` with `.len()`" +} + pub struct Methods { msrv: Option, } @@ -1585,6 +1611,7 @@ impl_lint_pass!(Methods => [ MAP_FLATTEN, ITERATOR_STEP_BY_ZERO, ITER_NEXT_SLICE, + ITER_COUNT, ITER_NTH, ITER_NTH_ZERO, BYTES_NTH, @@ -1664,6 +1691,8 @@ impl<'tcx> LateLintPass<'tcx> for Methods { lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) }, ["extend", ..] => lint_extend(cx, expr, arg_lists[0]), + ["count", "iter"] => lint_iter_count(cx, expr, &arg_lists[1], false), + ["count", "iter_mut"] => lint_iter_count(cx, expr, &arg_lists[1], true), ["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false), ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true), ["nth", "bytes"] => bytes_nth::lints(cx, expr, &arg_lists[1]), @@ -2632,6 +2661,39 @@ fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_ } } +fn lint_iter_count<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], is_mut: bool) { + let mut_str = if is_mut { "_mut" } else { "" }; + if_chain! { + let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() { + Some("slice") + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { + Some("Vec") + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { + Some("VecDeque") + } else if match_trait_method(cx, expr, &paths::ITERATOR) { + Some("std::iter::Iterator") + } else { + None + }; + if let Some(caller_type) = caller_type; + then { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + ITER_COUNT, + expr.span, + &format!("called `.iter{}().count()` on a `{}`", mut_str, caller_type), + "try", + format!( + "{}.len()", + snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability), + ), + applicability, + ); + } + } +} + fn lint_iter_nth<'tcx>( cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, diff --git a/tests/ui/auxiliary/option_helpers.rs b/tests/ui/auxiliary/option_helpers.rs index ed11c41e21c1a..7dc3f4ebd4d46 100644 --- a/tests/ui/auxiliary/option_helpers.rs +++ b/tests/ui/auxiliary/option_helpers.rs @@ -48,4 +48,8 @@ impl IteratorFalsePositives { pub fn skip_while(self) -> IteratorFalsePositives { self } + + pub fn count(self) -> usize { + self.foo as usize + } } diff --git a/tests/ui/iter_count.fixed b/tests/ui/iter_count.fixed new file mode 100644 index 0000000000000..14cae1cd73e42 --- /dev/null +++ b/tests/ui/iter_count.fixed @@ -0,0 +1,58 @@ +// run-rustfix +// aux-build:option_helpers.rs + +#![warn(clippy::iter_count)] +#![allow(unused_variables)] +#![allow(unused_mut)] + +extern crate option_helpers; + +use option_helpers::IteratorFalsePositives; +use std::collections::{HashSet, VecDeque}; + +/// Struct to generate false positives for things with `.iter()`. +#[derive(Copy, Clone)] +struct HasIter; + +impl HasIter { + fn iter(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } + + fn iter_mut(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } +} + +fn main() { + let mut some_vec = vec![0, 1, 2, 3]; + let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); + let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect(); + let mut some_hash_set = HashSet::new(); + some_hash_set.insert(1); + + { + // Make sure we lint `.iter()` for relevant types. + let bad_vec = some_vec.len(); + let bad_slice = &some_vec[..].len(); + let bad_boxed_slice = boxed_slice.len(); + let bad_vec_deque = some_vec_deque.len(); + let bad_hash_set = some_hash_set.len(); + } + + { + // Make sure we lint `.iter_mut()` for relevant types. + let bad_vec = some_vec.len(); + } + { + let bad_slice = &some_vec[..].len(); + } + { + let bad_vec_deque = some_vec_deque.len(); + } + + // Make sure we don't lint for non-relevant types. + let false_positive = HasIter; + let ok = false_positive.iter().count(); + let ok_mut = false_positive.iter_mut().count(); +} diff --git a/tests/ui/iter_count.rs b/tests/ui/iter_count.rs new file mode 100644 index 0000000000000..dfe02e5d53e29 --- /dev/null +++ b/tests/ui/iter_count.rs @@ -0,0 +1,58 @@ +// run-rustfix +// aux-build:option_helpers.rs + +#![warn(clippy::iter_count)] +#![allow(unused_variables)] +#![allow(unused_mut)] + +extern crate option_helpers; + +use option_helpers::IteratorFalsePositives; +use std::collections::{HashSet, VecDeque}; + +/// Struct to generate false positives for things with `.iter()`. +#[derive(Copy, Clone)] +struct HasIter; + +impl HasIter { + fn iter(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } + + fn iter_mut(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } +} + +fn main() { + let mut some_vec = vec![0, 1, 2, 3]; + let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); + let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect(); + let mut some_hash_set = HashSet::new(); + some_hash_set.insert(1); + + { + // Make sure we lint `.iter()` for relevant types. + let bad_vec = some_vec.iter().count(); + let bad_slice = &some_vec[..].iter().count(); + let bad_boxed_slice = boxed_slice.iter().count(); + let bad_vec_deque = some_vec_deque.iter().count(); + let bad_hash_set = some_hash_set.iter().count(); + } + + { + // Make sure we lint `.iter_mut()` for relevant types. + let bad_vec = some_vec.iter_mut().count(); + } + { + let bad_slice = &some_vec[..].iter_mut().count(); + } + { + let bad_vec_deque = some_vec_deque.iter_mut().count(); + } + + // Make sure we don't lint for non-relevant types. + let false_positive = HasIter; + let ok = false_positive.iter().count(); + let ok_mut = false_positive.iter_mut().count(); +} diff --git a/tests/ui/iter_count.stderr b/tests/ui/iter_count.stderr new file mode 100644 index 0000000000000..a465d22199455 --- /dev/null +++ b/tests/ui/iter_count.stderr @@ -0,0 +1,52 @@ +error: called `.iter().count()` on a `Vec` + --> $DIR/iter_count.rs:36:23 + | +LL | let bad_vec = some_vec.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec.len()` + | + = note: `-D clippy::iter-count` implied by `-D warnings` + +error: called `.iter().count()` on a `slice` + --> $DIR/iter_count.rs:37:26 + | +LL | let bad_slice = &some_vec[..].iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[..].len()` + +error: called `.iter().count()` on a `slice` + --> $DIR/iter_count.rs:38:31 + | +LL | let bad_boxed_slice = boxed_slice.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()` + +error: called `.iter().count()` on a `VecDeque` + --> $DIR/iter_count.rs:39:29 + | +LL | let bad_vec_deque = some_vec_deque.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec_deque.len()` + +error: called `.iter().count()` on a `std::iter::Iterator` + --> $DIR/iter_count.rs:40:28 + | +LL | let bad_hash_set = some_hash_set.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_hash_set.len()` + +error: called `.iter_mut().count()` on a `Vec` + --> $DIR/iter_count.rs:45:23 + | +LL | let bad_vec = some_vec.iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec.len()` + +error: called `.iter_mut().count()` on a `slice` + --> $DIR/iter_count.rs:48:26 + | +LL | let bad_slice = &some_vec[..].iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[..].len()` + +error: called `.iter_mut().count()` on a `VecDeque` + --> $DIR/iter_count.rs:51:29 + | +LL | let bad_vec_deque = some_vec_deque.iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec_deque.len()` + +error: aborting due to 8 previous errors + From 7223ee6590bb74e2a7ad02361b51cfa58178c740 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 25 Feb 2021 23:07:15 +0900 Subject: [PATCH 023/226] allow clippy::iter_count --- tests/ui/needless_collect.fixed | 2 +- tests/ui/needless_collect.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index 7f2fcf02f6b5b..af6c7bf15ea6c 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![allow(unused, clippy::suspicious_map)] +#![allow(unused, clippy::suspicious_map, clippy::iter_count)] use std::collections::{BTreeSet, HashMap, HashSet}; diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 788a9eb3264ee..6ae14f370b14b 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -1,6 +1,6 @@ // run-rustfix -#![allow(unused, clippy::suspicious_map)] +#![allow(unused, clippy::suspicious_map, clippy::iter_count)] use std::collections::{BTreeSet, HashMap, HashSet}; From 204b27937c488eb7c1b81c31d56779861ff488c3 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 26 Feb 2021 01:54:51 +0900 Subject: [PATCH 024/226] lint for `into_iter().count()` --- clippy_lints/src/methods/mod.rs | 11 ++++- tests/ui/iter_count.fixed | 58 +++++++++++++------------- tests/ui/iter_count.rs | 58 +++++++++++++------------- tests/ui/iter_count.stderr | 72 ++++++++++++++++++++------------- 4 files changed, 116 insertions(+), 83 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 17e7f6f662db5..e5509ee2c4e0f 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1691,7 +1691,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) }, ["extend", ..] => lint_extend(cx, expr, arg_lists[0]), - ["count", "iter"] => lint_iter_count(cx, expr, &arg_lists[1], false), + ["count", "into_iter" | "iter"] => lint_iter_count(cx, expr, &arg_lists[1], false), ["count", "iter_mut"] => lint_iter_count(cx, expr, &arg_lists[1], true), ["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false), ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true), @@ -2663,6 +2663,13 @@ fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_ fn lint_iter_count<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], is_mut: bool) { let mut_str = if is_mut { "_mut" } else { "" }; + let iter_method = if method_chain_args(expr, &[format!("iter{}", mut_str).as_str(), "count"]).is_some() { + "iter" + } else if method_chain_args(expr, &["into_iter", "count"]).is_some() { + "into_iter" + } else { + return; + }; if_chain! { let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() { Some("slice") @@ -2682,7 +2689,7 @@ fn lint_iter_count<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'t cx, ITER_COUNT, expr.span, - &format!("called `.iter{}().count()` on a `{}`", mut_str, caller_type), + &format!("called `.{}{}().count()` on a `{}`", iter_method, mut_str, caller_type), "try", format!( "{}.len()", diff --git a/tests/ui/iter_count.fixed b/tests/ui/iter_count.fixed index 14cae1cd73e42..c8f896408479f 100644 --- a/tests/ui/iter_count.fixed +++ b/tests/ui/iter_count.fixed @@ -2,8 +2,13 @@ // aux-build:option_helpers.rs #![warn(clippy::iter_count)] -#![allow(unused_variables)] -#![allow(unused_mut)] +#![allow( + unused_variables, + array_into_iter, + unused_mut, + clippy::into_iter_on_ref, + clippy::unnecessary_operation +)] extern crate option_helpers; @@ -22,37 +27,36 @@ impl HasIter { fn iter_mut(self) -> IteratorFalsePositives { IteratorFalsePositives { foo: 0 } } + + fn into_iter(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } } fn main() { - let mut some_vec = vec![0, 1, 2, 3]; + let mut vec = vec![0, 1, 2, 3]; let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); - let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect(); - let mut some_hash_set = HashSet::new(); - some_hash_set.insert(1); - - { - // Make sure we lint `.iter()` for relevant types. - let bad_vec = some_vec.len(); - let bad_slice = &some_vec[..].len(); - let bad_boxed_slice = boxed_slice.len(); - let bad_vec_deque = some_vec_deque.len(); - let bad_hash_set = some_hash_set.len(); - } + let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect(); + let mut hash_set = HashSet::new(); + hash_set.insert(1); - { - // Make sure we lint `.iter_mut()` for relevant types. - let bad_vec = some_vec.len(); - } - { - let bad_slice = &some_vec[..].len(); - } - { - let bad_vec_deque = some_vec_deque.len(); - } + &vec[..].len(); + vec.len(); + boxed_slice.len(); + vec_deque.len(); + hash_set.len(); + + vec.len(); + &vec[..].len(); + vec_deque.len(); + + &vec[..].len(); + vec.len(); + vec_deque.len(); // Make sure we don't lint for non-relevant types. let false_positive = HasIter; - let ok = false_positive.iter().count(); - let ok_mut = false_positive.iter_mut().count(); + false_positive.iter().count(); + false_positive.iter_mut().count(); + false_positive.into_iter().count(); } diff --git a/tests/ui/iter_count.rs b/tests/ui/iter_count.rs index dfe02e5d53e29..8ea17ef34fa63 100644 --- a/tests/ui/iter_count.rs +++ b/tests/ui/iter_count.rs @@ -2,8 +2,13 @@ // aux-build:option_helpers.rs #![warn(clippy::iter_count)] -#![allow(unused_variables)] -#![allow(unused_mut)] +#![allow( + unused_variables, + array_into_iter, + unused_mut, + clippy::into_iter_on_ref, + clippy::unnecessary_operation +)] extern crate option_helpers; @@ -22,37 +27,36 @@ impl HasIter { fn iter_mut(self) -> IteratorFalsePositives { IteratorFalsePositives { foo: 0 } } + + fn into_iter(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } } fn main() { - let mut some_vec = vec![0, 1, 2, 3]; + let mut vec = vec![0, 1, 2, 3]; let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); - let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect(); - let mut some_hash_set = HashSet::new(); - some_hash_set.insert(1); - - { - // Make sure we lint `.iter()` for relevant types. - let bad_vec = some_vec.iter().count(); - let bad_slice = &some_vec[..].iter().count(); - let bad_boxed_slice = boxed_slice.iter().count(); - let bad_vec_deque = some_vec_deque.iter().count(); - let bad_hash_set = some_hash_set.iter().count(); - } + let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect(); + let mut hash_set = HashSet::new(); + hash_set.insert(1); - { - // Make sure we lint `.iter_mut()` for relevant types. - let bad_vec = some_vec.iter_mut().count(); - } - { - let bad_slice = &some_vec[..].iter_mut().count(); - } - { - let bad_vec_deque = some_vec_deque.iter_mut().count(); - } + &vec[..].iter().count(); + vec.iter().count(); + boxed_slice.iter().count(); + vec_deque.iter().count(); + hash_set.iter().count(); + + vec.iter_mut().count(); + &vec[..].iter_mut().count(); + vec_deque.iter_mut().count(); + + &vec[..].into_iter().count(); + vec.into_iter().count(); + vec_deque.into_iter().count(); // Make sure we don't lint for non-relevant types. let false_positive = HasIter; - let ok = false_positive.iter().count(); - let ok_mut = false_positive.iter_mut().count(); + false_positive.iter().count(); + false_positive.iter_mut().count(); + false_positive.into_iter().count(); } diff --git a/tests/ui/iter_count.stderr b/tests/ui/iter_count.stderr index a465d22199455..0820c0014434b 100644 --- a/tests/ui/iter_count.stderr +++ b/tests/ui/iter_count.stderr @@ -1,52 +1,70 @@ -error: called `.iter().count()` on a `Vec` - --> $DIR/iter_count.rs:36:23 +error: called `.iter().count()` on a `slice` + --> $DIR/iter_count.rs:43:6 | -LL | let bad_vec = some_vec.iter().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec.len()` +LL | &vec[..].iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` | = note: `-D clippy::iter-count` implied by `-D warnings` -error: called `.iter().count()` on a `slice` - --> $DIR/iter_count.rs:37:26 +error: called `.iter().count()` on a `Vec` + --> $DIR/iter_count.rs:44:5 | -LL | let bad_slice = &some_vec[..].iter().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[..].len()` +LL | vec.iter().count(); + | ^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter().count()` on a `slice` - --> $DIR/iter_count.rs:38:31 + --> $DIR/iter_count.rs:45:5 | -LL | let bad_boxed_slice = boxed_slice.iter().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()` +LL | boxed_slice.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()` error: called `.iter().count()` on a `VecDeque` - --> $DIR/iter_count.rs:39:29 + --> $DIR/iter_count.rs:46:5 | -LL | let bad_vec_deque = some_vec_deque.iter().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec_deque.len()` +LL | vec_deque.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` error: called `.iter().count()` on a `std::iter::Iterator` - --> $DIR/iter_count.rs:40:28 + --> $DIR/iter_count.rs:47:5 | -LL | let bad_hash_set = some_hash_set.iter().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_hash_set.len()` +LL | hash_set.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()` error: called `.iter_mut().count()` on a `Vec` - --> $DIR/iter_count.rs:45:23 + --> $DIR/iter_count.rs:49:5 | -LL | let bad_vec = some_vec.iter_mut().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec.len()` +LL | vec.iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter_mut().count()` on a `slice` - --> $DIR/iter_count.rs:48:26 + --> $DIR/iter_count.rs:50:6 | -LL | let bad_slice = &some_vec[..].iter_mut().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[..].len()` +LL | &vec[..].iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` error: called `.iter_mut().count()` on a `VecDeque` - --> $DIR/iter_count.rs:51:29 + --> $DIR/iter_count.rs:51:5 + | +LL | vec_deque.iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` + +error: called `.into_iter().count()` on a `slice` + --> $DIR/iter_count.rs:53:6 + | +LL | &vec[..].into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` + +error: called `.into_iter().count()` on a `Vec` + --> $DIR/iter_count.rs:54:5 + | +LL | vec.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` + +error: called `.into_iter().count()` on a `VecDeque` + --> $DIR/iter_count.rs:55:5 | -LL | let bad_vec_deque = some_vec_deque.iter_mut().count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec_deque.len()` +LL | vec_deque.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` -error: aborting due to 8 previous errors +error: aborting due to 11 previous errors From 9958af4229d4bee06ee65b921ac11b1fe498e831 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 26 Feb 2021 02:18:52 +0900 Subject: [PATCH 025/226] move `lints()` to `iter_count.rs` --- clippy_lints/src/methods/iter_count.rs | 51 ++++++++++++++ clippy_lints/src/methods/mod.rs | 97 +++----------------------- clippy_utils/src/lib.rs | 40 +++++++++++ 3 files changed, 100 insertions(+), 88 deletions(-) create mode 100644 clippy_lints/src/methods/iter_count.rs diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs new file mode 100644 index 0000000000000..ca8723cec9498 --- /dev/null +++ b/clippy_lints/src/methods/iter_count.rs @@ -0,0 +1,51 @@ +use crate::utils::{ + derefs_to_slice, is_type_diagnostic_item, match_trait_method, method_chain_args, paths, snippet_with_applicability, + span_lint_and_sugg, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_span::sym; + +use super::ITER_COUNT; + +pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], is_mut: bool) { + let mut_str = if is_mut { "_mut" } else { "" }; + let iter_method = if method_chain_args(expr, &[format!("iter{}", mut_str).as_str(), "count"]).is_some() { + "iter" + } else if method_chain_args(expr, &["into_iter", "count"]).is_some() { + "into_iter" + } else { + return; + }; + if_chain! { + let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() { + Some("slice") + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { + Some("Vec") + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { + Some("VecDeque") + } else if match_trait_method(cx, expr, &paths::ITERATOR) { + Some("std::iter::Iterator") + } else { + None + }; + if let Some(caller_type) = caller_type; + then { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + ITER_COUNT, + expr.span, + &format!("called `.{}{}().count()` on a `{}`", iter_method, mut_str, caller_type), + "try", + format!( + "{}.len()", + snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability), + ), + applicability, + ); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index e5509ee2c4e0f..d2a926d0944f2 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -4,6 +4,7 @@ mod filter_map_identity; mod implicit_clone; mod inefficient_to_string; mod inspect_for_each; +mod iter_count; mod manual_saturating_arithmetic; mod option_map_unwrap_or; mod unnecessary_filter_map; @@ -32,12 +33,12 @@ use crate::consts::{constant, Constant}; use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::usage::mutated_variables; use crate::utils::{ - contains_return, contains_ty, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, - in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, - match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, - remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, - span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg, walk_ptrs_ty_depth, - SpanlessEq, + contains_return, contains_ty, derefs_to_slice, get_parent_expr, get_trait_def_id, has_iter_method, higher, + implements_trait, in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, + match_def_path, match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, + path_to_local_id, paths, remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, + snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, + sugg, walk_ptrs_ty_depth, SpanlessEq, }; declare_clippy_lint! { @@ -1691,8 +1692,8 @@ impl<'tcx> LateLintPass<'tcx> for Methods { lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) }, ["extend", ..] => lint_extend(cx, expr, arg_lists[0]), - ["count", "into_iter" | "iter"] => lint_iter_count(cx, expr, &arg_lists[1], false), - ["count", "iter_mut"] => lint_iter_count(cx, expr, &arg_lists[1], true), + ["count", "into_iter" | "iter"] => iter_count::lints(cx, expr, &arg_lists[1], false), + ["count", "iter_mut"] => iter_count::lints(cx, expr, &arg_lists[1], true), ["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false), ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true), ["nth", "bytes"] => bytes_nth::lints(cx, expr, &arg_lists[1]), @@ -2661,46 +2662,6 @@ fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_ } } -fn lint_iter_count<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], is_mut: bool) { - let mut_str = if is_mut { "_mut" } else { "" }; - let iter_method = if method_chain_args(expr, &[format!("iter{}", mut_str).as_str(), "count"]).is_some() { - "iter" - } else if method_chain_args(expr, &["into_iter", "count"]).is_some() { - "into_iter" - } else { - return; - }; - if_chain! { - let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() { - Some("slice") - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { - Some("Vec") - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { - Some("VecDeque") - } else if match_trait_method(cx, expr, &paths::ITERATOR) { - Some("std::iter::Iterator") - } else { - None - }; - if let Some(caller_type) = caller_type; - then { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - ITER_COUNT, - expr.span, - &format!("called `.{}{}().count()` on a `{}`", iter_method, mut_str, caller_type), - "try", - format!( - "{}.len()", - snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability), - ), - applicability, - ); - } - } -} - fn lint_iter_nth<'tcx>( cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, @@ -2841,46 +2802,6 @@ fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[ } } -fn derefs_to_slice<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'tcx>, - ty: Ty<'tcx>, -) -> Option<&'tcx hir::Expr<'tcx>> { - fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool { - match ty.kind() { - ty::Slice(_) => true, - ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), - ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::vec_type), - ty::Array(_, size) => size - .try_eval_usize(cx.tcx, cx.param_env) - .map_or(false, |size| size < 32), - ty::Ref(_, inner, _) => may_slice(cx, inner), - _ => false, - } - } - - if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { - if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(&args[0])) { - Some(&args[0]) - } else { - None - } - } else { - match ty.kind() { - ty::Slice(_) => Some(expr), - ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr), - ty::Ref(_, inner, _) => { - if may_slice(cx, inner) { - Some(expr) - } else { - None - } - }, - _ => None, - } - } -} - /// lint use of `unwrap()` for `Option`s and `Result`s fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { let obj_ty = cx.typeck_results().expr_ty(&unwrap_args[0]).peel_refs(); diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 2380ea4c7bfae..ec1b189bf77e8 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1802,6 +1802,46 @@ pub fn is_some_ctor(cx: &LateContext<'_>, res: Res) -> bool { false } +pub fn derefs_to_slice<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + ty: Ty<'tcx>, +) -> Option<&'tcx hir::Expr<'tcx>> { + fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool { + match ty.kind() { + ty::Slice(_) => true, + ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), + ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::vec_type), + ty::Array(_, size) => size + .try_eval_usize(cx.tcx, cx.param_env) + .map_or(false, |size| size < 32), + ty::Ref(_, inner, _) => may_slice(cx, inner), + _ => false, + } + } + + if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { + if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(&args[0])) { + Some(&args[0]) + } else { + None + } + } else { + match ty.kind() { + ty::Slice(_) => Some(expr), + ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr), + ty::Ref(_, inner, _) => { + if may_slice(cx, inner) { + Some(expr) + } else { + None + } + }, + _ => None, + } + } +} + #[cfg(test)] mod test { use super::{reindent_multiline, without_block_comments}; From cc2b00055ccc18f4b345a1f6d50865ada9093e88 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 26 Feb 2021 04:11:01 +0900 Subject: [PATCH 026/226] return when the ty doesn't have `len()` --- clippy_lints/src/methods/iter_count.rs | 33 +++++--- tests/ui/iter_count.fixed | 26 +++++- tests/ui/iter_count.rs | 26 +++++- tests/ui/iter_count.stderr | 110 ++++++++++++++++++++++--- 4 files changed, 169 insertions(+), 26 deletions(-) diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index ca8723cec9498..1bcdb57ad29e9 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -1,7 +1,8 @@ use crate::utils::{ - derefs_to_slice, is_type_diagnostic_item, match_trait_method, method_chain_args, paths, snippet_with_applicability, + derefs_to_slice, is_type_diagnostic_item, match_type, method_chain_args, paths, snippet_with_applicability, span_lint_and_sugg, }; + use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::Expr; @@ -19,19 +20,29 @@ pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &' } else { return; }; + let ty = cx.typeck_results().expr_ty(&iter_args[0]); if_chain! { - let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() { - Some("slice") - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { - Some("Vec") - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { - Some("VecDeque") - } else if match_trait_method(cx, expr, &paths::ITERATOR) { - Some("std::iter::Iterator") + let caller_type = if derefs_to_slice(cx, &iter_args[0], ty).is_some() { + "slice" + } else if is_type_diagnostic_item(cx, ty, sym::vec_type) { + "Vec" + } else if is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) { + "VecDeque" + } else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) { + "HashSet" + } else if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { + "HashMap" + } else if match_type(cx, ty, &paths::BTREEMAP) { + "BTreeMap" + } else if match_type(cx, ty, &paths::BTREESET) { + "BTreeSet" + } else if match_type(cx, ty, &paths::LINKED_LIST) { + "LinkedList" + } else if match_type(cx, ty, &paths::BINARY_HEAP) { + "BinaryHeap" } else { - None + return }; - if let Some(caller_type) = caller_type; then { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( diff --git a/tests/ui/iter_count.fixed b/tests/ui/iter_count.fixed index c8f896408479f..b11dadda6c24e 100644 --- a/tests/ui/iter_count.fixed +++ b/tests/ui/iter_count.fixed @@ -13,7 +13,7 @@ extern crate option_helpers; use option_helpers::IteratorFalsePositives; -use std::collections::{HashSet, VecDeque}; +use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; /// Struct to generate false positives for things with `.iter()`. #[derive(Copy, Clone)] @@ -38,21 +38,45 @@ fn main() { let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect(); let mut hash_set = HashSet::new(); + let mut hash_map = HashMap::new(); + let mut b_tree_map = BTreeMap::new(); + let mut b_tree_set = BTreeSet::new(); + let mut linked_list = LinkedList::new(); + let mut binary_heap = BinaryHeap::new(); hash_set.insert(1); + hash_map.insert(1, 2); + b_tree_map.insert(1, 2); + b_tree_set.insert(1); + linked_list.push_back(1); + binary_heap.push(1); &vec[..].len(); vec.len(); boxed_slice.len(); vec_deque.len(); hash_set.len(); + hash_map.len(); + b_tree_map.len(); + b_tree_set.len(); + linked_list.len(); + binary_heap.len(); vec.len(); &vec[..].len(); vec_deque.len(); + hash_map.len(); + b_tree_map.len(); + linked_list.len(); &vec[..].len(); vec.len(); vec_deque.len(); + hash_set.len(); + hash_map.len(); + b_tree_map.len(); + b_tree_set.len(); + linked_list.len(); + binary_heap.len(); // Make sure we don't lint for non-relevant types. let false_positive = HasIter; diff --git a/tests/ui/iter_count.rs b/tests/ui/iter_count.rs index 8ea17ef34fa63..7d49c6a3dbbb9 100644 --- a/tests/ui/iter_count.rs +++ b/tests/ui/iter_count.rs @@ -13,7 +13,7 @@ extern crate option_helpers; use option_helpers::IteratorFalsePositives; -use std::collections::{HashSet, VecDeque}; +use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; /// Struct to generate false positives for things with `.iter()`. #[derive(Copy, Clone)] @@ -38,21 +38,45 @@ fn main() { let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect(); let mut hash_set = HashSet::new(); + let mut hash_map = HashMap::new(); + let mut b_tree_map = BTreeMap::new(); + let mut b_tree_set = BTreeSet::new(); + let mut linked_list = LinkedList::new(); + let mut binary_heap = BinaryHeap::new(); hash_set.insert(1); + hash_map.insert(1, 2); + b_tree_map.insert(1, 2); + b_tree_set.insert(1); + linked_list.push_back(1); + binary_heap.push(1); &vec[..].iter().count(); vec.iter().count(); boxed_slice.iter().count(); vec_deque.iter().count(); hash_set.iter().count(); + hash_map.iter().count(); + b_tree_map.iter().count(); + b_tree_set.iter().count(); + linked_list.iter().count(); + binary_heap.iter().count(); vec.iter_mut().count(); &vec[..].iter_mut().count(); vec_deque.iter_mut().count(); + hash_map.iter_mut().count(); + b_tree_map.iter_mut().count(); + linked_list.iter_mut().count(); &vec[..].into_iter().count(); vec.into_iter().count(); vec_deque.into_iter().count(); + hash_set.into_iter().count(); + hash_map.into_iter().count(); + b_tree_map.into_iter().count(); + b_tree_set.into_iter().count(); + linked_list.into_iter().count(); + binary_heap.into_iter().count(); // Make sure we don't lint for non-relevant types. let false_positive = HasIter; diff --git a/tests/ui/iter_count.stderr b/tests/ui/iter_count.stderr index 0820c0014434b..f3fb98e65b990 100644 --- a/tests/ui/iter_count.stderr +++ b/tests/ui/iter_count.stderr @@ -1,5 +1,5 @@ error: called `.iter().count()` on a `slice` - --> $DIR/iter_count.rs:43:6 + --> $DIR/iter_count.rs:53:6 | LL | &vec[..].iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` @@ -7,64 +7,148 @@ LL | &vec[..].iter().count(); = note: `-D clippy::iter-count` implied by `-D warnings` error: called `.iter().count()` on a `Vec` - --> $DIR/iter_count.rs:44:5 + --> $DIR/iter_count.rs:54:5 | LL | vec.iter().count(); | ^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter().count()` on a `slice` - --> $DIR/iter_count.rs:45:5 + --> $DIR/iter_count.rs:55:5 | LL | boxed_slice.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()` error: called `.iter().count()` on a `VecDeque` - --> $DIR/iter_count.rs:46:5 + --> $DIR/iter_count.rs:56:5 | LL | vec_deque.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` -error: called `.iter().count()` on a `std::iter::Iterator` - --> $DIR/iter_count.rs:47:5 +error: called `.iter().count()` on a `HashSet` + --> $DIR/iter_count.rs:57:5 | LL | hash_set.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()` +error: called `.iter().count()` on a `HashMap` + --> $DIR/iter_count.rs:58:5 + | +LL | hash_map.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` + +error: called `.iter().count()` on a `BTreeMap` + --> $DIR/iter_count.rs:59:5 + | +LL | b_tree_map.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` + +error: called `.iter().count()` on a `BTreeSet` + --> $DIR/iter_count.rs:60:5 + | +LL | b_tree_set.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()` + +error: called `.iter().count()` on a `LinkedList` + --> $DIR/iter_count.rs:61:5 + | +LL | linked_list.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` + +error: called `.iter().count()` on a `BinaryHeap` + --> $DIR/iter_count.rs:62:5 + | +LL | binary_heap.iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()` + error: called `.iter_mut().count()` on a `Vec` - --> $DIR/iter_count.rs:49:5 + --> $DIR/iter_count.rs:64:5 | LL | vec.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter_mut().count()` on a `slice` - --> $DIR/iter_count.rs:50:6 + --> $DIR/iter_count.rs:65:6 | LL | &vec[..].iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` error: called `.iter_mut().count()` on a `VecDeque` - --> $DIR/iter_count.rs:51:5 + --> $DIR/iter_count.rs:66:5 | LL | vec_deque.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` +error: called `.iter_mut().count()` on a `HashMap` + --> $DIR/iter_count.rs:67:5 + | +LL | hash_map.iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` + +error: called `.iter_mut().count()` on a `BTreeMap` + --> $DIR/iter_count.rs:68:5 + | +LL | b_tree_map.iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` + +error: called `.iter_mut().count()` on a `LinkedList` + --> $DIR/iter_count.rs:69:5 + | +LL | linked_list.iter_mut().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` + error: called `.into_iter().count()` on a `slice` - --> $DIR/iter_count.rs:53:6 + --> $DIR/iter_count.rs:71:6 | LL | &vec[..].into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` error: called `.into_iter().count()` on a `Vec` - --> $DIR/iter_count.rs:54:5 + --> $DIR/iter_count.rs:72:5 | LL | vec.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.into_iter().count()` on a `VecDeque` - --> $DIR/iter_count.rs:55:5 + --> $DIR/iter_count.rs:73:5 | LL | vec_deque.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` -error: aborting due to 11 previous errors +error: called `.into_iter().count()` on a `HashSet` + --> $DIR/iter_count.rs:74:5 + | +LL | hash_set.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()` + +error: called `.into_iter().count()` on a `HashMap` + --> $DIR/iter_count.rs:75:5 + | +LL | hash_map.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` + +error: called `.into_iter().count()` on a `BTreeMap` + --> $DIR/iter_count.rs:76:5 + | +LL | b_tree_map.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` + +error: called `.into_iter().count()` on a `BTreeSet` + --> $DIR/iter_count.rs:77:5 + | +LL | b_tree_set.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()` + +error: called `.into_iter().count()` on a `LinkedList` + --> $DIR/iter_count.rs:78:5 + | +LL | linked_list.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` + +error: called `.into_iter().count()` on a `BinaryHeap` + --> $DIR/iter_count.rs:79:5 + | +LL | binary_heap.into_iter().count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()` + +error: aborting due to 25 previous errors From 8bae2797067650071b69273ecfbf55240190db07 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 26 Feb 2021 15:49:03 +0900 Subject: [PATCH 027/226] remove if_chain --- clippy_lints/src/methods/iter_count.rs | 72 ++++++++++++-------------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index 1bcdb57ad29e9..06ce06126e62c 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -21,42 +21,38 @@ pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &' return; }; let ty = cx.typeck_results().expr_ty(&iter_args[0]); - if_chain! { - let caller_type = if derefs_to_slice(cx, &iter_args[0], ty).is_some() { - "slice" - } else if is_type_diagnostic_item(cx, ty, sym::vec_type) { - "Vec" - } else if is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) { - "VecDeque" - } else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) { - "HashSet" - } else if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { - "HashMap" - } else if match_type(cx, ty, &paths::BTREEMAP) { - "BTreeMap" - } else if match_type(cx, ty, &paths::BTREESET) { - "BTreeSet" - } else if match_type(cx, ty, &paths::LINKED_LIST) { - "LinkedList" - } else if match_type(cx, ty, &paths::BINARY_HEAP) { - "BinaryHeap" - } else { - return - }; - then { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - ITER_COUNT, - expr.span, - &format!("called `.{}{}().count()` on a `{}`", iter_method, mut_str, caller_type), - "try", - format!( - "{}.len()", - snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability), - ), - applicability, - ); - } - } + let caller_type = if derefs_to_slice(cx, &iter_args[0], ty).is_some() { + "slice" + } else if is_type_diagnostic_item(cx, ty, sym::vec_type) { + "Vec" + } else if is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) { + "VecDeque" + } else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) { + "HashSet" + } else if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { + "HashMap" + } else if match_type(cx, ty, &paths::BTREEMAP) { + "BTreeMap" + } else if match_type(cx, ty, &paths::BTREESET) { + "BTreeSet" + } else if match_type(cx, ty, &paths::LINKED_LIST) { + "LinkedList" + } else if match_type(cx, ty, &paths::BINARY_HEAP) { + "BinaryHeap" + } else { + return; + }; + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + ITER_COUNT, + expr.span, + &format!("called `.{}{}().count()` on a `{}`", iter_method, mut_str, caller_type), + "try", + format!( + "{}.len()", + snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability), + ), + applicability, + ); } From 77907e6dab42dd0acc23c0cf1d540d2aa3e32bb8 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 26 Feb 2021 16:21:43 +0900 Subject: [PATCH 028/226] receive iter method name as an argument --- clippy_lints/src/methods/iter_count.rs | 16 +++------------- clippy_lints/src/methods/mod.rs | 5 +++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index 06ce06126e62c..ff3aa346e2d68 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -1,9 +1,7 @@ use crate::utils::{ - derefs_to_slice, is_type_diagnostic_item, match_type, method_chain_args, paths, snippet_with_applicability, - span_lint_and_sugg, + derefs_to_slice, is_type_diagnostic_item, match_type, paths, snippet_with_applicability, span_lint_and_sugg, }; -use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; @@ -11,15 +9,7 @@ use rustc_span::sym; use super::ITER_COUNT; -pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], is_mut: bool) { - let mut_str = if is_mut { "_mut" } else { "" }; - let iter_method = if method_chain_args(expr, &[format!("iter{}", mut_str).as_str(), "count"]).is_some() { - "iter" - } else if method_chain_args(expr, &["into_iter", "count"]).is_some() { - "into_iter" - } else { - return; - }; +pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], iter_method: &str) { let ty = cx.typeck_results().expr_ty(&iter_args[0]); let caller_type = if derefs_to_slice(cx, &iter_args[0], ty).is_some() { "slice" @@ -47,7 +37,7 @@ pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &' cx, ITER_COUNT, expr.span, - &format!("called `.{}{}().count()` on a `{}`", iter_method, mut_str, caller_type), + &format!("called `.{}().count()` on a `{}`", iter_method, caller_type), "try", format!( "{}.len()", diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index d2a926d0944f2..f394e6673d48f 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1692,8 +1692,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods { lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) }, ["extend", ..] => lint_extend(cx, expr, arg_lists[0]), - ["count", "into_iter" | "iter"] => iter_count::lints(cx, expr, &arg_lists[1], false), - ["count", "iter_mut"] => iter_count::lints(cx, expr, &arg_lists[1], true), + ["count", "into_iter"] => iter_count::lints(cx, expr, &arg_lists[1], "into_iter"), + ["count", "iter"] => iter_count::lints(cx, expr, &arg_lists[1], "iter"), + ["count", "iter_mut"] => iter_count::lints(cx, expr, &arg_lists[1], "iter_mut"), ["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false), ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true), ["nth", "bytes"] => bytes_nth::lints(cx, expr, &arg_lists[1]), From c297174adf9468234d0eebad608514879a52b82b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 26 Feb 2021 17:07:00 +0900 Subject: [PATCH 029/226] export `derefs_to_slice` from methods module --- clippy_lints/src/methods/iter_count.rs | 5 +-- clippy_lints/src/methods/mod.rs | 52 +++++++++++++++++++++++--- clippy_utils/src/lib.rs | 40 -------------------- 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index ff3aa346e2d68..1b99bacc3f1c2 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -1,6 +1,5 @@ -use crate::utils::{ - derefs_to_slice, is_type_diagnostic_item, match_type, paths, snippet_with_applicability, span_lint_and_sugg, -}; +use crate::methods::derefs_to_slice; +use crate::utils::{is_type_diagnostic_item, match_type, paths, snippet_with_applicability, span_lint_and_sugg}; use rustc_errors::Applicability; use rustc_hir::Expr; diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f394e6673d48f..30830fb0af651 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -33,12 +33,12 @@ use crate::consts::{constant, Constant}; use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::usage::mutated_variables; use crate::utils::{ - contains_return, contains_ty, derefs_to_slice, get_parent_expr, get_trait_def_id, has_iter_method, higher, - implements_trait, in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, - match_def_path, match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, - path_to_local_id, paths, remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, - snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, - sugg, walk_ptrs_ty_depth, SpanlessEq, + contains_return, contains_ty, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, + in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, + match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, + remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, + span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg, walk_ptrs_ty_depth, + SpanlessEq, }; declare_clippy_lint! { @@ -2803,6 +2803,46 @@ fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[ } } +pub(crate) fn derefs_to_slice<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + ty: Ty<'tcx>, +) -> Option<&'tcx hir::Expr<'tcx>> { + fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool { + match ty.kind() { + ty::Slice(_) => true, + ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), + ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::vec_type), + ty::Array(_, size) => size + .try_eval_usize(cx.tcx, cx.param_env) + .map_or(false, |size| size < 32), + ty::Ref(_, inner, _) => may_slice(cx, inner), + _ => false, + } + } + + if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { + if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(&args[0])) { + Some(&args[0]) + } else { + None + } + } else { + match ty.kind() { + ty::Slice(_) => Some(expr), + ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr), + ty::Ref(_, inner, _) => { + if may_slice(cx, inner) { + Some(expr) + } else { + None + } + }, + _ => None, + } + } +} + /// lint use of `unwrap()` for `Option`s and `Result`s fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { let obj_ty = cx.typeck_results().expr_ty(&unwrap_args[0]).peel_refs(); diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index ec1b189bf77e8..2380ea4c7bfae 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1802,46 +1802,6 @@ pub fn is_some_ctor(cx: &LateContext<'_>, res: Res) -> bool { false } -pub fn derefs_to_slice<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'tcx>, - ty: Ty<'tcx>, -) -> Option<&'tcx hir::Expr<'tcx>> { - fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool { - match ty.kind() { - ty::Slice(_) => true, - ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), - ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::vec_type), - ty::Array(_, size) => size - .try_eval_usize(cx.tcx, cx.param_env) - .map_or(false, |size| size < 32), - ty::Ref(_, inner, _) => may_slice(cx, inner), - _ => false, - } - } - - if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { - if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(&args[0])) { - Some(&args[0]) - } else { - None - } - } else { - match ty.kind() { - ty::Slice(_) => Some(expr), - ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr), - ty::Ref(_, inner, _) => { - if may_slice(cx, inner) { - Some(expr) - } else { - None - } - }, - _ => None, - } - } -} - #[cfg(test)] mod test { use super::{reindent_multiline, without_block_comments}; From 6041365f4bae6482467210ea1b60e18101ba6fd0 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 26 Feb 2021 17:38:21 +0900 Subject: [PATCH 030/226] remove pub(crate) --- clippy_lints/src/methods/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 30830fb0af651..4a63de3cf48df 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2803,7 +2803,7 @@ fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[ } } -pub(crate) fn derefs_to_slice<'tcx>( +fn derefs_to_slice<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, ty: Ty<'tcx>, From bdeec5dbd6e484cec26039cb795193ab044cf4d9 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Sat, 27 Feb 2021 21:52:15 +0900 Subject: [PATCH 031/226] Use TypeckResults::expr_ty instead of TyCtxt::type_of to fix "Not a type" ICE --- clippy_lints/src/default_numeric_fallback.rs | 5 ++--- .../src/inconsistent_struct_constructor.rs | 3 +-- tests/ui/crashes/ice-6792.rs | 20 +++++++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 tests/ui/crashes/ice-6792.rs diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs index 6ace9aa6bdfc0..369efacc9bcf4 100644 --- a/clippy_lints/src/default_numeric_fallback.rs +++ b/clippy_lints/src/default_numeric_fallback.rs @@ -130,10 +130,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { } }, - ExprKind::Struct(qpath, fields, base) => { + ExprKind::Struct(_, fields, base) => { if_chain! { - if let Some(def_id) = self.cx.qpath_res(qpath, expr.hir_id).opt_def_id(); - let ty = self.cx.tcx.type_of(def_id); + let ty = self.cx.typeck_results().expr_ty(expr); if let Some(adt_def) = ty.ty_adt_def(); if adt_def.is_struct(); if let Some(variant) = adt_def.variants.iter().next(); diff --git a/clippy_lints/src/inconsistent_struct_constructor.rs b/clippy_lints/src/inconsistent_struct_constructor.rs index c5afdf530eb70..4f35e13c85a1c 100644 --- a/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/clippy_lints/src/inconsistent_struct_constructor.rs @@ -66,8 +66,7 @@ impl LateLintPass<'_> for InconsistentStructConstructor { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if_chain! { if let ExprKind::Struct(qpath, fields, base) = expr.kind; - if let Some(def_id) = cx.qpath_res(qpath, expr.hir_id).opt_def_id(); - let ty = cx.tcx.type_of(def_id); + let ty = cx.typeck_results().expr_ty(expr); if let Some(adt_def) = ty.ty_adt_def(); if adt_def.is_struct(); if let Some(variant) = adt_def.variants.iter().next(); diff --git a/tests/ui/crashes/ice-6792.rs b/tests/ui/crashes/ice-6792.rs new file mode 100644 index 0000000000000..0e2ab1a39b82f --- /dev/null +++ b/tests/ui/crashes/ice-6792.rs @@ -0,0 +1,20 @@ +//! This is a reproducer for the ICE 6792: https://github.com/rust-lang/rust-clippy/issues/6792. +//! The ICE is caused by using `TyCtxt::type_of(assoc_type_id)`. + +trait Trait { + type Ty; + + fn broken() -> Self::Ty; +} + +struct Foo {} + +impl Trait for Foo { + type Ty = Foo; + + fn broken() -> Self::Ty { + Self::Ty {} + } +} + +fn main() {} From e51bb0ee26413c8db8264abe413cc06c95bd9a13 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Sat, 27 Feb 2021 22:46:10 +0900 Subject: [PATCH 032/226] Add test for ICE 6793 --- tests/ui/crashes/ice-6793.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/ui/crashes/ice-6793.rs diff --git a/tests/ui/crashes/ice-6793.rs b/tests/ui/crashes/ice-6793.rs new file mode 100644 index 0000000000000..12a4a0d25ef5d --- /dev/null +++ b/tests/ui/crashes/ice-6793.rs @@ -0,0 +1,23 @@ +//! This is a reproducer for the ICE 6793: https://github.com/rust-lang/rust-clippy/issues/6793. +//! The ICE is caused by using `TyCtxt::type_of(assoc_type_id)`, which is the same as the ICE 6792. + +trait Trait { + type Ty: 'static + Clone; + + fn broken() -> Self::Ty; +} + +#[derive(Clone)] +struct MyType { + x: i32, +} + +impl Trait for MyType { + type Ty = MyType; + + fn broken() -> Self::Ty { + Self::Ty { x: 1 } + } +} + +fn main() {} From b119b6585959b77017d75149075b22927c452207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 24 Feb 2021 13:50:11 +0100 Subject: [PATCH 033/226] tests: add test that roughly ensures that our lint messages conform with the diagnostics convention of the rustc dev guide lint message should not start with uppercase letters lint messages should not have punctuation at the end of the last line https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure The test reads through all the .stderr files in the testsuit and checks lint messages that start with "help: ", "error: " etc. There is also an exception list for special messages that are deemed acceptable. changelog: make sure lint messages conform with the rustc dev guide and add test --- Cargo.toml | 1 + tests/lint_message_convention.rs | 102 +++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 tests/lint_message_convention.rs diff --git a/Cargo.toml b/Cargo.toml index ea32a8edd1ffb..98a5be2898dcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ tester = "0.9" clippy-mini-macro-test = { version = "0.2", path = "mini-macro" } serde = { version = "1.0", features = ["derive"] } derive-new = "0.5" +regex = "1.4" # A noop dependency that changes in the Rust repository, it's a bit of a hack. # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs new file mode 100644 index 0000000000000..45e0d7336c13a --- /dev/null +++ b/tests/lint_message_convention.rs @@ -0,0 +1,102 @@ +use std::path::PathBuf; + +use regex::RegexSet; + +#[derive(Debug)] +struct Message { + path: PathBuf, + bad_lines: Vec, +} + +impl Message { + fn new(path: PathBuf) -> Self { + let content: String = std::fs::read_to_string(&path).unwrap(); + // we don't want the first letter after "error: ", "help: " ... to be capitalized + // also no puncutation (except for "?" ?) at the end of a line + let regex_set: RegexSet = RegexSet::new(&[ + r"error: [A-Z]", + r"help: [A-Z]", + r"warning: [A-Z]", + r"note: [A-Z]", + r"try this: [A-Z]", + r"error: .*[.!]$", + r"help: .*[.!]$", + r"warning: .*[.!]$", + r"note: .*[.!]$", + r"try this: .*[.!]$", + ]) + .unwrap(); + + // sometimes the first character is capitalized and it is legal (like in "Iterator...") or + // we want to ask a question ending in "?" + let exceptions_set: RegexSet = RegexSet::new(&[ + r".*error: I see you're using a LinkedList! Perhaps you meant some other data structure?", + r".*C-like enum variant discriminant is not portable to 32-bit targets", + r".*Iterator::step_by(0) will panic at runtime", + r".*did you mean `unix`?", + r".*the arguments may be inverted...", + r".*Intel x86 assembly syntax used", + r".*AT&T x86 assembly syntax used", + r".*remove .* the return type...", + r"note: Clippy version: .*", + ]) + .unwrap(); + + let bad_lines = content + .lines() + .filter(|line| regex_set.matches(line).matched_any()) + // ignore exceptions + .filter(|line| !exceptions_set.matches(line).matched_any()) + .map(|s| s.to_owned()) + .collect::>(); + + Message { path, bad_lines } + } +} + +#[test] +fn lint_message_convention() { + // make sure that lint messages: + // * are not capitalized + // * don't have puncuation at the end of the last sentence + + // these directories have interesting tests + let test_dirs = ["ui", "ui-cargo", "ui-internal", "ui-toml"] + .iter() + .map(PathBuf::from) + .map(|p| { + let base = PathBuf::from("tests"); + base.join(p) + }); + + // gather all .stderr files + let tests = test_dirs + .map(|dir| { + std::fs::read_dir(dir) + .expect("failed to read dir") + .map(|direntry| direntry.unwrap().path()) + }) + .flatten() + .filter(|file| matches!(file.extension().map(|s| s.to_str()), Some(Some("stderr")))); + + // get all files that have any "bad lines" in them + let bad_tests: Vec = tests + .map(|path| Message::new(path)) + .filter(|message| !message.bad_lines.is_empty()) + .collect(); + + bad_tests.iter().for_each(|message| { + eprintln!( + "error: the test '{}' contained the following nonconforming lines :", + message.path.display() + ); + message.bad_lines.iter().for_each(|line| eprintln!("{}", line)); + eprintln!("\n\n"); + }); + + eprintln!("\n\n\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed."); + eprintln!("Check out the rustc-dev-guide for more information:"); + eprintln!("https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure"); + + assert!(bad_tests.is_empty()); +} From 53705768824aca634ea6366acd666344611d37e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 24 Feb 2021 13:56:04 +0100 Subject: [PATCH 034/226] fix clippy lint warnings --- tests/lint_message_convention.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index 45e0d7336c13a..493bd3bf56bb6 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -1,3 +1,4 @@ +use std::ffi::OsStr; use std::path::PathBuf; use regex::RegexSet; @@ -47,7 +48,7 @@ impl Message { .filter(|line| regex_set.matches(line).matched_any()) // ignore exceptions .filter(|line| !exceptions_set.matches(line).matched_any()) - .map(|s| s.to_owned()) + .map(ToOwned::to_owned) .collect::>(); Message { path, bad_lines } @@ -71,17 +72,16 @@ fn lint_message_convention() { // gather all .stderr files let tests = test_dirs - .map(|dir| { + .flat_map(|dir| { std::fs::read_dir(dir) .expect("failed to read dir") .map(|direntry| direntry.unwrap().path()) }) - .flatten() - .filter(|file| matches!(file.extension().map(|s| s.to_str()), Some(Some("stderr")))); + .filter(|file| matches!(file.extension().map(OsStr::to_str), Some(Some("stderr")))); // get all files that have any "bad lines" in them let bad_tests: Vec = tests - .map(|path| Message::new(path)) + .map(Message::new) .filter(|message| !message.bad_lines.is_empty()) .collect(); From 8eb2bd13d0dd70131be1e21a0a0261c9dc69937a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 24 Feb 2021 14:02:51 +0100 Subject: [PATCH 035/226] update the lint messages and tests --- clippy_lints/src/assign_ops.rs | 2 +- clippy_lints/src/attrs.rs | 2 +- clippy_lints/src/await_holding_invalid.rs | 4 +- clippy_lints/src/comparison_chain.rs | 2 +- clippy_lints/src/drop_forget_ref.rs | 8 +-- clippy_lints/src/fallible_impl_from.rs | 2 +- clippy_lints/src/indexing_slicing.rs | 12 ++-- clippy_lints/src/integer_division.rs | 2 +- clippy_lints/src/loops.rs | 19 +++--- clippy_lints/src/matches.rs | 4 +- clippy_lints/src/methods/mod.rs | 4 +- .../src/methods/unnecessary_lazy_eval.rs | 2 +- clippy_lints/src/misc.rs | 4 +- clippy_lints/src/needless_question_mark.rs | 2 +- clippy_lints/src/ptr.rs | 8 +-- .../src/suspicious_operation_groupings.rs | 2 +- clippy_lints/src/transmuting_null.rs | 2 +- clippy_lints/src/types.rs | 4 +- clippy_lints/src/zero_div_zero.rs | 2 +- tests/lint_message_convention.rs | 7 +- tests/ui-toml/vec_box_sized/test.stderr | 6 +- tests/ui/assign_ops2.stderr | 18 +++--- tests/ui/await_holding_lock.stderr | 8 +-- tests/ui/await_holding_refcell_ref.stderr | 12 ++-- tests/ui/box_vec.stderr | 2 +- tests/ui/comparison_chain.stderr | 14 ++-- tests/ui/drop_forget_copy.stderr | 12 ++-- tests/ui/drop_ref.stderr | 18 +++--- tests/ui/explicit_counter_loop.stderr | 14 ++-- tests/ui/fallible_impl_from.stderr | 8 +-- tests/ui/filter_map_next.stderr | 2 +- tests/ui/filter_map_next_fixable.stderr | 2 +- tests/ui/for_loops_over_fallibles.stderr | 10 +-- tests/ui/forget_ref.stderr | 18 +++--- tests/ui/indexing_slicing_index.stderr | 24 +++---- tests/ui/indexing_slicing_slice.stderr | 48 +++++++------- tests/ui/integer_division.stderr | 6 +- tests/ui/methods.stderr | 2 +- tests/ui/methods_fixable.stderr | 2 +- tests/ui/mismatched_target_os_unix.stderr | 34 +++++----- tests/ui/needless_collect_indirect.stderr | 10 +-- tests/ui/needless_question_mark.stderr | 28 ++++---- tests/ui/needless_range_loop.stderr | 20 +++--- tests/ui/needless_range_loop2.stderr | 16 ++--- tests/ui/ptr_arg.stderr | 24 +++---- .../ui/suspicious_operation_groupings.stderr | 54 ++++++++-------- tests/ui/toplevel_ref_arg_non_rustfix.stderr | 4 +- tests/ui/transmuting_null.stderr | 6 +- tests/ui/unnecessary_lazy_eval.stderr | 64 +++++++++---------- .../ui/unnecessary_lazy_eval_unfixable.stderr | 6 +- tests/ui/used_underscore_binding.stderr | 12 ++-- tests/ui/vec_box_sized.stderr | 8 +-- tests/ui/wild_in_or_pats.stderr | 16 ++--- tests/ui/zero_div_zero.stderr | 8 +-- 54 files changed, 315 insertions(+), 315 deletions(-) diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index b3185b8884014..e13f62d04281a 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -209,7 +209,7 @@ fn lint_misrefactored_assign_op( diag.span_suggestion( expr.span, &format!( - "Did you mean `{} = {} {} {}` or `{}`? Consider replacing it with", + "did you mean `{} = {} {} {}` or `{}`? Consider replacing it with", snip_a, snip_a, op.node.as_str(), diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 652d1fa16b6de..bb7be3d472429 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -639,7 +639,7 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) { diag.span_suggestion(span, "try", sugg, Applicability::MaybeIncorrect); if !unix_suggested && is_unix(os) { - diag.help("Did you mean `unix`?"); + diag.help("did you mean `unix`?"); unix_suggested = true; } } diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index ae64c68874454..fad3aff96cc82 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -116,7 +116,7 @@ fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorType cx, AWAIT_HOLDING_LOCK, ty_cause.span, - "this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await.", + "this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await", ty_cause.scope_span.or(Some(span)), "these are all the await points this lock is held through", ); @@ -126,7 +126,7 @@ fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorType cx, AWAIT_HOLDING_REFCELL_REF, ty_cause.span, - "this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await.", + "this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await", ty_cause.scope_span.or(Some(span)), "these are all the await points this ref is held through", ); diff --git a/clippy_lints/src/comparison_chain.rs b/clippy_lints/src/comparison_chain.rs index 90d31dece1311..e309db25995fb 100644 --- a/clippy_lints/src/comparison_chain.rs +++ b/clippy_lints/src/comparison_chain.rs @@ -117,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for ComparisonChain { expr.span, "`if` chain can be rewritten with `match`", None, - "Consider rewriting the `if` chain to use `cmp` and `match`.", + "consider rewriting the `if` chain to use `cmp` and `match`", ) } } diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index a84f9c4628716..2aea00d883c41 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -98,13 +98,13 @@ declare_clippy_lint! { } const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value. \ - Dropping a reference does nothing."; + Dropping a reference does nothing"; const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \ - Forgetting a reference does nothing."; + Forgetting a reference does nothing"; const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements `Copy`. \ - Dropping a copy leaves the original intact."; + Dropping a copy leaves the original intact"; const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \ - Forgetting a copy leaves the original intact."; + Forgetting a copy leaves the original intact"; declare_lint_pass!(DropForgetRef => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]); diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index 6d522c7ef3398..f466dddc13c20 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -133,7 +133,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h move |diag| { diag.help( "`From` is intended for infallible conversions only. \ - Use `TryFrom` if there's a possibility for the conversion to fail."); + Use `TryFrom` if there's a possibility for the conversion to fail"); diag.span_note(fpu.result, "potential failure(s)"); }); } diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index 741195f3b10d5..c919ec097a239 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -132,13 +132,13 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { } let help_msg = match (range.start, range.end) { - (None, Some(_)) => "Consider using `.get(..n)`or `.get_mut(..n)` instead", - (Some(_), None) => "Consider using `.get(n..)` or .get_mut(n..)` instead", - (Some(_), Some(_)) => "Consider using `.get(n..m)` or `.get_mut(n..m)` instead", + (None, Some(_)) => "consider using `.get(..n)`or `.get_mut(..n)` instead", + (Some(_), None) => "consider using `.get(n..)` or .get_mut(n..)` instead", + (Some(_), Some(_)) => "consider using `.get(n..m)` or `.get_mut(n..m)` instead", (None, None) => return, // [..] is ok. }; - span_lint_and_help(cx, INDEXING_SLICING, expr.span, "slicing may panic.", None, help_msg); + span_lint_and_help(cx, INDEXING_SLICING, expr.span, "slicing may panic", None, help_msg); } else { // Catchall non-range index, i.e., [n] or [n << m] if let ty::Array(..) = ty.kind() { @@ -153,9 +153,9 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { cx, INDEXING_SLICING, expr.span, - "indexing may panic.", + "indexing may panic", None, - "Consider using `.get(n)` or `.get_mut(n)` instead", + "consider using `.get(n)` or `.get_mut(n)` instead", ); } } diff --git a/clippy_lints/src/integer_division.rs b/clippy_lints/src/integer_division.rs index 31181c10d23db..39b4605e72f10 100644 --- a/clippy_lints/src/integer_division.rs +++ b/clippy_lints/src/integer_division.rs @@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for IntegerDivision { expr.span, "integer division", None, - "division of integers may cause loss of precision. consider using floats.", + "division of integers may cause loss of precision. consider using floats", ); } } diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 1c9373a756c88..3ff9e18212106 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -1625,10 +1625,7 @@ fn check_for_loop_range<'tcx>( cx, NEEDLESS_RANGE_LOOP, expr.span, - &format!( - "the loop variable `{}` is only used to index `{}`.", - ident.name, indexed - ), + &format!("the loop variable `{}` is only used to index `{}`", ident.name, indexed), |diag| { multispan_sugg( diag, @@ -1763,7 +1760,7 @@ fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { arg.span, &format!( "for loop over `{0}`, which is an `Option`. This is more readably written as an \ - `if let` statement.", + `if let` statement", snippet(cx, arg.span, "_") ), None, @@ -1780,7 +1777,7 @@ fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { arg.span, &format!( "for loop over `{0}`, which is a `Result`. This is more readably written as an \ - `if let` statement.", + `if let` statement", snippet(cx, arg.span, "_") ), None, @@ -1826,7 +1823,7 @@ fn check_for_loop_explicit_counter<'tcx>( cx, EXPLICIT_COUNTER_LOOP, for_span.with_hi(arg.span.hi()), - &format!("the variable `{}` is used as a loop counter.", name), + &format!("the variable `{}` is used as a loop counter", name), "consider using", format!( "for ({}, {}) in {}.enumerate()", @@ -3055,16 +3052,16 @@ impl IterFunction { fn get_suggestion_text(&self) -> &'static str { match &self.func { IterFunctionKind::IntoIter => { - "Use the original Iterator instead of collecting it and then producing a new one" + "use the original Iterator instead of collecting it and then producing a new one" }, IterFunctionKind::Len => { - "Take the original Iterator's count instead of collecting it and finding the length" + "take the original Iterator's count instead of collecting it and finding the length" }, IterFunctionKind::IsEmpty => { - "Check if the original Iterator has anything instead of collecting it and seeing if it's empty" + "check if the original Iterator has anything instead of collecting it and seeing if it's empty" }, IterFunctionKind::Contains(_) => { - "Check if the original Iterator contains an element instead of collecting then checking" + "check if the original Iterator contains an element instead of collecting then checking" }, } } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index efc8b13942507..0d79ffbe944e5 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1173,9 +1173,9 @@ fn check_wild_in_or_pats(cx: &LateContext<'_>, arms: &[Arm<'_>]) { cx, WILDCARD_IN_OR_PATTERNS, arm.pat.span, - "wildcard pattern covers any other pattern as it will match anyway.", + "wildcard pattern covers any other pattern as it will match anyway", None, - "Consider handling `_` separately.", + "consider handling `_` separately", ); } } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 6f491144435ac..f5c01ac772987 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -3081,7 +3081,7 @@ fn lint_filter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, fil // lint if caller of `.filter().next()` is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { let msg = "called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling \ - `.find(..)` instead."; + `.find(..)` instead"; let filter_snippet = snippet(cx, filter_args[1].span, ".."); if filter_snippet.lines().count() <= 1 { let iter_snippet = snippet(cx, filter_args[0].span, ".."); @@ -3209,7 +3209,7 @@ fn lint_filter_map_next<'tcx>( } let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \ - `.find_map(..)` instead."; + `.find_map(..)` instead"; let filter_snippet = snippet(cx, filter_args[1].span, ".."); if filter_snippet.lines().count() <= 1 { let iter_snippet = snippet(cx, filter_args[0].span, ".."); diff --git a/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/clippy_lints/src/methods/unnecessary_lazy_eval.rs index a867bdb326d72..40ccb8c80b342 100644 --- a/clippy_lints/src/methods/unnecessary_lazy_eval.rs +++ b/clippy_lints/src/methods/unnecessary_lazy_eval.rs @@ -50,7 +50,7 @@ pub(super) fn lint<'tcx>( UNNECESSARY_LAZY_EVALUATIONS, expr.span, msg, - &format!("Use `{}` instead", simplify_using), + &format!("use `{}` instead", simplify_using), format!( "{0}.{1}({2})", snippet(cx, args[0].span, ".."), diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 2ef5c6aa2a4e2..12f91d7bf639b 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -292,7 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints { TOPLEVEL_REF_ARG, arg.pat.span, "`ref` directly on a function argument is ignored. \ - Consider using a reference type instead.", + Consider using a reference type instead", ); } } @@ -422,7 +422,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints { expr.span, &format!( "used binding `{}` which is prefixed with an underscore. A leading \ - underscore signals that a binding will not be used.", + underscore signals that a binding will not be used", binding ), ); diff --git a/clippy_lints/src/needless_question_mark.rs b/clippy_lints/src/needless_question_mark.rs index fe8d4d07abc15..a3293f1b36149 100644 --- a/clippy_lints/src/needless_question_mark.rs +++ b/clippy_lints/src/needless_question_mark.rs @@ -142,7 +142,7 @@ fn emit_lint(cx: &LateContext<'_>, expr: &SomeOkCall<'_>) { cx, NEEDLESS_QUESTION_MARK, entire_expr.span, - "Question mark operator is useless here", + "question mark operator is useless here", "try", format!("{}", utils::snippet(cx, inner_expr.span, r#""...""#)), Applicability::MachineApplicable, diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index de2fb8decb715..5474fdf30bfaf 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -188,7 +188,7 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: PTR_ARG, arg.span, "writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \ - with non-Vec-based slices.", + with non-Vec-based slices", |diag| { if let Some(ref snippet) = get_only_generic_arg_snippet(cx, arg) { diag.span_suggestion( @@ -217,7 +217,7 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: cx, PTR_ARG, arg.span, - "writing `&String` instead of `&str` involves a new object where a slice will do.", + "writing `&String` instead of `&str` involves a new object where a slice will do", |diag| { diag.span_suggestion(arg.span, "change this to", "&str".into(), Applicability::Unspecified); for (clonespan, suggestion) in spans { @@ -239,7 +239,7 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: cx, PTR_ARG, arg.span, - "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do.", + "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do", |diag| { diag.span_suggestion( arg.span, @@ -278,7 +278,7 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: cx, PTR_ARG, arg.span, - "using a reference to `Cow` is not recommended.", + "using a reference to `Cow` is not recommended", "change this to", "&".to_owned() + &r, Applicability::Unspecified, diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index cccd24ccf9401..2ff30698043dc 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -261,7 +261,7 @@ fn emit_suggestion(cx: &EarlyContext<'_>, span: Span, sugg: String, applicabilit cx, SUSPICIOUS_OPERATION_GROUPINGS, span, - "This sequence of operators looks suspiciously like a bug.", + "this sequence of operators looks suspiciously like a bug", "I think you meant", sugg, applicability, diff --git a/clippy_lints/src/transmuting_null.rs b/clippy_lints/src/transmuting_null.rs index 6b171a0fa1af2..2ba2b646f004f 100644 --- a/clippy_lints/src/transmuting_null.rs +++ b/clippy_lints/src/transmuting_null.rs @@ -27,7 +27,7 @@ declare_clippy_lint! { declare_lint_pass!(TransmutingNull => [TRANSMUTING_NULL]); -const LINT_MSG: &str = "transmuting a known null pointer into a reference."; +const LINT_MSG: &str = "transmuting a known null pointer into a reference"; impl<'tcx> LateLintPass<'tcx> for TransmutingNull { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index af8d6865f93aa..a18cba6fb44bd 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -388,7 +388,7 @@ impl Types { hir_ty.span, "you seem to be trying to use `Box>`. Consider using just `Vec`", None, - "`Vec` is already on the heap, `Box>` makes an extra allocation.", + "`Vec` is already on the heap, `Box>` makes an extra allocation", ); return; // don't recurse into the type } @@ -554,7 +554,7 @@ impl Types { cx, VEC_BOX, hir_ty.span, - "`Vec` is already on the heap, the boxing is unnecessary.", + "`Vec` is already on the heap, the boxing is unnecessary", "try", format!("Vec<{}>", snippet(cx, boxed_ty.span, "..")), Applicability::MachineApplicable, diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index 4b81a27632d8d..11d96e15ff151 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for ZeroDiv { "constant division of `0.0` with `0.0` will always result in NaN", None, &format!( - "Consider using `{}::NAN` if you would like a constant representing NaN", + "consider using `{}::NAN` if you would like a constant representing NaN", float_type, ), ); diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index 493bd3bf56bb6..e316a884996d4 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -38,8 +38,11 @@ impl Message { r".*the arguments may be inverted...", r".*Intel x86 assembly syntax used", r".*AT&T x86 assembly syntax used", - r".*remove .* the return type...", + r".*remove .*the return type...", r"note: Clippy version: .*", + r"the compiler unexpectedly panicked. this is a bug.", + r".*help: I think you meant: .*", + r"Iterator.* will panic at runtime", ]) .unwrap(); @@ -96,7 +99,7 @@ fn lint_message_convention() { eprintln!("\n\n\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed."); eprintln!("Check out the rustc-dev-guide for more information:"); - eprintln!("https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure"); + eprintln!("https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure\n\n\n"); assert!(bad_tests.is_empty()); } diff --git a/tests/ui-toml/vec_box_sized/test.stderr b/tests/ui-toml/vec_box_sized/test.stderr index 3bdeca0bc8774..cf194de3c5537 100644 --- a/tests/ui-toml/vec_box_sized/test.stderr +++ b/tests/ui-toml/vec_box_sized/test.stderr @@ -1,4 +1,4 @@ -error: `Vec` is already on the heap, the boxing is unnecessary. +error: `Vec` is already on the heap, the boxing is unnecessary --> $DIR/test.rs:9:12 | LL | struct Foo(Vec>); @@ -6,13 +6,13 @@ LL | struct Foo(Vec>); | = note: `-D clippy::vec-box` implied by `-D warnings` -error: `Vec` is already on the heap, the boxing is unnecessary. +error: `Vec` is already on the heap, the boxing is unnecessary --> $DIR/test.rs:10:12 | LL | struct Bar(Vec>); | ^^^^^^^^^^^^^ help: try: `Vec` -error: `Vec` is already on the heap, the boxing is unnecessary. +error: `Vec` is already on the heap, the boxing is unnecessary --> $DIR/test.rs:13:18 | LL | struct FooBarBaz(Vec>); diff --git a/tests/ui/assign_ops2.stderr b/tests/ui/assign_ops2.stderr index 70b15d18a568b..e40668ed339f2 100644 --- a/tests/ui/assign_ops2.stderr +++ b/tests/ui/assign_ops2.stderr @@ -5,7 +5,7 @@ LL | a += a + 1; | ^^^^^^^^^^ | = note: `-D clippy::misrefactored-assign-op` implied by `-D warnings` -help: Did you mean `a = a + 1` or `a = a + a + 1`? Consider replacing it with +help: did you mean `a = a + 1` or `a = a + a + 1`? Consider replacing it with | LL | a += 1; | ^^^^^^ @@ -20,7 +20,7 @@ error: variable appears on both sides of an assignment operation LL | a += 1 + a; | ^^^^^^^^^^ | -help: Did you mean `a = a + 1` or `a = a + 1 + a`? Consider replacing it with +help: did you mean `a = a + 1` or `a = a + 1 + a`? Consider replacing it with | LL | a += 1; | ^^^^^^ @@ -35,7 +35,7 @@ error: variable appears on both sides of an assignment operation LL | a -= a - 1; | ^^^^^^^^^^ | -help: Did you mean `a = a - 1` or `a = a - (a - 1)`? Consider replacing it with +help: did you mean `a = a - 1` or `a = a - (a - 1)`? Consider replacing it with | LL | a -= 1; | ^^^^^^ @@ -50,7 +50,7 @@ error: variable appears on both sides of an assignment operation LL | a *= a * 99; | ^^^^^^^^^^^ | -help: Did you mean `a = a * 99` or `a = a * a * 99`? Consider replacing it with +help: did you mean `a = a * 99` or `a = a * a * 99`? Consider replacing it with | LL | a *= 99; | ^^^^^^^ @@ -65,7 +65,7 @@ error: variable appears on both sides of an assignment operation LL | a *= 42 * a; | ^^^^^^^^^^^ | -help: Did you mean `a = a * 42` or `a = a * 42 * a`? Consider replacing it with +help: did you mean `a = a * 42` or `a = a * 42 * a`? Consider replacing it with | LL | a *= 42; | ^^^^^^^ @@ -80,7 +80,7 @@ error: variable appears on both sides of an assignment operation LL | a /= a / 2; | ^^^^^^^^^^ | -help: Did you mean `a = a / 2` or `a = a / (a / 2)`? Consider replacing it with +help: did you mean `a = a / 2` or `a = a / (a / 2)`? Consider replacing it with | LL | a /= 2; | ^^^^^^ @@ -95,7 +95,7 @@ error: variable appears on both sides of an assignment operation LL | a %= a % 5; | ^^^^^^^^^^ | -help: Did you mean `a = a % 5` or `a = a % (a % 5)`? Consider replacing it with +help: did you mean `a = a % 5` or `a = a % (a % 5)`? Consider replacing it with | LL | a %= 5; | ^^^^^^ @@ -110,7 +110,7 @@ error: variable appears on both sides of an assignment operation LL | a &= a & 1; | ^^^^^^^^^^ | -help: Did you mean `a = a & 1` or `a = a & a & 1`? Consider replacing it with +help: did you mean `a = a & 1` or `a = a & a & 1`? Consider replacing it with | LL | a &= 1; | ^^^^^^ @@ -125,7 +125,7 @@ error: variable appears on both sides of an assignment operation LL | a *= a * a; | ^^^^^^^^^^ | -help: Did you mean `a = a * a` or `a = a * a * a`? Consider replacing it with +help: did you mean `a = a * a` or `a = a * a * a`? Consider replacing it with | LL | a *= a; | ^^^^^^ diff --git a/tests/ui/await_holding_lock.stderr b/tests/ui/await_holding_lock.stderr index 21bf49d16f048..a5fcff7e0e443 100644 --- a/tests/ui/await_holding_lock.stderr +++ b/tests/ui/await_holding_lock.stderr @@ -1,4 +1,4 @@ -error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await. +error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await --> $DIR/await_holding_lock.rs:7:9 | LL | let guard = x.lock().unwrap(); @@ -13,7 +13,7 @@ LL | | baz().await LL | | } | |_^ -error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await. +error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await --> $DIR/await_holding_lock.rs:28:9 | LL | let guard = x.lock().unwrap(); @@ -31,7 +31,7 @@ LL | | first + second + third LL | | } | |_^ -error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await. +error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await --> $DIR/await_holding_lock.rs:41:13 | LL | let guard = x.lock().unwrap(); @@ -45,7 +45,7 @@ LL | | baz().await LL | | }; | |_____^ -error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await. +error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await --> $DIR/await_holding_lock.rs:53:13 | LL | let guard = x.lock().unwrap(); diff --git a/tests/ui/await_holding_refcell_ref.stderr b/tests/ui/await_holding_refcell_ref.stderr index b504f04549136..55e41dbca96f8 100644 --- a/tests/ui/await_holding_refcell_ref.stderr +++ b/tests/ui/await_holding_refcell_ref.stderr @@ -1,4 +1,4 @@ -error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. +error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await --> $DIR/await_holding_refcell_ref.rs:7:9 | LL | let b = x.borrow(); @@ -13,7 +13,7 @@ LL | | baz().await LL | | } | |_^ -error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. +error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await --> $DIR/await_holding_refcell_ref.rs:12:9 | LL | let b = x.borrow_mut(); @@ -27,7 +27,7 @@ LL | | baz().await LL | | } | |_^ -error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. +error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await --> $DIR/await_holding_refcell_ref.rs:33:9 | LL | let b = x.borrow_mut(); @@ -45,7 +45,7 @@ LL | | first + second + third LL | | } | |_^ -error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. +error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await --> $DIR/await_holding_refcell_ref.rs:45:9 | LL | let b = x.borrow_mut(); @@ -63,7 +63,7 @@ LL | | first + second + third LL | | } | |_^ -error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. +error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await --> $DIR/await_holding_refcell_ref.rs:60:13 | LL | let b = x.borrow_mut(); @@ -77,7 +77,7 @@ LL | | baz().await LL | | }; | |_____^ -error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. +error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await --> $DIR/await_holding_refcell_ref.rs:72:13 | LL | let b = x.borrow_mut(); diff --git a/tests/ui/box_vec.stderr b/tests/ui/box_vec.stderr index fca12eddd573f..9b789334baeec 100644 --- a/tests/ui/box_vec.stderr +++ b/tests/ui/box_vec.stderr @@ -5,7 +5,7 @@ LL | pub fn test(foo: Box>) { | ^^^^^^^^^^^^^^ | = note: `-D clippy::box-vec` implied by `-D warnings` - = help: `Vec` is already on the heap, `Box>` makes an extra allocation. + = help: `Vec` is already on the heap, `Box>` makes an extra allocation error: aborting due to previous error diff --git a/tests/ui/comparison_chain.stderr b/tests/ui/comparison_chain.stderr index 69db88b03b5b5..be25a80dde0a1 100644 --- a/tests/ui/comparison_chain.stderr +++ b/tests/ui/comparison_chain.stderr @@ -9,7 +9,7 @@ LL | | } | |_____^ | = note: `-D clippy::comparison-chain` implied by `-D warnings` - = help: Consider rewriting the `if` chain to use `cmp` and `match`. + = help: consider rewriting the `if` chain to use `cmp` and `match` error: `if` chain can be rewritten with `match` --> $DIR/comparison_chain.rs:27:5 @@ -23,7 +23,7 @@ LL | | c() LL | | } | |_____^ | - = help: Consider rewriting the `if` chain to use `cmp` and `match`. + = help: consider rewriting the `if` chain to use `cmp` and `match` error: `if` chain can be rewritten with `match` --> $DIR/comparison_chain.rs:35:5 @@ -37,7 +37,7 @@ LL | | c() LL | | } | |_____^ | - = help: Consider rewriting the `if` chain to use `cmp` and `match`. + = help: consider rewriting the `if` chain to use `cmp` and `match` error: `if` chain can be rewritten with `match` --> $DIR/comparison_chain.rs:43:5 @@ -51,7 +51,7 @@ LL | | c() LL | | } | |_____^ | - = help: Consider rewriting the `if` chain to use `cmp` and `match`. + = help: consider rewriting the `if` chain to use `cmp` and `match` error: `if` chain can be rewritten with `match` --> $DIR/comparison_chain.rs:117:5 @@ -63,7 +63,7 @@ LL | | b() LL | | } | |_____^ | - = help: Consider rewriting the `if` chain to use `cmp` and `match`. + = help: consider rewriting the `if` chain to use `cmp` and `match` error: `if` chain can be rewritten with `match` --> $DIR/comparison_chain.rs:123:5 @@ -77,7 +77,7 @@ LL | | c() LL | | } | |_____^ | - = help: Consider rewriting the `if` chain to use `cmp` and `match`. + = help: consider rewriting the `if` chain to use `cmp` and `match` error: `if` chain can be rewritten with `match` --> $DIR/comparison_chain.rs:131:5 @@ -91,7 +91,7 @@ LL | | c() LL | | } | |_____^ | - = help: Consider rewriting the `if` chain to use `cmp` and `match`. + = help: consider rewriting the `if` chain to use `cmp` and `match` error: aborting due to 7 previous errors diff --git a/tests/ui/drop_forget_copy.stderr b/tests/ui/drop_forget_copy.stderr index 82a4f047ba858..01de0be7caea9 100644 --- a/tests/ui/drop_forget_copy.stderr +++ b/tests/ui/drop_forget_copy.stderr @@ -1,4 +1,4 @@ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact. +error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact --> $DIR/drop_forget_copy.rs:33:5 | LL | drop(s1); @@ -11,7 +11,7 @@ note: argument has type SomeStruct LL | drop(s1); | ^^ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact. +error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact --> $DIR/drop_forget_copy.rs:34:5 | LL | drop(s2); @@ -23,7 +23,7 @@ note: argument has type SomeStruct LL | drop(s2); | ^^ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact. +error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact --> $DIR/drop_forget_copy.rs:36:5 | LL | drop(s4); @@ -35,7 +35,7 @@ note: argument has type SomeStruct LL | drop(s4); | ^^ -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact. +error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact --> $DIR/drop_forget_copy.rs:39:5 | LL | forget(s1); @@ -48,7 +48,7 @@ note: argument has type SomeStruct LL | forget(s1); | ^^ -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact. +error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact --> $DIR/drop_forget_copy.rs:40:5 | LL | forget(s2); @@ -60,7 +60,7 @@ note: argument has type SomeStruct LL | forget(s2); | ^^ -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact. +error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact --> $DIR/drop_forget_copy.rs:42:5 | LL | forget(s4); diff --git a/tests/ui/drop_ref.stderr b/tests/ui/drop_ref.stderr index 10087cb4820a7..531849f0680ae 100644 --- a/tests/ui/drop_ref.stderr +++ b/tests/ui/drop_ref.stderr @@ -1,4 +1,4 @@ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:11:5 | LL | drop(&SomeStruct); @@ -11,7 +11,7 @@ note: argument has type `&SomeStruct` LL | drop(&SomeStruct); | ^^^^^^^^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:14:5 | LL | drop(&owned1); @@ -23,7 +23,7 @@ note: argument has type `&SomeStruct` LL | drop(&owned1); | ^^^^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:15:5 | LL | drop(&&owned1); @@ -35,7 +35,7 @@ note: argument has type `&&SomeStruct` LL | drop(&&owned1); | ^^^^^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:16:5 | LL | drop(&mut owned1); @@ -47,7 +47,7 @@ note: argument has type `&mut SomeStruct` LL | drop(&mut owned1); | ^^^^^^^^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:20:5 | LL | drop(reference1); @@ -59,7 +59,7 @@ note: argument has type `&SomeStruct` LL | drop(reference1); | ^^^^^^^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:23:5 | LL | drop(reference2); @@ -71,7 +71,7 @@ note: argument has type `&mut SomeStruct` LL | drop(reference2); | ^^^^^^^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:26:5 | LL | drop(reference3); @@ -83,7 +83,7 @@ note: argument has type `&SomeStruct` LL | drop(reference3); | ^^^^^^^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:31:5 | LL | drop(&val); @@ -95,7 +95,7 @@ note: argument has type `&T` LL | drop(&val); | ^^^^ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing. +error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:39:5 | LL | std::mem::drop(&SomeStruct); diff --git a/tests/ui/explicit_counter_loop.stderr b/tests/ui/explicit_counter_loop.stderr index 931af46efe663..4cbacffe87bf4 100644 --- a/tests/ui/explicit_counter_loop.stderr +++ b/tests/ui/explicit_counter_loop.stderr @@ -1,4 +1,4 @@ -error: the variable `_index` is used as a loop counter. +error: the variable `_index` is used as a loop counter --> $DIR/explicit_counter_loop.rs:6:5 | LL | for _v in &vec { @@ -6,37 +6,37 @@ LL | for _v in &vec { | = note: `-D clippy::explicit-counter-loop` implied by `-D warnings` -error: the variable `_index` is used as a loop counter. +error: the variable `_index` is used as a loop counter --> $DIR/explicit_counter_loop.rs:12:5 | LL | for _v in &vec { | ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter().enumerate()` -error: the variable `_index` is used as a loop counter. +error: the variable `_index` is used as a loop counter --> $DIR/explicit_counter_loop.rs:17:5 | LL | for _v in &mut vec { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter_mut().enumerate()` -error: the variable `_index` is used as a loop counter. +error: the variable `_index` is used as a loop counter --> $DIR/explicit_counter_loop.rs:22:5 | LL | for _v in vec { | ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()` -error: the variable `count` is used as a loop counter. +error: the variable `count` is used as a loop counter --> $DIR/explicit_counter_loop.rs:61:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` -error: the variable `count` is used as a loop counter. +error: the variable `count` is used as a loop counter --> $DIR/explicit_counter_loop.rs:72:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` -error: the variable `count` is used as a loop counter. +error: the variable `count` is used as a loop counter --> $DIR/explicit_counter_loop.rs:130:9 | LL | for _i in 3..10 { diff --git a/tests/ui/fallible_impl_from.stderr b/tests/ui/fallible_impl_from.stderr index f787b30bdabc5..a938d234fa07b 100644 --- a/tests/ui/fallible_impl_from.stderr +++ b/tests/ui/fallible_impl_from.stderr @@ -13,7 +13,7 @@ note: the lint level is defined here | LL | #![deny(clippy::fallible_impl_from)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail. + = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) --> $DIR/fallible_impl_from.rs:7:13 | @@ -32,7 +32,7 @@ LL | | } LL | | } | |_^ | - = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail. + = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) --> $DIR/fallible_impl_from.rs:29:13 | @@ -52,7 +52,7 @@ LL | | } LL | | } | |_^ | - = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail. + = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) --> $DIR/fallible_impl_from.rs:37:17 | @@ -79,7 +79,7 @@ LL | | } LL | | } | |_^ | - = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail. + = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) --> $DIR/fallible_impl_from.rs:55:12 | diff --git a/tests/ui/filter_map_next.stderr b/tests/ui/filter_map_next.stderr index 45427684d96e1..ddc982c93fe6d 100644 --- a/tests/ui/filter_map_next.stderr +++ b/tests/ui/filter_map_next.stderr @@ -1,4 +1,4 @@ -error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead. +error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead --> $DIR/filter_map_next.rs:7:26 | LL | let _: Option = vec![1, 2, 3, 4, 5, 6] diff --git a/tests/ui/filter_map_next_fixable.stderr b/tests/ui/filter_map_next_fixable.stderr index 6c2530e0379e4..3bb062ffd7a32 100644 --- a/tests/ui/filter_map_next_fixable.stderr +++ b/tests/ui/filter_map_next_fixable.stderr @@ -1,4 +1,4 @@ -error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead. +error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead --> $DIR/filter_map_next_fixable.rs:8:32 | LL | let element: Option = a.iter().filter_map(|s| s.parse().ok()).next(); diff --git a/tests/ui/for_loops_over_fallibles.stderr b/tests/ui/for_loops_over_fallibles.stderr index bef228d4b93af..52b94875aec4d 100644 --- a/tests/ui/for_loops_over_fallibles.stderr +++ b/tests/ui/for_loops_over_fallibles.stderr @@ -1,4 +1,4 @@ -error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement. +error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement --> $DIR/for_loops_over_fallibles.rs:9:14 | LL | for x in option { @@ -7,7 +7,7 @@ LL | for x in option { = note: `-D clippy::for-loops-over-fallibles` implied by `-D warnings` = help: consider replacing `for x in option` with `if let Some(x) = option` -error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement. +error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement --> $DIR/for_loops_over_fallibles.rs:14:14 | LL | for x in result { @@ -15,7 +15,7 @@ LL | for x in result { | = help: consider replacing `for x in result` with `if let Ok(x) = result` -error: for loop over `option.ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement. +error: for loop over `option.ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement --> $DIR/for_loops_over_fallibles.rs:18:14 | LL | for x in option.ok_or("x not found") { @@ -31,7 +31,7 @@ LL | for x in v.iter().next() { | = note: `#[deny(clippy::iter_next_loop)]` on by default -error: for loop over `v.iter().next().and(Some(0))`, which is an `Option`. This is more readably written as an `if let` statement. +error: for loop over `v.iter().next().and(Some(0))`, which is an `Option`. This is more readably written as an `if let` statement --> $DIR/for_loops_over_fallibles.rs:29:14 | LL | for x in v.iter().next().and(Some(0)) { @@ -39,7 +39,7 @@ LL | for x in v.iter().next().and(Some(0)) { | = help: consider replacing `for x in v.iter().next().and(Some(0))` with `if let Some(x) = v.iter().next().and(Some(0))` -error: for loop over `v.iter().next().ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement. +error: for loop over `v.iter().next().ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement --> $DIR/for_loops_over_fallibles.rs:33:14 | LL | for x in v.iter().next().ok_or("x not found") { diff --git a/tests/ui/forget_ref.stderr b/tests/ui/forget_ref.stderr index b2c7f2023bfbf..73409388ed16a 100644 --- a/tests/ui/forget_ref.stderr +++ b/tests/ui/forget_ref.stderr @@ -1,4 +1,4 @@ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:10:5 | LL | forget(&SomeStruct); @@ -11,7 +11,7 @@ note: argument has type `&SomeStruct` LL | forget(&SomeStruct); | ^^^^^^^^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:13:5 | LL | forget(&owned); @@ -23,7 +23,7 @@ note: argument has type `&SomeStruct` LL | forget(&owned); | ^^^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:14:5 | LL | forget(&&owned); @@ -35,7 +35,7 @@ note: argument has type `&&SomeStruct` LL | forget(&&owned); | ^^^^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:15:5 | LL | forget(&mut owned); @@ -47,7 +47,7 @@ note: argument has type `&mut SomeStruct` LL | forget(&mut owned); | ^^^^^^^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:19:5 | LL | forget(&*reference1); @@ -59,7 +59,7 @@ note: argument has type `&SomeStruct` LL | forget(&*reference1); | ^^^^^^^^^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:22:5 | LL | forget(reference2); @@ -71,7 +71,7 @@ note: argument has type `&mut SomeStruct` LL | forget(reference2); | ^^^^^^^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:25:5 | LL | forget(reference3); @@ -83,7 +83,7 @@ note: argument has type `&SomeStruct` LL | forget(reference3); | ^^^^^^^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:30:5 | LL | forget(&val); @@ -95,7 +95,7 @@ note: argument has type `&T` LL | forget(&val); | ^^^^ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing. +error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:38:5 | LL | std::mem::forget(&SomeStruct); diff --git a/tests/ui/indexing_slicing_index.stderr b/tests/ui/indexing_slicing_index.stderr index 2f6c9e2f4e5a0..76ecec3348400 100644 --- a/tests/ui/indexing_slicing_index.stderr +++ b/tests/ui/indexing_slicing_index.stderr @@ -1,51 +1,51 @@ -error: indexing may panic. +error: indexing may panic --> $DIR/indexing_slicing_index.rs:10:5 | LL | x[index]; | ^^^^^^^^ | = note: `-D clippy::indexing-slicing` implied by `-D warnings` - = help: Consider using `.get(n)` or `.get_mut(n)` instead + = help: consider using `.get(n)` or `.get_mut(n)` instead -error: indexing may panic. +error: indexing may panic --> $DIR/indexing_slicing_index.rs:22:5 | LL | v[0]; | ^^^^ | - = help: Consider using `.get(n)` or `.get_mut(n)` instead + = help: consider using `.get(n)` or `.get_mut(n)` instead -error: indexing may panic. +error: indexing may panic --> $DIR/indexing_slicing_index.rs:23:5 | LL | v[10]; | ^^^^^ | - = help: Consider using `.get(n)` or `.get_mut(n)` instead + = help: consider using `.get(n)` or `.get_mut(n)` instead -error: indexing may panic. +error: indexing may panic --> $DIR/indexing_slicing_index.rs:24:5 | LL | v[1 << 3]; | ^^^^^^^^^ | - = help: Consider using `.get(n)` or `.get_mut(n)` instead + = help: consider using `.get(n)` or `.get_mut(n)` instead -error: indexing may panic. +error: indexing may panic --> $DIR/indexing_slicing_index.rs:30:5 | LL | v[N]; | ^^^^ | - = help: Consider using `.get(n)` or `.get_mut(n)` instead + = help: consider using `.get(n)` or `.get_mut(n)` instead -error: indexing may panic. +error: indexing may panic --> $DIR/indexing_slicing_index.rs:31:5 | LL | v[M]; | ^^^^ | - = help: Consider using `.get(n)` or `.get_mut(n)` instead + = help: consider using `.get(n)` or `.get_mut(n)` instead error: aborting due to 6 previous errors diff --git a/tests/ui/indexing_slicing_slice.stderr b/tests/ui/indexing_slicing_slice.stderr index 2231deee833ee..f70722b92a5b8 100644 --- a/tests/ui/indexing_slicing_slice.stderr +++ b/tests/ui/indexing_slicing_slice.stderr @@ -1,51 +1,51 @@ -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:12:6 | LL | &x[index..]; | ^^^^^^^^^^ | = note: `-D clippy::indexing-slicing` implied by `-D warnings` - = help: Consider using `.get(n..)` or .get_mut(n..)` instead + = help: consider using `.get(n..)` or .get_mut(n..)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:13:6 | LL | &x[..index]; | ^^^^^^^^^^ | - = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + = help: consider using `.get(..n)`or `.get_mut(..n)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:14:6 | LL | &x[index_from..index_to]; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead + = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:15:6 | LL | &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to]. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + = help: consider using `.get(..n)`or `.get_mut(..n)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:15:6 | LL | &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to]. | ^^^^^^^^^^^^^^^ | - = help: Consider using `.get(n..)` or .get_mut(n..)` instead + = help: consider using `.get(n..)` or .get_mut(n..)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:16:6 | LL | &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and another for slicing [..10]. | ^^^^^^^^^^^^ | - = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds --> $DIR/indexing_slicing_slice.rs:16:8 @@ -55,21 +55,21 @@ LL | &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and ano | = note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings` -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:17:6 | LL | &x[0..][..3]; | ^^^^^^^^^^^ | - = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + = help: consider using `.get(..n)`or `.get_mut(..n)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:18:6 | LL | &x[1..][..5]; | ^^^^^^^^^^^ | - = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds --> $DIR/indexing_slicing_slice.rs:25:12 @@ -83,21 +83,21 @@ error: range is out of bounds LL | &y[..=4]; | ^ -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:31:6 | LL | &v[10..100]; | ^^^^^^^^^^ | - = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead + = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:32:6 | LL | &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100]. | ^^^^^^^^^^^^^^ | - = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds --> $DIR/indexing_slicing_slice.rs:32:8 @@ -105,21 +105,21 @@ error: range is out of bounds LL | &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100]. | ^^ -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:33:6 | LL | &v[10..]; | ^^^^^^^ | - = help: Consider using `.get(n..)` or .get_mut(n..)` instead + = help: consider using `.get(n..)` or .get_mut(n..)` instead -error: slicing may panic. +error: slicing may panic --> $DIR/indexing_slicing_slice.rs:34:6 | LL | &v[..100]; | ^^^^^^^^ | - = help: Consider using `.get(..n)`or `.get_mut(..n)` instead + = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: aborting due to 16 previous errors diff --git a/tests/ui/integer_division.stderr b/tests/ui/integer_division.stderr index 72a232ef3d750..cbb7f88142495 100644 --- a/tests/ui/integer_division.stderr +++ b/tests/ui/integer_division.stderr @@ -5,7 +5,7 @@ LL | let n = 1 / 2; | ^^^^^ | = note: `-D clippy::integer-division` implied by `-D warnings` - = help: division of integers may cause loss of precision. consider using floats. + = help: division of integers may cause loss of precision. consider using floats error: integer division --> $DIR/integer_division.rs:6:13 @@ -13,7 +13,7 @@ error: integer division LL | let o = 1 / two; | ^^^^^^^ | - = help: division of integers may cause loss of precision. consider using floats. + = help: division of integers may cause loss of precision. consider using floats error: integer division --> $DIR/integer_division.rs:7:13 @@ -21,7 +21,7 @@ error: integer division LL | let p = two / 4; | ^^^^^^^ | - = help: division of integers may cause loss of precision. consider using floats. + = help: division of integers may cause loss of precision. consider using floats error: aborting due to 3 previous errors diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index 33aba630a5304..4643e09e27028 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -8,7 +8,7 @@ LL | | } | = note: `-D clippy::new-ret-no-self` implied by `-D warnings` -error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead. +error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead --> $DIR/methods.rs:126:13 | LL | let _ = v.iter().filter(|&x| { diff --git a/tests/ui/methods_fixable.stderr b/tests/ui/methods_fixable.stderr index 70e7c3dea545b..852f48e32d678 100644 --- a/tests/ui/methods_fixable.stderr +++ b/tests/ui/methods_fixable.stderr @@ -1,4 +1,4 @@ -error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead. +error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead --> $DIR/methods_fixable.rs:10:13 | LL | let _ = v.iter().filter(|&x| *x < 0).next(); diff --git a/tests/ui/mismatched_target_os_unix.stderr b/tests/ui/mismatched_target_os_unix.stderr index fe9aeedb59c45..ea39f5b5577be 100644 --- a/tests/ui/mismatched_target_os_unix.stderr +++ b/tests/ui/mismatched_target_os_unix.stderr @@ -7,7 +7,7 @@ LL | #[cfg(linux)] | help: try: `target_os = "linux"` | = note: `-D clippy::mismatched-target-os` implied by `-D warnings` - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:9:1 @@ -17,7 +17,7 @@ LL | #[cfg(freebsd)] | | | help: try: `target_os = "freebsd"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:12:1 @@ -27,7 +27,7 @@ LL | #[cfg(dragonfly)] | | | help: try: `target_os = "dragonfly"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:15:1 @@ -37,7 +37,7 @@ LL | #[cfg(openbsd)] | | | help: try: `target_os = "openbsd"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:18:1 @@ -47,7 +47,7 @@ LL | #[cfg(netbsd)] | | | help: try: `target_os = "netbsd"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:21:1 @@ -57,7 +57,7 @@ LL | #[cfg(macos)] | | | help: try: `target_os = "macos"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:24:1 @@ -67,7 +67,7 @@ LL | #[cfg(ios)] | | | help: try: `target_os = "ios"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:27:1 @@ -77,7 +77,7 @@ LL | #[cfg(android)] | | | help: try: `target_os = "android"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:30:1 @@ -87,7 +87,7 @@ LL | #[cfg(emscripten)] | | | help: try: `target_os = "emscripten"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:33:1 @@ -97,7 +97,7 @@ LL | #[cfg(fuchsia)] | | | help: try: `target_os = "fuchsia"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:36:1 @@ -107,7 +107,7 @@ LL | #[cfg(haiku)] | | | help: try: `target_os = "haiku"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:39:1 @@ -117,7 +117,7 @@ LL | #[cfg(illumos)] | | | help: try: `target_os = "illumos"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:42:1 @@ -127,7 +127,7 @@ LL | #[cfg(l4re)] | | | help: try: `target_os = "l4re"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:45:1 @@ -137,7 +137,7 @@ LL | #[cfg(redox)] | | | help: try: `target_os = "redox"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:48:1 @@ -147,7 +147,7 @@ LL | #[cfg(solaris)] | | | help: try: `target_os = "solaris"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:51:1 @@ -157,7 +157,7 @@ LL | #[cfg(vxworks)] | | | help: try: `target_os = "vxworks"` | - = help: Did you mean `unix`? + = help: did you mean `unix`? error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:55:1 @@ -165,7 +165,7 @@ error: operating system used in target family position LL | #[cfg(all(not(any(solaris, linux)), freebsd))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: Did you mean `unix`? + = help: did you mean `unix`? help: try | LL | #[cfg(all(not(any(target_os = "solaris", linux)), freebsd))] diff --git a/tests/ui/needless_collect_indirect.stderr b/tests/ui/needless_collect_indirect.stderr index fb807da5f8abe..76e789d905254 100644 --- a/tests/ui/needless_collect_indirect.stderr +++ b/tests/ui/needless_collect_indirect.stderr @@ -6,7 +6,7 @@ LL | | indirect_iter.into_iter().map(|x| (x, x + 1)).collect:: | |____^ | = note: `-D clippy::needless-collect` implied by `-D warnings` -help: Use the original Iterator instead of collecting it and then producing a new one +help: use the original Iterator instead of collecting it and then producing a new one | LL | LL | sample.iter().map(|x| (x, x + 1)).collect::>(); @@ -19,7 +19,7 @@ LL | / let indirect_len = sample.iter().collect::>(); LL | | indirect_len.len(); | |____^ | -help: Take the original Iterator's count instead of collecting it and finding the length +help: take the original Iterator's count instead of collecting it and finding the length | LL | LL | sample.iter().count(); @@ -32,7 +32,7 @@ LL | / let indirect_empty = sample.iter().collect::>(); LL | | indirect_empty.is_empty(); | |____^ | -help: Check if the original Iterator has anything instead of collecting it and seeing if it's empty +help: check if the original Iterator has anything instead of collecting it and seeing if it's empty | LL | LL | sample.iter().next().is_none(); @@ -45,7 +45,7 @@ LL | / let indirect_contains = sample.iter().collect::>(); LL | | indirect_contains.contains(&&5); | |____^ | -help: Check if the original Iterator contains an element instead of collecting then checking +help: check if the original Iterator contains an element instead of collecting then checking | LL | LL | sample.iter().any(|x| x == &5); @@ -58,7 +58,7 @@ LL | / let non_copy_contains = sample.into_iter().collect::>(); LL | | non_copy_contains.contains(&a); | |____^ | -help: Check if the original Iterator contains an element instead of collecting then checking +help: check if the original Iterator contains an element instead of collecting then checking | LL | LL | sample.into_iter().any(|x| x == a); diff --git a/tests/ui/needless_question_mark.stderr b/tests/ui/needless_question_mark.stderr index 567bc518a3fda..983c56031d8f5 100644 --- a/tests/ui/needless_question_mark.stderr +++ b/tests/ui/needless_question_mark.stderr @@ -1,4 +1,4 @@ -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:23:12 | LL | return Some(to.magic?); @@ -6,79 +6,79 @@ LL | return Some(to.magic?); | = note: `-D clippy::needless-question-mark` implied by `-D warnings` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:31:12 | LL | return Some(to.magic?) | ^^^^^^^^^^^^^^^ help: try: `to.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:36:5 | LL | Some(to.magic?) | ^^^^^^^^^^^^^^^ help: try: `to.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:41:21 | LL | to.and_then(|t| Some(t.magic?)) | ^^^^^^^^^^^^^^ help: try: `t.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:50:9 | LL | Some(t.magic?) | ^^^^^^^^^^^^^^ help: try: `t.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:55:12 | LL | return Ok(tr.magic?); | ^^^^^^^^^^^^^ help: try: `tr.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:62:12 | LL | return Ok(tr.magic?) | ^^^^^^^^^^^^^ help: try: `tr.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:66:5 | LL | Ok(tr.magic?) | ^^^^^^^^^^^^^ help: try: `tr.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:70:21 | LL | tr.and_then(|t| Ok(t.magic?)) | ^^^^^^^^^^^^ help: try: `t.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:78:9 | LL | Ok(t.magic?) | ^^^^^^^^^^^^ help: try: `t.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:85:16 | LL | return Ok(t.magic?); | ^^^^^^^^^^^^ help: try: `t.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:138:9 | LL | Ok(to.magic?) // should be triggered | ^^^^^^^^^^^^^ help: try: `to.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:154:9 | LL | Some(to.magic?) // should be triggered | ^^^^^^^^^^^^^^^ help: try: `to.magic` -error: Question mark operator is useless here +error: question mark operator is useless here --> $DIR/needless_question_mark.rs:162:9 | LL | Ok(to.magic?) // should be triggered diff --git a/tests/ui/needless_range_loop.stderr b/tests/ui/needless_range_loop.stderr index c50c4931fb4cc..c898cd64a9392 100644 --- a/tests/ui/needless_range_loop.stderr +++ b/tests/ui/needless_range_loop.stderr @@ -1,4 +1,4 @@ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop.rs:10:14 | LL | for i in 0..vec.len() { @@ -10,7 +10,7 @@ help: consider using an iterator LL | for in &vec { | ^^^^^^ ^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop.rs:19:14 | LL | for i in 0..vec.len() { @@ -21,7 +21,7 @@ help: consider using an iterator LL | for in &vec { | ^^^^^^ ^^^^ -error: the loop variable `j` is only used to index `STATIC`. +error: the loop variable `j` is only used to index `STATIC` --> $DIR/needless_range_loop.rs:24:14 | LL | for j in 0..4 { @@ -32,7 +32,7 @@ help: consider using an iterator LL | for in &STATIC { | ^^^^^^ ^^^^^^^ -error: the loop variable `j` is only used to index `CONST`. +error: the loop variable `j` is only used to index `CONST` --> $DIR/needless_range_loop.rs:28:14 | LL | for j in 0..4 { @@ -54,7 +54,7 @@ help: consider using an iterator LL | for (i, ) in vec.iter().enumerate() { | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `vec2`. +error: the loop variable `i` is only used to index `vec2` --> $DIR/needless_range_loop.rs:40:14 | LL | for i in 0..vec.len() { @@ -65,7 +65,7 @@ help: consider using an iterator LL | for in vec2.iter().take(vec.len()) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop.rs:44:14 | LL | for i in 5..vec.len() { @@ -76,7 +76,7 @@ help: consider using an iterator LL | for in vec.iter().skip(5) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop.rs:48:14 | LL | for i in 0..MAX_LEN { @@ -87,7 +87,7 @@ help: consider using an iterator LL | for in vec.iter().take(MAX_LEN) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop.rs:52:14 | LL | for i in 0..=MAX_LEN { @@ -98,7 +98,7 @@ help: consider using an iterator LL | for in vec.iter().take(MAX_LEN + 1) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop.rs:56:14 | LL | for i in 5..10 { @@ -109,7 +109,7 @@ help: consider using an iterator LL | for in vec.iter().take(10).skip(5) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop.rs:60:14 | LL | for i in 5..=10 { diff --git a/tests/ui/needless_range_loop2.stderr b/tests/ui/needless_range_loop2.stderr index c54ab5ec9809a..2e1f0fd0299b4 100644 --- a/tests/ui/needless_range_loop2.stderr +++ b/tests/ui/needless_range_loop2.stderr @@ -1,4 +1,4 @@ -error: the loop variable `i` is only used to index `ns`. +error: the loop variable `i` is only used to index `ns` --> $DIR/needless_range_loop2.rs:10:14 | LL | for i in 3..10 { @@ -10,7 +10,7 @@ help: consider using an iterator LL | for in ns.iter().take(10).skip(3) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `ms`. +error: the loop variable `i` is only used to index `ms` --> $DIR/needless_range_loop2.rs:31:14 | LL | for i in 0..ms.len() { @@ -21,7 +21,7 @@ help: consider using an iterator LL | for in &mut ms { | ^^^^^^ ^^^^^^^ -error: the loop variable `i` is only used to index `ms`. +error: the loop variable `i` is only used to index `ms` --> $DIR/needless_range_loop2.rs:37:14 | LL | for i in 0..ms.len() { @@ -32,7 +32,7 @@ help: consider using an iterator LL | for in &mut ms { | ^^^^^^ ^^^^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop2.rs:61:14 | LL | for i in x..x + 4 { @@ -43,7 +43,7 @@ help: consider using an iterator LL | for in vec.iter_mut().skip(x).take(4) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `vec`. +error: the loop variable `i` is only used to index `vec` --> $DIR/needless_range_loop2.rs:68:14 | LL | for i in x..=x + 4 { @@ -54,7 +54,7 @@ help: consider using an iterator LL | for in vec.iter_mut().skip(x).take(4 + 1) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `arr`. +error: the loop variable `i` is only used to index `arr` --> $DIR/needless_range_loop2.rs:74:14 | LL | for i in 0..3 { @@ -65,7 +65,7 @@ help: consider using an iterator LL | for in &arr { | ^^^^^^ ^^^^ -error: the loop variable `i` is only used to index `arr`. +error: the loop variable `i` is only used to index `arr` --> $DIR/needless_range_loop2.rs:78:14 | LL | for i in 0..2 { @@ -76,7 +76,7 @@ help: consider using an iterator LL | for in arr.iter().take(2) { | ^^^^^^ ^^^^^^^^^^^^^^^^^^ -error: the loop variable `i` is only used to index `arr`. +error: the loop variable `i` is only used to index `arr` --> $DIR/needless_range_loop2.rs:82:14 | LL | for i in 1..3 { diff --git a/tests/ui/ptr_arg.stderr b/tests/ui/ptr_arg.stderr index 708318bbe295c..d302b16d4b72a 100644 --- a/tests/ui/ptr_arg.stderr +++ b/tests/ui/ptr_arg.stderr @@ -1,4 +1,4 @@ -error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices --> $DIR/ptr_arg.rs:7:14 | LL | fn do_vec(x: &Vec) { @@ -6,25 +6,25 @@ LL | fn do_vec(x: &Vec) { | = note: `-D clippy::ptr-arg` implied by `-D warnings` -error: writing `&String` instead of `&str` involves a new object where a slice will do. +error: writing `&String` instead of `&str` involves a new object where a slice will do --> $DIR/ptr_arg.rs:16:14 | LL | fn do_str(x: &String) { | ^^^^^^^ help: change this to: `&str` -error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do. +error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do --> $DIR/ptr_arg.rs:25:15 | LL | fn do_path(x: &PathBuf) { | ^^^^^^^^ help: change this to: `&Path` -error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices --> $DIR/ptr_arg.rs:38:18 | LL | fn do_vec(x: &Vec); | ^^^^^^^^^ help: change this to: `&[i64]` -error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices --> $DIR/ptr_arg.rs:51:14 | LL | fn cloned(x: &Vec) -> Vec { @@ -43,7 +43,7 @@ help: change `x.clone()` to LL | x.to_owned() | -error: writing `&String` instead of `&str` involves a new object where a slice will do. +error: writing `&String` instead of `&str` involves a new object where a slice will do --> $DIR/ptr_arg.rs:60:18 | LL | fn str_cloned(x: &String) -> String { @@ -66,7 +66,7 @@ help: change `x.clone()` to LL | x.to_string() | -error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do. +error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do --> $DIR/ptr_arg.rs:68:19 | LL | fn path_cloned(x: &PathBuf) -> PathBuf { @@ -89,7 +89,7 @@ help: change `x.clone()` to LL | x.to_path_buf() | -error: writing `&String` instead of `&str` involves a new object where a slice will do. +error: writing `&String` instead of `&str` involves a new object where a slice will do --> $DIR/ptr_arg.rs:76:44 | LL | fn false_positive_capacity(x: &Vec, y: &String) { @@ -108,13 +108,13 @@ help: change `y.as_str()` to LL | let c = y; | ^ -error: using a reference to `Cow` is not recommended. +error: using a reference to `Cow` is not recommended --> $DIR/ptr_arg.rs:90:25 | LL | fn test_cow_with_ref(c: &Cow<[i32]>) {} | ^^^^^^^^^^^ help: change this to: `&[i32]` -error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices --> $DIR/ptr_arg.rs:143:21 | LL | fn foo_vec(vec: &Vec) { @@ -133,7 +133,7 @@ help: change `vec.clone()` to LL | let _ = vec.to_owned().clone(); | ^^^^^^^^^^^^^^ -error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do. +error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do --> $DIR/ptr_arg.rs:148:23 | LL | fn foo_path(path: &PathBuf) { @@ -152,7 +152,7 @@ help: change `path.clone()` to LL | let _ = path.to_path_buf().clone(); | ^^^^^^^^^^^^^^^^^^ -error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do. +error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do --> $DIR/ptr_arg.rs:153:21 | LL | fn foo_str(str: &PathBuf) { diff --git a/tests/ui/suspicious_operation_groupings.stderr b/tests/ui/suspicious_operation_groupings.stderr index ce7108217f18d..2da05399575a1 100644 --- a/tests/ui/suspicious_operation_groupings.stderr +++ b/tests/ui/suspicious_operation_groupings.stderr @@ -1,4 +1,4 @@ -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:14:9 | LL | self.x == other.y && self.y == other.y && self.z == other.z @@ -6,157 +6,157 @@ LL | self.x == other.y && self.y == other.y && self.z == other.z | = note: `-D clippy::suspicious-operation-groupings` implied by `-D warnings` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:14:9 | LL | self.x == other.y && self.y == other.y && self.z == other.z | ^^^^^^^^^^^^^^^^^ help: I think you meant: `self.x == other.x` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:27:20 | LL | s1.a < s2.a && s1.a < s2.b | ^^^^^^^^^^^ help: I think you meant: `s1.b < s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:75:33 | LL | s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:80:19 | LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:80:19 | LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:85:19 | LL | s1.a * s2.a + s2.b * s2.b + s1.c * s2.c | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:90:19 | LL | s1.a * s2.a + s1.b * s1.b + s1.c * s2.c | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:95:5 | LL | s1.a * s1.a + s1.b * s2.b + s1.c * s2.c | ^^^^^^^^^^^ help: I think you meant: `s1.a * s2.a` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:100:33 | LL | s1.a * s2.a + s1.b * s2.b + s1.c * s1.c | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:113:20 | LL | (s1.a * s2.a + s1.b * s1.b) | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:118:34 | LL | (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d) | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:123:38 | LL | (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d) | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:128:39 | LL | ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)) | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:133:42 | LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d))) | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:133:42 | LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d))) | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:138:40 | LL | (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d)) | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:143:40 | LL | ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))) | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:148:20 | LL | (s1.a * s2.a + s2.b * s2.b) / 2 | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:153:35 | LL | i32::swap_bytes(s1.a * s2.a + s2.b * s2.b) | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:158:29 | LL | s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d | ^^^^^^^^^^^^ help: I think you meant: `s1.c == s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:163:17 | LL | s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d | ^^^^^^^^^^^^ help: I think you meant: `s1.c == s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:172:77 | LL | (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: I think you meant: `(n1.inner.2).0 == (n2.inner.2).0` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:186:25 | LL | s1.a <= s2.a && s1.a <= s2.b | ^^^^^^^^^^^^ help: I think you meant: `s1.b <= s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:192:23 | LL | if s1.a < s2.a && s1.a < s2.b { | ^^^^^^^^^^^ help: I think you meant: `s1.b < s2.b` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:199:48 | LL | -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d))) | ^^^^^^^^^^^^^ help: I think you meant: `-s1.c * -s2.c` -error: This sequence of operators looks suspiciously like a bug. +error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:204:27 | LL | -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a }) diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.stderr b/tests/ui/toplevel_ref_arg_non_rustfix.stderr index 6c36141a58c65..b8cfd98739497 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.stderr +++ b/tests/ui/toplevel_ref_arg_non_rustfix.stderr @@ -1,4 +1,4 @@ -error: `ref` directly on a function argument is ignored. Consider using a reference type instead. +error: `ref` directly on a function argument is ignored. Consider using a reference type instead --> $DIR/toplevel_ref_arg_non_rustfix.rs:9:15 | LL | fn the_answer(ref mut x: u8) { @@ -6,7 +6,7 @@ LL | fn the_answer(ref mut x: u8) { | = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` -error: `ref` directly on a function argument is ignored. Consider using a reference type instead. +error: `ref` directly on a function argument is ignored. Consider using a reference type instead --> $DIR/toplevel_ref_arg_non_rustfix.rs:15:24 | LL | fn fun_example(ref _x: usize) {} diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index 05f91ee2adaa8..1848fc2490a00 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -1,4 +1,4 @@ -error: transmuting a known null pointer into a reference. +error: transmuting a known null pointer into a reference --> $DIR/transmuting_null.rs:10:23 | LL | let _: &u64 = std::mem::transmute(0 as *const u64); @@ -6,13 +6,13 @@ LL | let _: &u64 = std::mem::transmute(0 as *const u64); | = note: `-D clippy::transmuting-null` implied by `-D warnings` -error: transmuting a known null pointer into a reference. +error: transmuting a known null pointer into a reference --> $DIR/transmuting_null.rs:11:23 | LL | let _: &u64 = std::mem::transmute(std::ptr::null::()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: transmuting a known null pointer into a reference. +error: transmuting a known null pointer into a reference --> $DIR/transmuting_null.rs:21:23 | LL | let _: &u64 = std::mem::transmute(ZPTR); diff --git a/tests/ui/unnecessary_lazy_eval.stderr b/tests/ui/unnecessary_lazy_eval.stderr index 44dcd0cafbb6e..cc94bd5cd9e16 100644 --- a/tests/ui/unnecessary_lazy_eval.stderr +++ b/tests/ui/unnecessary_lazy_eval.stderr @@ -2,7 +2,7 @@ error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:35:13 | LL | let _ = opt.unwrap_or_else(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `opt.unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `opt.unwrap_or(2)` | = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings` @@ -10,187 +10,187 @@ error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:36:13 | LL | let _ = opt.unwrap_or_else(|| astronomers_pi); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `opt.unwrap_or(astronomers_pi)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `opt.unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:37:13 | LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `opt.unwrap_or(ext_str.some_field)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `opt.unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:39:13 | LL | let _ = opt.and_then(|_| ext_opt); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `opt.and(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `and` instead: `opt.and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:40:13 | LL | let _ = opt.or_else(|| ext_opt); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `opt.or(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `opt.or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:41:13 | LL | let _ = opt.or_else(|| None); - | ^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `opt.or(None)` + | ^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `opt.or(None)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:42:13 | LL | let _ = opt.get_or_insert_with(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `get_or_insert` instead: `opt.get_or_insert(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `get_or_insert` instead: `opt.get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:43:13 | LL | let _ = opt.ok_or_else(|| 2); - | ^^^^^^^^^^^^^^^^^^^^ help: Use `ok_or` instead: `opt.ok_or(2)` + | ^^^^^^^^^^^^^^^^^^^^ help: use `ok_or` instead: `opt.ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:44:13 | LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `nested_tuple_opt.unwrap_or(Some((1, 2)))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `nested_tuple_opt.unwrap_or(Some((1, 2)))` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:47:13 | LL | let _ = Some(10).unwrap_or_else(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `Some(10).unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `Some(10).unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:48:13 | LL | let _ = Some(10).and_then(|_| ext_opt); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `Some(10).and(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `and` instead: `Some(10).and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:49:28 | LL | let _: Option = None.or_else(|| ext_opt); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `None.or(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `None.or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:50:13 | LL | let _ = None.get_or_insert_with(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `get_or_insert` instead: `None.get_or_insert(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `get_or_insert` instead: `None.get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:51:35 | LL | let _: Result = None.ok_or_else(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^ help: Use `ok_or` instead: `None.ok_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^ help: use `ok_or` instead: `None.ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:52:28 | LL | let _: Option = None.or_else(|| None); - | ^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `None.or(None)` + | ^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `None.or(None)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:55:13 | LL | let _ = deep.0.unwrap_or_else(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `deep.0.unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `deep.0.unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:56:13 | LL | let _ = deep.0.and_then(|_| ext_opt); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `deep.0.and(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `and` instead: `deep.0.and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:57:13 | LL | let _ = deep.0.or_else(|| None); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `deep.0.or(None)` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `deep.0.or(None)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:58:13 | LL | let _ = deep.0.get_or_insert_with(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `get_or_insert` instead: `deep.0.get_or_insert(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `get_or_insert` instead: `deep.0.get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:59:13 | LL | let _ = deep.0.ok_or_else(|| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `ok_or` instead: `deep.0.ok_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `ok_or` instead: `deep.0.ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:79:28 | LL | let _: Option = None.or_else(|| Some(3)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `None.or(Some(3))` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `None.or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:80:13 | LL | let _ = deep.0.or_else(|| Some(3)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `deep.0.or(Some(3))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `deep.0.or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` --> $DIR/unnecessary_lazy_eval.rs:81:13 | LL | let _ = opt.or_else(|| Some(3)); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `opt.or(Some(3))` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `opt.or(Some(3))` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:87:13 | LL | let _ = res2.unwrap_or_else(|_| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `res2.unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `res2.unwrap_or(2)` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:88:13 | LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `res2.unwrap_or(astronomers_pi)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `res2.unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:89:13 | LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `res2.unwrap_or(ext_str.some_field)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `res2.unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:111:35 | LL | let _: Result = res.and_then(|_| Err(2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `res.and(Err(2))` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `and` instead: `res.and(Err(2))` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:112:35 | LL | let _: Result = res.and_then(|_| Err(astronomers_pi)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `res.and(Err(astronomers_pi))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `and` instead: `res.and(Err(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:113:35 | LL | let _: Result = res.and_then(|_| Err(ext_str.some_field)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `res.and(Err(ext_str.some_field))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `and` instead: `res.and(Err(ext_str.some_field))` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:115:35 | LL | let _: Result = res.or_else(|_| Ok(2)); - | ^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `res.or(Ok(2))` + | ^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `res.or(Ok(2))` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:116:35 | LL | let _: Result = res.or_else(|_| Ok(astronomers_pi)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `res.or(Ok(astronomers_pi))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `res.or(Ok(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval.rs:117:35 | LL | let _: Result = res.or_else(|_| Ok(ext_str.some_field)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `res.or(Ok(ext_str.some_field))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `or` instead: `res.or(Ok(ext_str.some_field))` error: aborting due to 32 previous errors diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/tests/ui/unnecessary_lazy_eval_unfixable.stderr index 581d641cbf54b..75674b0a9d20a 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -2,7 +2,7 @@ error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval_unfixable.rs:12:13 | LL | let _ = Ok(1).unwrap_or_else(|()| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `Ok(1).unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `Ok(1).unwrap_or(2)` | = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings` @@ -10,13 +10,13 @@ error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval_unfixable.rs:16:13 | LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `Ok(1).unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `Ok(1).unwrap_or(2)` error: unnecessary closure used to substitute value for `Result::Err` --> $DIR/unnecessary_lazy_eval_unfixable.rs:17:13 | LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `Ok(1).unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `unwrap_or` instead: `Ok(1).unwrap_or(2)` error: aborting due to 3 previous errors diff --git a/tests/ui/used_underscore_binding.stderr b/tests/ui/used_underscore_binding.stderr index 68e96148093d2..2cbfc5ca2e270 100644 --- a/tests/ui/used_underscore_binding.stderr +++ b/tests/ui/used_underscore_binding.stderr @@ -1,4 +1,4 @@ -error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used --> $DIR/used_underscore_binding.rs:26:5 | LL | _foo + 1 @@ -6,31 +6,31 @@ LL | _foo + 1 | = note: `-D clippy::used-underscore-binding` implied by `-D warnings` -error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used --> $DIR/used_underscore_binding.rs:31:20 | LL | println!("{}", _foo); | ^^^^ -error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used --> $DIR/used_underscore_binding.rs:32:16 | LL | assert_eq!(_foo, _foo); | ^^^^ -error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used --> $DIR/used_underscore_binding.rs:32:22 | LL | assert_eq!(_foo, _foo); | ^^^^ -error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. +error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used --> $DIR/used_underscore_binding.rs:45:5 | LL | s._underscore_field += 1; | ^^^^^^^^^^^^^^^^^^^ -error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. +error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used --> $DIR/used_underscore_binding.rs:100:16 | LL | uses_i(_i); diff --git a/tests/ui/vec_box_sized.stderr b/tests/ui/vec_box_sized.stderr index 57e2f1fdf9a74..83435a40aa16f 100644 --- a/tests/ui/vec_box_sized.stderr +++ b/tests/ui/vec_box_sized.stderr @@ -1,4 +1,4 @@ -error: `Vec` is already on the heap, the boxing is unnecessary. +error: `Vec` is already on the heap, the boxing is unnecessary --> $DIR/vec_box_sized.rs:14:21 | LL | sized_type: Vec>, @@ -6,19 +6,19 @@ LL | sized_type: Vec>, | = note: `-D clippy::vec-box` implied by `-D warnings` -error: `Vec` is already on the heap, the boxing is unnecessary. +error: `Vec` is already on the heap, the boxing is unnecessary --> $DIR/vec_box_sized.rs:17:14 | LL | struct A(Vec>); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec` -error: `Vec` is already on the heap, the boxing is unnecessary. +error: `Vec` is already on the heap, the boxing is unnecessary --> $DIR/vec_box_sized.rs:18:18 | LL | struct B(Vec>>); | ^^^^^^^^^^^^^^^ help: try: `Vec` -error: `Vec` is already on the heap, the boxing is unnecessary. +error: `Vec` is already on the heap, the boxing is unnecessary --> $DIR/vec_box_sized.rs:46:23 | LL | pub fn f() -> Vec> { diff --git a/tests/ui/wild_in_or_pats.stderr b/tests/ui/wild_in_or_pats.stderr index 33c34cbbd4088..45b87aa0f20b9 100644 --- a/tests/ui/wild_in_or_pats.stderr +++ b/tests/ui/wild_in_or_pats.stderr @@ -1,35 +1,35 @@ -error: wildcard pattern covers any other pattern as it will match anyway. +error: wildcard pattern covers any other pattern as it will match anyway --> $DIR/wild_in_or_pats.rs:8:9 | LL | "bar" | _ => { | ^^^^^^^^^ | = note: `-D clippy::wildcard-in-or-patterns` implied by `-D warnings` - = help: Consider handling `_` separately. + = help: consider handling `_` separately -error: wildcard pattern covers any other pattern as it will match anyway. +error: wildcard pattern covers any other pattern as it will match anyway --> $DIR/wild_in_or_pats.rs:16:9 | LL | "bar" | "bar2" | _ => { | ^^^^^^^^^^^^^^^^^^ | - = help: Consider handling `_` separately. + = help: consider handling `_` separately -error: wildcard pattern covers any other pattern as it will match anyway. +error: wildcard pattern covers any other pattern as it will match anyway --> $DIR/wild_in_or_pats.rs:24:9 | LL | _ | "bar" | _ => { | ^^^^^^^^^^^^^ | - = help: Consider handling `_` separately. + = help: consider handling `_` separately -error: wildcard pattern covers any other pattern as it will match anyway. +error: wildcard pattern covers any other pattern as it will match anyway --> $DIR/wild_in_or_pats.rs:32:9 | LL | _ | "bar" => { | ^^^^^^^^^ | - = help: Consider handling `_` separately. + = help: consider handling `_` separately error: aborting due to 4 previous errors diff --git a/tests/ui/zero_div_zero.stderr b/tests/ui/zero_div_zero.stderr index d0e88f3c5a546..0931dd32e7af2 100644 --- a/tests/ui/zero_div_zero.stderr +++ b/tests/ui/zero_div_zero.stderr @@ -13,7 +13,7 @@ LL | let nan = 0.0 / 0.0; | ^^^^^^^^^ | = note: `-D clippy::zero-divided-by-zero` implied by `-D warnings` - = help: Consider using `f64::NAN` if you would like a constant representing NaN + = help: consider using `f64::NAN` if you would like a constant representing NaN error: equal expressions as operands to `/` --> $DIR/zero_div_zero.rs:5:19 @@ -27,7 +27,7 @@ error: constant division of `0.0` with `0.0` will always result in NaN LL | let f64_nan = 0.0 / 0.0f64; | ^^^^^^^^^^^^ | - = help: Consider using `f64::NAN` if you would like a constant representing NaN + = help: consider using `f64::NAN` if you would like a constant representing NaN error: equal expressions as operands to `/` --> $DIR/zero_div_zero.rs:6:25 @@ -41,7 +41,7 @@ error: constant division of `0.0` with `0.0` will always result in NaN LL | let other_f64_nan = 0.0f64 / 0.0; | ^^^^^^^^^^^^ | - = help: Consider using `f64::NAN` if you would like a constant representing NaN + = help: consider using `f64::NAN` if you would like a constant representing NaN error: equal expressions as operands to `/` --> $DIR/zero_div_zero.rs:7:28 @@ -55,7 +55,7 @@ error: constant division of `0.0` with `0.0` will always result in NaN LL | let one_more_f64_nan = 0.0f64 / 0.0f64; | ^^^^^^^^^^^^^^^ | - = help: Consider using `f64::NAN` if you would like a constant representing NaN + = help: consider using `f64::NAN` if you would like a constant representing NaN error: aborting due to 8 previous errors From e107b65b5a025d6c3a7109f5f3dfa9f6efdf0852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 25 Feb 2021 12:30:51 +0100 Subject: [PATCH 036/226] disable lint_message_convention test inside the rustc test suite --- tests/lint_message_convention.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index e316a884996d4..1606a7881c7fd 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -60,6 +60,11 @@ impl Message { #[test] fn lint_message_convention() { + // disable the test inside the rustc test suite + if option_env!("RUSTC_TEST_SUITE").is_some() { + return; + } + // make sure that lint messages: // * are not capitalized // * don't have puncuation at the end of the last sentence From e00b1cc73ada33c7ef72702810a74f5abd38b112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 26 Feb 2021 15:49:18 +0100 Subject: [PATCH 037/226] change some lint messages and remove old entries from the ignorelist --- clippy_lints/src/methods/mod.rs | 2 +- .../src/suspicious_operation_groupings.rs | 2 +- clippy_lints/src/types.rs | 2 +- tests/lint_message_convention.rs | 4 -- tests/ui/dlist.stderr | 12 ++--- tests/ui/iterator_step_by_zero.stderr | 14 ++--- .../ui/suspicious_operation_groupings.stderr | 54 +++++++++---------- 7 files changed, 43 insertions(+), 47 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f5c01ac772987..b0f8185e331fc 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2569,7 +2569,7 @@ fn lint_step_by<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx cx, ITERATOR_STEP_BY_ZERO, expr.span, - "Iterator::step_by(0) will panic at runtime", + "`Iterator::step_by(0)` will panic at runtime", ); } } diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index 2ff30698043dc..44521885d2009 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -262,7 +262,7 @@ fn emit_suggestion(cx: &EarlyContext<'_>, span: Span, sugg: String, applicabilit SUSPICIOUS_OPERATION_GROUPINGS, span, "this sequence of operators looks suspiciously like a bug", - "I think you meant", + "did you mean", sugg, applicability, ) diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index a18cba6fb44bd..f71b1651bfe9b 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -578,7 +578,7 @@ impl Types { cx, LINKEDLIST, hir_ty.span, - "I see you're using a LinkedList! Perhaps you meant some other data structure?", + "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?", None, "a `VecDeque` might work", ); diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index 1606a7881c7fd..d45d93f8184be 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -31,9 +31,7 @@ impl Message { // sometimes the first character is capitalized and it is legal (like in "Iterator...") or // we want to ask a question ending in "?" let exceptions_set: RegexSet = RegexSet::new(&[ - r".*error: I see you're using a LinkedList! Perhaps you meant some other data structure?", r".*C-like enum variant discriminant is not portable to 32-bit targets", - r".*Iterator::step_by(0) will panic at runtime", r".*did you mean `unix`?", r".*the arguments may be inverted...", r".*Intel x86 assembly syntax used", @@ -41,8 +39,6 @@ impl Message { r".*remove .*the return type...", r"note: Clippy version: .*", r"the compiler unexpectedly panicked. this is a bug.", - r".*help: I think you meant: .*", - r"Iterator.* will panic at runtime", ]) .unwrap(); diff --git a/tests/ui/dlist.stderr b/tests/ui/dlist.stderr index 64fde33c64f52..234db33ba1242 100644 --- a/tests/ui/dlist.stderr +++ b/tests/ui/dlist.stderr @@ -1,4 +1,4 @@ -error: I see you're using a LinkedList! Perhaps you meant some other data structure? +error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? --> $DIR/dlist.rs:9:16 | LL | type Baz = LinkedList; @@ -7,7 +7,7 @@ LL | type Baz = LinkedList; = note: `-D clippy::linkedlist` implied by `-D warnings` = help: a `VecDeque` might work -error: I see you're using a LinkedList! Perhaps you meant some other data structure? +error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? --> $DIR/dlist.rs:10:15 | LL | fn foo(_: LinkedList); @@ -15,7 +15,7 @@ LL | fn foo(_: LinkedList); | = help: a `VecDeque` might work -error: I see you're using a LinkedList! Perhaps you meant some other data structure? +error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? --> $DIR/dlist.rs:11:23 | LL | const BAR: Option>; @@ -23,7 +23,7 @@ LL | const BAR: Option>; | = help: a `VecDeque` might work -error: I see you're using a LinkedList! Perhaps you meant some other data structure? +error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? --> $DIR/dlist.rs:22:15 | LL | fn foo(_: LinkedList) {} @@ -31,7 +31,7 @@ LL | fn foo(_: LinkedList) {} | = help: a `VecDeque` might work -error: I see you're using a LinkedList! Perhaps you meant some other data structure? +error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? --> $DIR/dlist.rs:25:39 | LL | pub fn test(my_favourite_linked_list: LinkedList) { @@ -39,7 +39,7 @@ LL | pub fn test(my_favourite_linked_list: LinkedList) { | = help: a `VecDeque` might work -error: I see you're using a LinkedList! Perhaps you meant some other data structure? +error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? --> $DIR/dlist.rs:29:29 | LL | pub fn test_ret() -> Option> { diff --git a/tests/ui/iterator_step_by_zero.stderr b/tests/ui/iterator_step_by_zero.stderr index c2c6803b3e6e7..d792aea11dfa0 100644 --- a/tests/ui/iterator_step_by_zero.stderr +++ b/tests/ui/iterator_step_by_zero.stderr @@ -1,4 +1,4 @@ -error: Iterator::step_by(0) will panic at runtime +error: `Iterator::step_by(0)` will panic at runtime --> $DIR/iterator_step_by_zero.rs:3:13 | LL | let _ = vec!["A", "B", "B"].iter().step_by(0); @@ -6,37 +6,37 @@ LL | let _ = vec!["A", "B", "B"].iter().step_by(0); | = note: `-D clippy::iterator-step-by-zero` implied by `-D warnings` -error: Iterator::step_by(0) will panic at runtime +error: `Iterator::step_by(0)` will panic at runtime --> $DIR/iterator_step_by_zero.rs:4:13 | LL | let _ = "XXX".chars().step_by(0); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: Iterator::step_by(0) will panic at runtime +error: `Iterator::step_by(0)` will panic at runtime --> $DIR/iterator_step_by_zero.rs:5:13 | LL | let _ = (0..1).step_by(0); | ^^^^^^^^^^^^^^^^^ -error: Iterator::step_by(0) will panic at runtime +error: `Iterator::step_by(0)` will panic at runtime --> $DIR/iterator_step_by_zero.rs:14:13 | LL | let _ = (1..).step_by(0); | ^^^^^^^^^^^^^^^^ -error: Iterator::step_by(0) will panic at runtime +error: `Iterator::step_by(0)` will panic at runtime --> $DIR/iterator_step_by_zero.rs:15:13 | LL | let _ = (1..=2).step_by(0); | ^^^^^^^^^^^^^^^^^^ -error: Iterator::step_by(0) will panic at runtime +error: `Iterator::step_by(0)` will panic at runtime --> $DIR/iterator_step_by_zero.rs:18:13 | LL | let _ = x.step_by(0); | ^^^^^^^^^^^^ -error: Iterator::step_by(0) will panic at runtime +error: `Iterator::step_by(0)` will panic at runtime --> $DIR/iterator_step_by_zero.rs:22:13 | LL | let _ = v1.iter().step_by(2 / 3); diff --git a/tests/ui/suspicious_operation_groupings.stderr b/tests/ui/suspicious_operation_groupings.stderr index 2da05399575a1..96065699d321a 100644 --- a/tests/ui/suspicious_operation_groupings.stderr +++ b/tests/ui/suspicious_operation_groupings.stderr @@ -2,7 +2,7 @@ error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:14:9 | LL | self.x == other.y && self.y == other.y && self.z == other.z - | ^^^^^^^^^^^^^^^^^ help: I think you meant: `self.x == other.x` + | ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x` | = note: `-D clippy::suspicious-operation-groupings` implied by `-D warnings` @@ -10,157 +10,157 @@ error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:14:9 | LL | self.x == other.y && self.y == other.y && self.z == other.z - | ^^^^^^^^^^^^^^^^^ help: I think you meant: `self.x == other.x` + | ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:27:20 | LL | s1.a < s2.a && s1.a < s2.b - | ^^^^^^^^^^^ help: I think you meant: `s1.b < s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:75:33 | LL | s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:80:19 | LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c - | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:80:19 | LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c - | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:85:19 | LL | s1.a * s2.a + s2.b * s2.b + s1.c * s2.c - | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:90:19 | LL | s1.a * s2.a + s1.b * s1.b + s1.c * s2.c - | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:95:5 | LL | s1.a * s1.a + s1.b * s2.b + s1.c * s2.c - | ^^^^^^^^^^^ help: I think you meant: `s1.a * s2.a` + | ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:100:33 | LL | s1.a * s2.a + s1.b * s2.b + s1.c * s1.c - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:113:20 | LL | (s1.a * s2.a + s1.b * s1.b) - | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:118:34 | LL | (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d) - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:123:38 | LL | (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d) - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:128:39 | LL | ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)) - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:133:42 | LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d))) - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:133:42 | LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d))) - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:138:40 | LL | (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d)) - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:143:40 | LL | ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))) - | ^^^^^^^^^^^ help: I think you meant: `s1.c * s2.c` + | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:148:20 | LL | (s1.a * s2.a + s2.b * s2.b) / 2 - | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:153:35 | LL | i32::swap_bytes(s1.a * s2.a + s2.b * s2.b) - | ^^^^^^^^^^^ help: I think you meant: `s1.b * s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:158:29 | LL | s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d - | ^^^^^^^^^^^^ help: I think you meant: `s1.c == s2.c` + | ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:163:17 | LL | s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d - | ^^^^^^^^^^^^ help: I think you meant: `s1.c == s2.c` + | ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:172:77 | LL | (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: I think you meant: `(n1.inner.2).0 == (n2.inner.2).0` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:186:25 | LL | s1.a <= s2.a && s1.a <= s2.b - | ^^^^^^^^^^^^ help: I think you meant: `s1.b <= s2.b` + | ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:192:23 | LL | if s1.a < s2.a && s1.a < s2.b { - | ^^^^^^^^^^^ help: I think you meant: `s1.b < s2.b` + | ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:199:48 | LL | -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d))) - | ^^^^^^^^^^^^^ help: I think you meant: `-s1.c * -s2.c` + | ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c` error: this sequence of operators looks suspiciously like a bug --> $DIR/suspicious_operation_groupings.rs:204:27 | LL | -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a }) - | ^^^^^^^^^^^^^ help: I think you meant: `-s1.b < -s2.b` + | ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b` error: aborting due to 27 previous errors From 24460f76cb99cfa4006d81ac3c723e4f509fd219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 26 Feb 2021 22:02:00 +0100 Subject: [PATCH 038/226] lintcheck: update logs --- lintcheck-logs/lintcheck_crates_logs.txt | 71 ++++++++++-------------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/lintcheck-logs/lintcheck_crates_logs.txt b/lintcheck-logs/lintcheck_crates_logs.txt index e3aeb76657f26..cf6af1a549a06 100644 --- a/lintcheck-logs/lintcheck_crates_logs.txt +++ b/lintcheck-logs/lintcheck_crates_logs.txt @@ -1,4 +1,4 @@ -clippy 0.1.52 (5c6cd87b9 2021-02-25) +clippy 0.1.52 (524f54c57 2021-02-26) cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" @@ -77,7 +77,6 @@ cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multi cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" cargo-0.49.0/src/bin/cargo/main.rs:72:22 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/main.rs:79:40 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/bin/cargo/main.rs:94:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" cargo-0.49.0/src/bin/cargo/main.rs:96:41 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/bin/cargo/main.rs:98:60 clippy::redundant_closure_for_method_calls "redundant closure found" @@ -96,7 +95,7 @@ cargo-0.49.0/src/cargo/core/compiler/build_context/mod.rs:83:20 clippy::doc_mark cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:108:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:121:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:149:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:411:9 clippy::needless_question_mark "Question mark operator is useless here" +cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:411:9 clippy::needless_question_mark "question mark operator is useless here" cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:420:69 clippy::doc_markdown "you should put `mode/target_kind` between ticks in the documentation" cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:423:19 clippy::doc_markdown "you should put `CrateTypes` between ticks in the documentation" cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:424:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -111,7 +110,7 @@ cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:96:31 clippy:: cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:98:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:4:9 clippy::doc_markdown "you should put `BuildPlan` between ticks in the documentation" cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:5:66 clippy::doc_markdown "you should put `BuildPlan` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:66:40 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do." +cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:66:40 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" cargo-0.49.0/src/cargo/core/compiler/compilation.rs:169:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -200,7 +199,6 @@ cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1966:22 clippy::cast_possibl cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:17 clippy::similar_names "binding's name is too similar to existing binding" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:24 clippy::manual_strip "stripping a prefix manually" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1986:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1986:27 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:2016:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:61:5 clippy::doc_markdown "you should put `CompileMode` between ticks in the documentation" cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:63:12 clippy::doc_markdown "you should put `CompileKind` between ticks in the documentation" @@ -248,8 +246,8 @@ cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::items_after_statements cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::unnecessary_wraps "this function's return value is unnecessary" cargo-0.49.0/src/cargo/core/compiler/mod.rs:392:45 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/cargo/core/compiler/mod.rs:415:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:464:18 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do." -cargo-0.49.0/src/cargo/core/compiler/mod.rs:488:61 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do." +cargo-0.49.0/src/cargo/core/compiler/mod.rs:464:18 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" +cargo-0.49.0/src/cargo/core/compiler/mod.rs:488:61 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" cargo-0.49.0/src/cargo/core/compiler/mod.rs:667:15 clippy::similar_names "binding's name is too similar to existing binding" cargo-0.49.0/src/cargo/core/compiler/mod.rs:693:1 clippy::unnecessary_wraps "this function's return value is unnecessary" cargo-0.49.0/src/cargo/core/compiler/mod.rs:725:42 clippy::match_same_arms "this `match` has identical arm bodies" @@ -453,7 +451,7 @@ cargo-0.49.0/src/cargo/core/package.rs:453:60 clippy::redundant_closure_for_meth cargo-0.49.0/src/cargo/core/package.rs:459:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/package.rs:473:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/package.rs:587:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:588:9 clippy::needless_question_mark "Question mark operator is useless here" +cargo-0.49.0/src/cargo/core/package.rs:588:9 clippy::needless_question_mark "question mark operator is useless here" cargo-0.49.0/src/cargo/core/package.rs:682:46 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" cargo-0.49.0/src/cargo/core/package.rs:682:46 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" cargo-0.49.0/src/cargo/core/package.rs:682:63 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" @@ -482,7 +480,6 @@ cargo-0.49.0/src/cargo/core/package_id_spec.rs:212:9 clippy::items_after_stateme cargo-0.49.0/src/cargo/core/package_id_spec.rs:231:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:64:23 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/core/package_id_spec.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/package_id_spec.rs:88:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/core/profiles.rs:1004:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -571,8 +568,8 @@ cargo-0.49.0/src/cargo/core/resolver/mod.rs:122:1 clippy::missing_errors_doc "do cargo-0.49.0/src/cargo/core/resolver/mod.rs:142:44 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/cargo/core/resolver/mod.rs:180:1 clippy::too_many_lines "this function has too many lines (225/100)" cargo-0.49.0/src/cargo/core/resolver/mod.rs:311:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:421:52 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead." -cargo-0.49.0/src/cargo/core/resolver/mod.rs:457:69 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead." +cargo-0.49.0/src/cargo/core/resolver/mod.rs:421:52 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" +cargo-0.49.0/src/cargo/core/resolver/mod.rs:457:69 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" cargo-0.49.0/src/cargo/core/resolver/mod.rs:470:37 clippy::similar_names "binding's name is too similar to existing binding" cargo-0.49.0/src/cargo/core/resolver/mod.rs:607:11 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" cargo-0.49.0/src/cargo/core/resolver/mod.rs:631:21 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" @@ -760,7 +757,6 @@ cargo-0.49.0/src/cargo/core/workspace.rs:329:37 clippy::doc_markdown "you should cargo-0.49.0/src/cargo/core/workspace.rs:410:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/core/workspace.rs:440:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" cargo-0.49.0/src/cargo/core/workspace.rs:511:32 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/workspace.rs:531:13 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/core/workspace.rs:561:25 clippy::non_ascii_literal "literal non-ASCII character detected" cargo-0.49.0/src/cargo/core/workspace.rs:613:13 clippy::filter_map "called `filter_map(..).map(..)` on an `Iterator`" cargo-0.49.0/src/cargo/core/workspace.rs:615:22 clippy::redundant_closure_for_method_calls "redundant closure found" @@ -796,7 +792,7 @@ cargo-0.49.0/src/cargo/ops/cargo_compile.rs:205:36 clippy::match_same_arms "this cargo-0.49.0/src/cargo/ops/cargo_compile.rs:242:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/ops/cargo_compile.rs:249:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/ops/cargo_compile.rs:258:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:267:16 clippy::needless_question_mark "Question mark operator is useless here" +cargo-0.49.0/src/cargo/ops/cargo_compile.rs:267:16 clippy::needless_question_mark "question mark operator is useless here" cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::too_many_lines "this function has too many lines (219/100)" cargo-0.49.0/src/cargo/ops/cargo_compile.rs:468:9 clippy::default_trait_access "calling `std::collections::HashMap::default()` is more clear than this expression" @@ -854,7 +850,7 @@ cargo-0.49.0/src/cargo/ops/cargo_new.rs:525:47 clippy::doc_markdown "you should cargo-0.49.0/src/cargo/ops/cargo_new.rs:525:9 clippy::doc_markdown "you should put `format_existing` between ticks in the documentation" cargo-0.49.0/src/cargo/ops/cargo_new.rs:572:34 clippy::match_same_arms "this `match` has identical arm bodies" cargo-0.49.0/src/cargo/ops/cargo_new.rs:623:1 clippy::too_many_lines "this function has too many lines (130/100)" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:781:5 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead." +cargo-0.49.0/src/cargo/ops/cargo_new.rs:781:5 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" cargo-0.49.0/src/cargo/ops/cargo_new.rs:800:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:163:36 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:27:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -993,8 +989,8 @@ cargo-0.49.0/src/cargo/ops/vendor.rs:320:60 clippy::case_sensitive_file_extensio cargo-0.49.0/src/cargo/ops/vendor.rs:324:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" cargo-0.49.0/src/cargo/ops/vendor.rs:70:1 clippy::too_many_lines "this function has too many lines (175/100)" cargo-0.49.0/src/cargo/sources/config.rs:102:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/config.rs:111:28 clippy::needless_question_mark "Question mark operator is useless here" -cargo-0.49.0/src/cargo/sources/config.rs:133:48 clippy::needless_question_mark "Question mark operator is useless here" +cargo-0.49.0/src/cargo/sources/config.rs:111:28 clippy::needless_question_mark "question mark operator is useless here" +cargo-0.49.0/src/cargo/sources/config.rs:133:48 clippy::needless_question_mark "question mark operator is useless here" cargo-0.49.0/src/cargo/sources/config.rs:135:67 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/cargo/sources/config.rs:206:36 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" cargo-0.49.0/src/cargo/sources/config.rs:282:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" @@ -1005,7 +1001,6 @@ cargo-0.49.0/src/cargo/sources/directory.rs:14:1 clippy::module_name_repetitions cargo-0.49.0/src/cargo/sources/directory.rs:90:56 clippy::redundant_closure_for_method_calls "redundant closure found" cargo-0.49.0/src/cargo/sources/git/source.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name" cargo-0.49.0/src/cargo/sources/git/source.rs:25:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/source.rs:34:25 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/sources/git/source.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" @@ -1065,7 +1060,6 @@ cargo-0.49.0/src/cargo/sources/registry/local.rs:12:1 clippy::module_name_repeti cargo-0.49.0/src/cargo/sources/registry/mod.rs:192:1 clippy::module_name_repetitions "item name starts with its containing module's name" cargo-0.49.0/src/cargo/sources/registry/mod.rs:203:1 clippy::module_name_repetitions "item name starts with its containing module's name" cargo-0.49.0/src/cargo/sources/registry/mod.rs:229:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:340:24 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/sources/registry/mod.rs:372:1 clippy::module_name_repetitions "item name starts with its containing module's name" cargo-0.49.0/src/cargo/sources/registry/mod.rs:373:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/sources/registry/mod.rs:375:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1090,7 +1084,6 @@ cargo-0.49.0/src/cargo/util/command_prelude.rs:222:1 clippy::must_use_candidate cargo-0.49.0/src/cargo/util/command_prelude.rs:234:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/command_prelude.rs:249:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/command_prelude.rs:264:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:265:19 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/command_prelude.rs:279:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/command_prelude.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/command_prelude.rs:320:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1131,11 +1124,11 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:1064:5 clippy::missing_errors_doc "doc cargo-0.49.0/src/cargo/util/config/mod.rs:1090:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:1166:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:1179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1181:33 clippy::needless_question_mark "Question mark operator is useless here" +cargo-0.49.0/src/cargo/util/config/mod.rs:1181:33 clippy::needless_question_mark "question mark operator is useless here" cargo-0.49.0/src/cargo/util/config/mod.rs:1184:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1186:33 clippy::needless_question_mark "Question mark operator is useless here" +cargo-0.49.0/src/cargo/util/config/mod.rs:1186:33 clippy::needless_question_mark "question mark operator is useless here" cargo-0.49.0/src/cargo/util/config/mod.rs:1189:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1191:33 clippy::needless_question_mark "Question mark operator is useless here" +cargo-0.49.0/src/cargo/util/config/mod.rs:1191:33 clippy::needless_question_mark "question mark operator is useless here" cargo-0.49.0/src/cargo/util/config/mod.rs:1203:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:1211:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:1216:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1172,7 +1165,6 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:1901:5 clippy::doc_markdown "you shoul cargo-0.49.0/src/cargo/util/config/mod.rs:214:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" cargo-0.49.0/src/cargo/util/config/mod.rs:259:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:299:12 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/config/mod.rs:311:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:318:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:353:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1190,7 +1182,6 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:689:20 clippy::unused_self "unused `se cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/config/mod.rs:748:30 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/config/mod.rs:816:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/config/path.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" cargo-0.49.0/src/cargo/util/config/path.rs:14:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -1276,7 +1267,6 @@ cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::missing_panics_doc "docs f cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/interning.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/into_url.rs:10:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/into_url_with_base.rs:14:24 clippy::manual_map "manual implementation of `Option::map`" cargo-0.49.0/src/cargo/util/into_url_with_base.rs:9:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" cargo-0.49.0/src/cargo/util/job.rs:20:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" cargo-0.49.0/src/cargo/util/lev_distance.rs:3:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" @@ -1832,7 +1822,7 @@ libc-0.2.81/src/unix/linux_like/linux/mod.rs:2572:9 clippy::needless_return "unn libc-0.2.81/src/unix/linux_like/linux/mod.rs:2578:20 clippy::zero_ptr "`0 as *mut _` detected" libc-0.2.81/src/unix/linux_like/linux/mod.rs:2588:13 clippy::zero_ptr "`0 as *mut _` detected" libc-0.2.81/src/unix/linux_like/linux/mod.rs:2590:13 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2596:52 clippy::used_underscore_binding "used binding `_dummy` which is prefixed with an underscore. A leading underscore signals that a binding will not be used." +libc-0.2.81/src/unix/linux_like/linux/mod.rs:2596:52 clippy::used_underscore_binding "used binding `_dummy` which is prefixed with an underscore. A leading underscore signals that a binding will not be used" libc-0.2.81/src/unix/linux_like/linux/mod.rs:2597:11 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" libc-0.2.81/src/unix/linux_like/linux/mod.rs:2601:21 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" libc-0.2.81/src/unix/linux_like/linux/mod.rs:2611:9 clippy::unused_unit "unneeded unit expression" @@ -2427,20 +2417,20 @@ rayon-1.5.0/src/iter/enumerate.rs:1:5 clippy::wildcard_imports "usage of wildcar rayon-1.5.0/src/iter/enumerate.rs:2:5 clippy::wildcard_imports "usage of wildcard import" rayon-1.5.0/src/iter/enumerate.rs:64:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" rayon-1.5.0/src/iter/enumerate.rs:68:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/extend.rs:143:63 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:182:57 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:218:32 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:218:59 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:25:42 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:287:62 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:322:56 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:41:27 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:47:30 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:47:56 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:47:74 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:53:29 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:57:36 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:59:61 clippy::linkedlist "I see you're using a LinkedList! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:143:63 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:182:57 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:218:32 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:218:59 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:25:42 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:287:62 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:322:56 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:41:27 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:47:30 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:47:56 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:47:74 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:53:29 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:57:36 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +rayon-1.5.0/src/iter/extend.rs:59:61 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" rayon-1.5.0/src/iter/filter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" rayon-1.5.0/src/iter/filter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" rayon-1.5.0/src/iter/filter_map.rs:123:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" @@ -3443,7 +3433,6 @@ clippy::invalid_upcast_comparisons 8 clippy::needless_question_mark 8 clippy::wrong_self_convention 8 clippy::multiple_crate_versions 9 -clippy::manual_map 10 clippy::manual_range_contains 10 clippy::match_wildcard_for_single_variants 10 clippy::missing_safety_doc 10 From ebc5c8f271cdb9e64f56b19273ff87745639433c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 28 Feb 2021 14:01:03 +0100 Subject: [PATCH 039/226] use different example (C-like) for valid capitalized start of lint message --- tests/lint_message_convention.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index d45d93f8184be..8c07c5b242f15 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -28,7 +28,7 @@ impl Message { ]) .unwrap(); - // sometimes the first character is capitalized and it is legal (like in "Iterator...") or + // sometimes the first character is capitalized and it is legal (like in "C-like enum variants") or // we want to ask a question ending in "?" let exceptions_set: RegexSet = RegexSet::new(&[ r".*C-like enum variant discriminant is not portable to 32-bit targets", From da3a57377ea34c1ddb0c0c41defb456b8dceed53 Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Sun, 28 Feb 2021 20:44:07 +0800 Subject: [PATCH 040/226] Fix false positives on procedural macros of `missing_inline_in_public_items` lint --- clippy_lints/src/missing_inline.rs | 8 ++++---- tests/ui/missing_inline_executable.rs | 5 +++++ tests/ui/missing_inline_proc_macro.rs | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 tests/ui/missing_inline_executable.rs create mode 100644 tests/ui/missing_inline_proc_macro.rs diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 47d7c5306c433..2448325e89980 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -69,21 +69,21 @@ fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp } } -fn is_executable(cx: &LateContext<'_>) -> bool { +fn is_executable_or_proc_macro(cx: &LateContext<'_>) -> bool { use rustc_session::config::CrateType; cx.tcx .sess .crate_types() .iter() - .any(|t: &CrateType| matches!(t, CrateType::Executable)) + .any(|t: &CrateType| matches!(t, CrateType::Executable | CrateType::ProcMacro)) } declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]); impl<'tcx> LateLintPass<'tcx> for MissingInline { fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { - if rustc_middle::lint::in_external_macro(cx.sess(), it.span) || is_executable(cx) { + if rustc_middle::lint::in_external_macro(cx.sess(), it.span) || is_executable_or_proc_macro(cx) { return; } @@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { use rustc_middle::ty::{ImplContainer, TraitContainer}; - if rustc_middle::lint::in_external_macro(cx.sess(), impl_item.span) || is_executable(cx) { + if rustc_middle::lint::in_external_macro(cx.sess(), impl_item.span) || is_executable_or_proc_macro(cx) { return; } diff --git a/tests/ui/missing_inline_executable.rs b/tests/ui/missing_inline_executable.rs new file mode 100644 index 0000000000000..6e0400ac935bb --- /dev/null +++ b/tests/ui/missing_inline_executable.rs @@ -0,0 +1,5 @@ +#![warn(clippy::missing_inline_in_public_items)] + +pub fn foo() {} + +fn main() {} diff --git a/tests/ui/missing_inline_proc_macro.rs b/tests/ui/missing_inline_proc_macro.rs new file mode 100644 index 0000000000000..3c68fb905f12d --- /dev/null +++ b/tests/ui/missing_inline_proc_macro.rs @@ -0,0 +1,23 @@ +#![warn(clippy::missing_inline_in_public_items)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +fn _foo() {} + +#[proc_macro] +pub fn function_like(_: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_attribute] +pub fn attribute(_: TokenStream, _: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_derive(Derive)] +pub fn derive(_: TokenStream) -> TokenStream { + TokenStream::new() +} From a3278a16d31198d45c710c3c4dde433fc77d8d90 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sun, 28 Feb 2021 09:03:21 -0500 Subject: [PATCH 041/226] Fix `manual_map`: do not expand macros in suggestions --- clippy_lints/src/manual_map.rs | 149 ++++++++++++++++-------------- clippy_utils/src/lib.rs | 33 ++++++- tests/ui/manual_map_option.fixed | 5 + tests/ui/manual_map_option.rs | 11 +++ tests/ui/manual_map_option.stderr | 20 +++- 5 files changed, 146 insertions(+), 72 deletions(-) diff --git a/clippy_lints/src/manual_map.rs b/clippy_lints/src/manual_map.rs index e6e70004527e4..983a10e8eaa22 100644 --- a/clippy_lints/src/manual_map.rs +++ b/clippy_lints/src/manual_map.rs @@ -3,7 +3,8 @@ use crate::{ matches::MATCH_AS_REF, utils::{ can_partially_move_ty, is_allowed, is_type_diagnostic_item, match_def_path, match_var, paths, - peel_hir_expr_refs, peel_mid_ty_refs_is_mutable, snippet_with_applicability, span_lint_and_sugg, + peel_hir_expr_refs, peel_mid_ty_refs_is_mutable, snippet_with_applicability, snippet_with_context, + span_lint_and_sugg, }, }; use rustc_ast::util::parser::PREC_POSTFIX; @@ -16,7 +17,10 @@ use rustc_hir::{ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::{ + symbol::{sym, Ident}, + SyntaxContext, +}; declare_clippy_lint! { /// **What it does:** Checks for usages of `match` which could be implemented using `map` @@ -56,43 +60,46 @@ impl LateLintPass<'_> for ManualMap { { let (scrutinee_ty, ty_ref_count, ty_mutability) = peel_mid_ty_refs_is_mutable(cx.typeck_results().expr_ty(scrutinee)); - if !is_type_diagnostic_item(cx, scrutinee_ty, sym::option_type) - || !is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::option_type) + if !(is_type_diagnostic_item(cx, scrutinee_ty, sym::option_type) + && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::option_type)) { return; } - let (some_expr, some_pat, pat_ref_count, is_wild_none) = - match (try_parse_pattern(cx, arm1.pat), try_parse_pattern(cx, arm2.pat)) { - (Some(OptionPat::Wild), Some(OptionPat::Some { pattern, ref_count })) - if is_none_expr(cx, arm1.body) => - { - (arm2.body, pattern, ref_count, true) - }, - (Some(OptionPat::None), Some(OptionPat::Some { pattern, ref_count })) - if is_none_expr(cx, arm1.body) => - { - (arm2.body, pattern, ref_count, false) - }, - (Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::Wild)) - if is_none_expr(cx, arm2.body) => - { - (arm1.body, pattern, ref_count, true) - }, - (Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::None)) - if is_none_expr(cx, arm2.body) => - { - (arm1.body, pattern, ref_count, false) - }, - _ => return, - }; + let expr_ctxt = expr.span.ctxt(); + let (some_expr, some_pat, pat_ref_count, is_wild_none) = match ( + try_parse_pattern(cx, arm1.pat, expr_ctxt), + try_parse_pattern(cx, arm2.pat, expr_ctxt), + ) { + (Some(OptionPat::Wild), Some(OptionPat::Some { pattern, ref_count })) + if is_none_expr(cx, arm1.body) => + { + (arm2.body, pattern, ref_count, true) + }, + (Some(OptionPat::None), Some(OptionPat::Some { pattern, ref_count })) + if is_none_expr(cx, arm1.body) => + { + (arm2.body, pattern, ref_count, false) + }, + (Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::Wild)) + if is_none_expr(cx, arm2.body) => + { + (arm1.body, pattern, ref_count, true) + }, + (Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::None)) + if is_none_expr(cx, arm2.body) => + { + (arm1.body, pattern, ref_count, false) + }, + _ => return, + }; // Top level or patterns aren't allowed in closures. if matches!(some_pat.kind, PatKind::Or(_)) { return; } - let some_expr = match get_some_expr(cx, some_expr) { + let some_expr = match get_some_expr(cx, some_expr, expr_ctxt) { Some(expr) => expr, None => return, }; @@ -119,47 +126,50 @@ impl LateLintPass<'_> for ManualMap { let mut app = Applicability::MachineApplicable; - // Remove address-of expressions from the scrutinee. `as_ref` will be called, - // the type is copyable, or the option is being passed by value. + // Remove address-of expressions from the scrutinee. Either `as_ref` will be called, or + // it's being passed by value. let scrutinee = peel_hir_expr_refs(scrutinee).0; - let scrutinee_str = snippet_with_applicability(cx, scrutinee.span, "_", &mut app); - let scrutinee_str = if expr.precedence().order() < PREC_POSTFIX { - // Parens are needed to chain method calls. - format!("({})", scrutinee_str) - } else { - scrutinee_str.into() - }; + let scrutinee_str = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app); + let scrutinee_str = + if scrutinee.span.ctxt() == expr.span.ctxt() && scrutinee.precedence().order() < PREC_POSTFIX { + format!("({})", scrutinee_str) + } else { + scrutinee_str.into() + }; let body_str = if let PatKind::Binding(annotation, _, some_binding, None) = some_pat.kind { - if let Some(func) = can_pass_as_func(cx, some_binding, some_expr) { - snippet_with_applicability(cx, func.span, "..", &mut app).into_owned() - } else { - if match_var(some_expr, some_binding.name) - && !is_allowed(cx, MATCH_AS_REF, expr.hir_id) - && binding_ref.is_some() - { - return; - } + match can_pass_as_func(cx, some_binding, some_expr) { + Some(func) if func.span.ctxt() == some_expr.span.ctxt() => { + snippet_with_applicability(cx, func.span, "..", &mut app).into_owned() + }, + _ => { + if match_var(some_expr, some_binding.name) + && !is_allowed(cx, MATCH_AS_REF, expr.hir_id) + && binding_ref.is_some() + { + return; + } - // `ref` and `ref mut` annotations were handled earlier. - let annotation = if matches!(annotation, BindingAnnotation::Mutable) { - "mut " - } else { - "" - }; - format!( - "|{}{}| {}", - annotation, - some_binding, - snippet_with_applicability(cx, some_expr.span, "..", &mut app) - ) + // `ref` and `ref mut` annotations were handled earlier. + let annotation = if matches!(annotation, BindingAnnotation::Mutable) { + "mut " + } else { + "" + }; + format!( + "|{}{}| {}", + annotation, + some_binding, + snippet_with_context(cx, some_expr.span, expr_ctxt, "..", &mut app) + ) + }, } } else if !is_wild_none && explicit_ref.is_none() { // TODO: handle explicit reference annotations. format!( "|{}| {}", - snippet_with_applicability(cx, some_pat.span, "..", &mut app), - snippet_with_applicability(cx, some_expr.span, "..", &mut app) + snippet_with_context(cx, some_pat.span, expr_ctxt, "..", &mut app), + snippet_with_context(cx, some_expr.span, expr_ctxt, "..", &mut app) ) } else { // Refutable bindings and mixed reference annotations can't be handled by `map`. @@ -246,11 +256,11 @@ enum OptionPat<'a> { // Try to parse into a recognized `Option` pattern. // i.e. `_`, `None`, `Some(..)`, or a reference to any of those. -fn try_parse_pattern(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) -> Option> { - fn f(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, ref_count: usize) -> Option> { +fn try_parse_pattern(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, ctxt: SyntaxContext) -> Option> { + fn f(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, ref_count: usize, ctxt: SyntaxContext) -> Option> { match pat.kind { PatKind::Wild => Some(OptionPat::Wild), - PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1), + PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1, ctxt), PatKind::Path(QPath::Resolved(None, path)) if path .res @@ -263,18 +273,19 @@ fn try_parse_pattern(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) -> Option + .map_or(false, |id| match_def_path(cx, id, &paths::OPTION_SOME)) + && pat.span.ctxt() == ctxt => { Some(OptionPat::Some { pattern, ref_count }) }, _ => None, } } - f(cx, pat, 0) + f(cx, pat, 0, ctxt) } // Checks for an expression wrapped by the `Some` constructor. Returns the contained expression. -fn get_some_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { +fn get_some_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ctxt: SyntaxContext) -> Option<&'tcx Expr<'tcx>> { // TODO: Allow more complex expressions. match expr.kind { ExprKind::Call( @@ -283,7 +294,7 @@ fn get_some_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx E .. }, [arg], - ) => { + ) if ctxt == expr.span.ctxt() => { if match_def_path(cx, path.res.opt_def_id()?, &paths::OPTION_SOME) { Some(arg) } else { @@ -297,7 +308,7 @@ fn get_some_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx E .. }, _, - ) => get_some_expr(cx, expr), + ) => get_some_expr(cx, expr, ctxt), _ => None, } } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 0552394351198..5d1093ea04040 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -73,11 +73,11 @@ use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, layout::IntegerExt, DefIdTree, Ty, TyCtxt, TypeFoldable}; use rustc_semver::RustcVersion; use rustc_session::Session; -use rustc_span::hygiene::{ExpnKind, MacroKind}; +use rustc_span::hygiene::{self, ExpnKind, MacroKind}; use rustc_span::source_map::original_sp; use rustc_span::sym; use rustc_span::symbol::{kw, Symbol}; -use rustc_span::{BytePos, Pos, Span, DUMMY_SP}; +use rustc_span::{BytePos, Pos, Span, SyntaxContext, DUMMY_SP}; use rustc_target::abi::Integer; use rustc_trait_selection::traits::query::normalize::AtExt; use smallvec::SmallVec; @@ -758,6 +758,35 @@ pub fn snippet_block_with_applicability<'a, T: LintContext>( reindent_multiline(snip, true, indent) } +/// Same as `snippet_with_applicability`, but first walks the span up to the given context. This +/// will result in the macro call, rather then the expansion, if the span is from a child context. +/// If the span is not from a child context, it will be used directly instead. +/// +/// e.g. Given the expression `&vec![]`, getting a snippet from the span for `vec![]` as a HIR node +/// would result in `box []`. If given the context of the address of expression, this function will +/// correctly get a snippet of `vec![]`. +pub fn snippet_with_context( + cx: &LateContext<'_>, + span: Span, + outer: SyntaxContext, + default: &'a str, + applicability: &mut Applicability, +) -> Cow<'a, str> { + let outer_span = hygiene::walk_chain(span, outer); + let span = if outer_span.ctxt() == outer { + outer_span + } else { + // The span is from a macro argument, and the outer context is the macro using the argument + if *applicability != Applicability::Unspecified { + *applicability = Applicability::MaybeIncorrect; + } + // TODO: get the argument span. + span + }; + + snippet_with_applicability(cx, span, default, applicability) +} + /// Returns a new Span that extends the original Span to the first non-whitespace char of the first /// line. /// diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed index 428aac4394079..e6fa10d22e1eb 100644 --- a/tests/ui/manual_map_option.fixed +++ b/tests/ui/manual_map_option.fixed @@ -110,4 +110,9 @@ fn main() { } } } + + // #6811 + Some(0).map(|x| vec![x]); + + option_env!("").map(String::from); } diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index 0f4a5bb2eb76d..7c2100299a719 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -162,4 +162,15 @@ fn main() { } } } + + // #6811 + match Some(0) { + Some(x) => Some(vec![x]), + None => None, + }; + + match option_env!("") { + Some(x) => Some(String::from(x)), + None => None, + }; } diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr index 49a5173778433..2d13213cf679b 100644 --- a/tests/ui/manual_map_option.stderr +++ b/tests/ui/manual_map_option.stderr @@ -154,5 +154,23 @@ LL | | None => None, LL | | }; | |_____^ help: try this: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` -error: aborting due to 17 previous errors +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:167:5 + | +LL | / match Some(0) { +LL | | Some(x) => Some(vec![x]), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `Some(0).map(|x| vec![x])` + +error: manual implementation of `Option::map` + --> $DIR/manual_map_option.rs:172:5 + | +LL | / match option_env!("") { +LL | | Some(x) => Some(String::from(x)), +LL | | None => None, +LL | | }; + | |_____^ help: try this: `option_env!("").map(String::from)` + +error: aborting due to 19 previous errors From d931d1b5e6d1ccb9290313dde986844966f3ee2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Feb 2021 00:29:42 +0100 Subject: [PATCH 042/226] lintcheck: refactor: introduce a basic LintcheckConfig struct which holds the job limit and paths to the sources and log files --- clippy_dev/src/lintcheck.rs | 111 +++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 45 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 65e438bc0e8d6..423daa0d19043 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -287,6 +287,61 @@ impl Crate { } } +#[derive(Debug)] +struct LintcheckConfig { + // max number of jobs to spawn (default 1) + max_jobs: usize, + // we read the sources to check from here + sources_toml_path: PathBuf, + // we save the clippy lint results here + lintcheck_results_path: PathBuf, +} + +impl LintcheckConfig { + fn from_clap(clap_config: &ArgMatches) -> Self { + // first, check if we got anything passed via the LINTCHECK_TOML env var, + // if not, ask clap if we got any value for --crates-toml + // if not, use the default "clippy_dev/lintcheck_crates.toml" + let sources_toml = env::var("LINTCHECK_TOML").unwrap_or( + clap_config + .value_of("crates-toml") + .clone() + .unwrap_or("clippy_dev/lintcheck_crates.toml") + .to_string(), + ); + + let sources_toml_path = PathBuf::from(sources_toml); + + // for the path where we save the lint results, get the filename without extenstion ( so for + // wasd.toml, use "wasd"....) + let filename: PathBuf = sources_toml_path.file_stem().unwrap().into(); + let lintcheck_results_path = PathBuf::from(format!("lintcheck-logs/{}_logs.txt", filename.display())); + + let max_jobs = match clap_config.value_of("threads") { + Some(threads) => { + let threads: usize = threads + .parse() + .expect(&format!("Failed to parse '{}' to a digit", threads)); + if threads == 0 { + // automatic choice + // Rayon seems to return thread count so half that for core count + (rayon::current_num_threads() / 2) as usize + } else { + threads + } + }, + // no -j passed, use a single thread + None => 1, + }; + + LintcheckConfig { + max_jobs, + sources_toml_path, + lintcheck_results_path, + } + } +} + /// takes a single json-formatted clippy warnings and returns true (we are interested in that line) /// or false (we aren't) fn filter_clippy_warnings(line: &str) -> bool { @@ -310,19 +365,6 @@ fn filter_clippy_warnings(line: &str) -> bool { false } -/// get the path to lintchecks crate sources .toml file, check LINTCHECK_TOML first but if it's -/// empty use the default path -fn lintcheck_config_toml(toml_path: Option<&str>) -> PathBuf { - PathBuf::from( - env::var("LINTCHECK_TOML").unwrap_or( - toml_path - .clone() - .unwrap_or("clippy_dev/lintcheck_crates.toml") - .to_string(), - ), - ) -} - /// Builds clippy inside the repo to make sure we have a clippy executable we can use. fn build_clippy() { let status = Command::new("cargo") @@ -336,9 +378,7 @@ fn build_clippy() { } /// Read a `toml` file and return a list of `CrateSources` that we want to check with clippy -fn read_crates(toml_path: &PathBuf) -> (String, Vec) { - // save it so that we can use the name of the sources.toml as name for the logfile later. - let toml_filename = toml_path.file_stem().unwrap().to_str().unwrap().to_string(); +fn read_crates(toml_path: &PathBuf) -> Vec { let toml_content: String = std::fs::read_to_string(&toml_path).unwrap_or_else(|_| panic!("Failed to read {}", toml_path.display())); let crate_list: SourceList = @@ -398,7 +438,7 @@ fn read_crates(toml_path: &PathBuf) -> (String, Vec) { // sort the crates crate_sources.sort(); - (toml_filename, crate_sources) + crate_sources } /// Parse the json output of clippy and return a `ClippyWarning` @@ -476,16 +516,15 @@ fn lintcheck_needs_rerun(toml_path: &PathBuf) -> bool { /// lintchecks `main()` function pub fn run(clap_config: &ArgMatches) { + let config = LintcheckConfig::from_clap(clap_config); + println!("Compiling clippy..."); build_clippy(); println!("Done compiling"); - let clap_toml_path: Option<&str> = clap_config.value_of("crates-toml"); - let toml_path: PathBuf = lintcheck_config_toml(clap_toml_path); - // if the clippy bin is newer than our logs, throw away target dirs to force clippy to // refresh the logs - if lintcheck_needs_rerun(&toml_path) { + if lintcheck_needs_rerun(&config.sources_toml_path) { let shared_target_dir = "target/lintcheck/shared_target_dir"; match std::fs::metadata(&shared_target_dir) { Ok(metadata) => { @@ -520,9 +559,8 @@ pub fn run(clap_config: &ArgMatches) { // download and extract the crates, then run clippy on them and collect clippys warnings // flatten into one big list of warnings - let (filename, crates) = read_crates(&toml_path); - let file = format!("lintcheck-logs/{}_logs.txt", filename); - let old_stats = read_stats_from_file(&file); + let crates = read_crates(&config.sources_toml_path); + let old_stats = read_stats_from_file(&config.lintcheck_results_path); let clippy_warnings: Vec = if let Some(only_one_crate) = clap_config.value_of("only") { // if we don't have the specified crate in the .toml, throw an error @@ -562,23 +600,7 @@ pub fn run(clap_config: &ArgMatches) { // order to achive some kind of parallelism // by default, use a single thread - let num_cpus = match clap_config.value_of("threads") { - Some(threads) => { - let threads: usize = threads - .parse() - .expect(&format!("Failed to parse '{}' to a digit", threads)); - if threads == 0 { - // automatic choice - // Rayon seems to return thread count so half that for core count - (rayon::current_num_threads() / 2) as usize - } else { - threads - } - }, - // no -j passed, use a single thread - None => 1, - }; - + let num_cpus = config.max_jobs; let num_crates = crates.len(); // check all crates (default) @@ -612,15 +634,14 @@ pub fn run(clap_config: &ArgMatches) { ices.iter() .for_each(|(cratename, msg)| text.push_str(&format!("{}: '{}'", cratename, msg))); - println!("Writing logs to {}", file); - write(&file, text).unwrap(); + println!("Writing logs to {}", config.lintcheck_results_path.display()); + write(&config.lintcheck_results_path, text).unwrap(); print_stats(old_stats, new_stats); } /// read the previous stats from the lintcheck-log file -fn read_stats_from_file(file_path: &String) -> HashMap { - let file_path = PathBuf::from(file_path); +fn read_stats_from_file(file_path: &PathBuf) -> HashMap { let file_content: String = match std::fs::read_to_string(file_path).ok() { Some(content) => content, None => { From 2d9932d720480e9f5e6cbe96bd5aadfd754fc074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Feb 2021 01:34:45 +0100 Subject: [PATCH 043/226] lintcheck: don't run clippy in parallel by default --- clippy_dev/src/lintcheck.rs | 57 +++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 423daa0d19043..00f406a085e93 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -588,28 +588,41 @@ pub fn run(clap_config: &ArgMatches) { .flatten() .collect() } else { - let counter = std::sync::atomic::AtomicUsize::new(0); - - // Ask rayon for thread count. Assume that half of that is the number of physical cores - // Use one target dir for each core so that we can run N clippys in parallel. - // We need to use different target dirs because cargo would lock them for a single build otherwise, - // killing the parallelism. However this also means that deps will only be reused half/a - // quarter of the time which might result in a longer wall clock runtime - - // This helps when we check many small crates with dep-trees that don't have a lot of branches in - // order to achive some kind of parallelism - - // by default, use a single thread - let num_cpus = config.max_jobs; - let num_crates = crates.len(); - - // check all crates (default) - crates - .into_par_iter() - .map(|krate| krate.download_and_extract()) - .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates)) - .flatten() - .collect() + if config.max_jobs > 1 { + // run parallel with rayon + + let counter = AtomicUsize::new(0); + + // Ask rayon for thread count. Assume that half of that is the number of physical cores + // Use one target dir for each core so that we can run N clippys in parallel. + // We need to use different target dirs because cargo would lock them for a single build otherwise, + // killing the parallelism. However this also means that deps will only be reused half/a + // quarter of the time which might result in a longer wall clock runtime + + // This helps when we check many small crates with dep-trees that don't have a lot of branches in + // order to achive some kind of parallelism + + // by default, use a single thread + let num_cpus = config.max_jobs; + let num_crates = crates.len(); + + // check all crates (default) + crates + .into_par_iter() + .map(|krate| krate.download_and_extract()) + .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates)) + .flatten() + .collect() + } else { + // run sequential + let num_crates = crates.len(); + crates + .into_iter() + .map(|krate| krate.download_and_extract()) + .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, num_crates)) + .flatten() + .collect() + } }; // generate some stats From e3386041a291c25d692e29d28dbb8fbfd7ef9c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Feb 2021 12:05:27 +0100 Subject: [PATCH 044/226] lintcheck: uses consts for clippy driver and cargo clippy paths --- clippy_dev/src/lintcheck.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 00f406a085e93..24af64626cb6e 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -19,6 +19,9 @@ use rayon::prelude::*; use serde::{Deserialize, Serialize}; use serde_json::Value; +const CLIPPY_DRIVER_PATH: &str = "target/debug/clippy-driver"; +const CARGO_CLIPPY_PATH: &str = "target/debug/cargo-clippy"; + /// List of sources to check, loaded from a .toml file #[derive(Debug, Serialize, Deserialize)] struct SourceList { @@ -317,6 +320,9 @@ impl LintcheckConfig { let filename: PathBuf = sources_toml_path.file_stem().unwrap().into(); let lintcheck_results_path = PathBuf::from(format!("lintcheck-logs/{}_logs.txt", filename.display())); + // look at the --threads arg, if 0 is passed, ask rayon rayon how many threads it would spawn and + // use half of that for the physical core count + // by default use a single thread let max_jobs = match clap_config.value_of("threads") { Some(threads) => { let threads: usize = threads @@ -492,14 +498,12 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String, /// clippy binary, if this is true, we should clean the lintchec shared target directory and recheck fn lintcheck_needs_rerun(toml_path: &PathBuf) -> bool { let clippy_modified: std::time::SystemTime = { - let mut times = ["target/debug/clippy-driver", "target/debug/cargo-clippy"] - .iter() - .map(|p| { - std::fs::metadata(p) - .expect("failed to get metadata of file") - .modified() - .expect("failed to get modification date") - }); + let mut times = [CLIPPY_DRIVER_PATH, CARGO_CLIPPY_PATH].iter().map(|p| { + std::fs::metadata(p) + .expect("failed to get metadata of file") + .modified() + .expect("failed to get modification date") + }); // the oldest modification of either of the binaries std::cmp::min(times.next().unwrap(), times.next().unwrap()) }; @@ -539,7 +543,7 @@ pub fn run(clap_config: &ArgMatches) { } } - let cargo_clippy_path: PathBuf = PathBuf::from("target/debug/cargo-clippy") + let cargo_clippy_path: PathBuf = PathBuf::from(CARGO_CLIPPY_PATH) .canonicalize() .expect("failed to canonicalize path to clippy binary"); @@ -550,7 +554,7 @@ pub fn run(clap_config: &ArgMatches) { cargo_clippy_path.display() ); - let clippy_ver = std::process::Command::new("target/debug/cargo-clippy") + let clippy_ver = std::process::Command::new(CARGO_CLIPPY_PATH) .arg("--version") .output() .map(|o| String::from_utf8_lossy(&o.stdout).into_owned()) From 1b1ed9359eef9f69c4d384ad1592ba5e1b1d83af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Feb 2021 12:29:13 +0100 Subject: [PATCH 045/226] lintcheck: put the full paths (target/lintcheck/sources/...) to the source files of a warning into the lintcheck log This is more convenient when reviewing new lint warnings that popped up in the logs --- clippy_dev/src/lintcheck.rs | 2 +- lintcheck-logs/lintcheck_crates_logs.txt | 6728 +++++++++++----------- 2 files changed, 3369 insertions(+), 3361 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 24af64626cb6e..622dad1740b7a 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -89,7 +89,7 @@ impl std::fmt::Display for ClippyWarning { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!( f, - r#"{}-{}/{}:{}:{} {} "{}""#, + r#"target/lintcheck/sources/{}-{}/{}:{}:{} {} "{}""#, &self.crate_name, &self.crate_version, &self.file, &self.line, &self.column, &self.linttype, &self.message ) } diff --git a/lintcheck-logs/lintcheck_crates_logs.txt b/lintcheck-logs/lintcheck_crates_logs.txt index cf6af1a549a06..b0ba84ed3f7c1 100644 --- a/lintcheck-logs/lintcheck_crates_logs.txt +++ b/lintcheck-logs/lintcheck_crates_logs.txt @@ -1,3364 +1,3371 @@ -clippy 0.1.52 (524f54c57 2021-02-26) +clippy 0.1.52 (e3386041a 2021-02-28) -cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" -cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" -cargo-0.49.0/src/bin/cargo/cli.rs:104:34 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/bin/cargo/cli.rs:121:5 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/bin/cargo/cli.rs:157:30 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/cli.rs:184:41 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -cargo-0.49.0/src/bin/cargo/cli.rs:196:42 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/cli.rs:200:39 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/cli.rs:231:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/bin/cargo/cli.rs:245:22 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -cargo-0.49.0/src/bin/cargo/cli.rs:247:47 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/cli.rs:257:22 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/cli.rs:26:20 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/bin/cargo/cli.rs:7:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/bench.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/bench.rs:76:59 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/build.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/check.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/clean.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/doc.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/fetch.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/fetch.rs:22:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/bin/cargo/commands/fix.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/generate_lockfile.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/git_checkout.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/help.rs:20:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/bin/cargo/commands/init.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/install.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/install.rs:97:16 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -cargo-0.49.0/src/bin/cargo/commands/locate_project.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/login.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/metadata.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/mod.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/new.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/new.rs:20:24 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -cargo-0.49.0/src/bin/cargo/commands/owner.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/owner.rs:38:43 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/owner.rs:39:43 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/owner.rs:40:43 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/owner.rs:43:30 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/owner.rs:46:30 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/package.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/pkgid.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/publish.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/publish.rs:40:47 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/read_manifest.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/run.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/rustc.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/rustdoc.rs:3:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/search.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/test.rs:127:54 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/test.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/tree.rs:149:49 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/tree.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/uninstall.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/update.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/vendor.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/vendor.rs:96:16 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -cargo-0.49.0/src/bin/cargo/commands/verify_project.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/version.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/yank.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/commands/yank.rs:32:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/yank.rs:33:35 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/yank.rs:34:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/commands/yank.rs:35:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/main.rs:100:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -cargo-0.49.0/src/bin/cargo/main.rs:118:41 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/main.rs:137:43 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/main.rs:148:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/bin/cargo/main.rs:174:57 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/main.rs:18:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" -cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" -cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `crossbeam-utils`: 0.6.6, 0.7.2" -cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" -cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" -cargo-0.49.0/src/bin/cargo/main.rs:72:22 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/main.rs:94:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -cargo-0.49.0/src/bin/cargo/main.rs:96:41 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/bin/cargo/main.rs:98:60 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:155:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:170:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:175:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:180:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:186:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:197:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:205:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:51:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:69:48 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -cargo-0.49.0/src/cargo/core/compiler/build_config.rs:96:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/build_context/mod.rs:44:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/build_context/mod.rs:83:20 clippy::doc_markdown "you should put `x86_64` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:108:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:121:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:149:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:411:9 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:420:69 clippy::doc_markdown "you should put `mode/target_kind` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:423:19 clippy::doc_markdown "you should put `CrateTypes` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:424:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:469:58 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:603:19 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:665:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:697:12 clippy::inconsistent_struct_constructor "inconsistent struct constructor" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:82:31 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:84:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:96:31 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:98:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:4:9 clippy::doc_markdown "you should put `BuildPlan` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:5:66 clippy::doc_markdown "you should put `BuildPlan` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:66:40 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:169:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:185:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:193:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:194:49 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:198:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:314:16 clippy::doc_markdown "you should put `rustc_tool` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/compilation.rs:91:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:118:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:123:18 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:157:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:33:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:49:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:69:48 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" -cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:204:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:277:22 clippy::doc_markdown "you should put `OUT_DIR` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:324:66 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:393:37 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:426:71 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::too_many_lines "this function has too many lines (107/100)" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:270:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:286:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:308:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:308:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:340:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:340:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:349:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:349:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:354:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:358:21 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:361:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:374:43 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:378:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:383:41 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:384:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:391:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:397:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:523:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:538:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:542:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:83:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:92:25 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:16:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:40:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:60:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:150:1 clippy::too_many_lines "this function has too many lines (230/100)" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:353:56 clippy::manual_strip "stripping a prefix manually" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:448:27 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:464:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:481:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:481:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:48:56 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:561:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:567:20 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:576:28 clippy::shadow_unrelated "`mut value` is being shadowed" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:606:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:688:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:756:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:762:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:762:5 clippy::unnecessary_wraps "this function's return value is unnecessary" -cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:823:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1021:51 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1656:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1664:5 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1787:5 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1795:5 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1882:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1894:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1906:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1917:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1923:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1956:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1962:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1963:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1964:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1965:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1966:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:24 clippy::manual_strip "stripping a prefix manually" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1986:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:2016:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:61:5 clippy::doc_markdown "you should put `CompileMode` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:63:12 clippy::doc_markdown "you should put `CompileKind` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:67:7 clippy::doc_markdown "you should put `CARGO_DEFAULT_LIB_METADATA[^4` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:68:5 clippy::doc_markdown "you should put `package_id` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:71:19 clippy::doc_markdown "you should put `test/bench/for_host/edition` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:755:52 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:77:5 clippy::doc_markdown "you should put `is_std` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:816:5 clippy::too_many_lines "this function has too many lines (127/100)" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:863:64 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:875:33 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:876:32 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:896:30 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:897:30 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:991:37 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:12:5 clippy::doc_markdown "you should put `src/librustc_jobserver/lib.rs` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:329:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:332:23 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:34:53 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:35:6 clippy::doc_markdown "you should put `ReleaseToken` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:37:6 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:40:5 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:40:56 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:43:6 clippy::doc_markdown "you should put `ReleaseToken` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:748:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:749:13 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:786:26 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:81:61 clippy::doc_markdown "you should put `DrainState` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:865:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:871:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:890:9 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:93:24 clippy::doc_markdown "you should put `JobQueue` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/links.rs:8:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:1016:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:1094:19 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:1131:1 clippy::unnecessary_wraps "this function's return value is unnecessary" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:1268:34 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:1277:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:179:1 clippy::too_many_lines "this function has too many lines (162/100)" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:198:78 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:201:25 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:267:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:324:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::unnecessary_wraps "this function's return value is unnecessary" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:392:45 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:415:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:464:18 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:488:61 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:667:15 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:693:1 clippy::unnecessary_wraps "this function's return value is unnecessary" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:725:42 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:736:1 clippy::too_many_lines "this function has too many lines (141/100)" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:73:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:777:12 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/compiler/mod.rs:873:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/output_depinfo.rs:41:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:16:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:57:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:72:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:134:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:16:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:30:28 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:16:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:192:64 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:212:58 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:234:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:355:13 clippy::cast_possible_truncation "casting `f64` to `u32` may truncate the value" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:355:13 clippy::cast_sign_loss "casting `f64` to `u32` may lose the sign of the value" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:397:38 clippy::cast_possible_truncation "casting `f64` to `u32` may truncate the value" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:397:38 clippy::cast_sign_loss "casting `f64` to `u32` may lose the sign of the value" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:484:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:605:38 clippy::doc_markdown "you should put `rmeta_time` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:605:50 clippy::doc_markdown "you should put `codegen_time` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/timings.rs:641:26 clippy::non_ascii_literal "literal non-ASCII character detected" -cargo-0.49.0/src/cargo/core/compiler/unit.rs:100:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/unit.rs:151:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/compiler/unit.rs:161:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/compiler/unit.rs:35:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:154:29 clippy::doc_markdown "you should put `state.unit_dependencies` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:213:1 clippy::too_many_lines "this function has too many lines (110/100)" -cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:52:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:52:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/compiler/unit_graph.rs:65:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/compiler/unit_graph.rs:65:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/dependency.rs:157:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/dependency.rs:182:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/dependency.rs:203:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:224:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:23:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/core/dependency.rs:248:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:270:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:274:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:278:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:287:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:291:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:305:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:311:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:319:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:337:75 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/dependency.rs:397:56 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/dependency.rs:403:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:408:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:415:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:419:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:424:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:428:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:433:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:438:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:443:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:449:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/dependency.rs:450:9 clippy::if_not_else "unnecessary `!=` operation" -cargo-0.49.0/src/cargo/core/features.rs:119:17 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/features.rs:229:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/features.rs:274:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/features.rs:278:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/features.rs:306:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/features.rs:338:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/core/features.rs:362:25 clippy::option_option "consider using `Option` instead of `Option>` or a custom enum if you need to distinguish all 3 cases" -cargo-0.49.0/src/cargo/core/features.rs:380:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/features.rs:401:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/features.rs:409:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/features.rs:412:45 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/features.rs:416:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/features.rs:419:45 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/features.rs:424:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/features.rs:431:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/features.rs:477:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/features.rs:509:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/features.rs:518:5 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -cargo-0.49.0/src/cargo/core/features.rs:542:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/features.rs:543:37 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/features.rs:547:60 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/features.rs:556:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/features.rs:563:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/manifest.rs:116:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -cargo-0.49.0/src/cargo/core/manifest.rs:118:58 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/manifest.rs:130:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -cargo-0.49.0/src/cargo/core/manifest.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:159:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:162:34 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/manifest.rs:169:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:17:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/cargo/core/manifest.rs:189:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/core/manifest.rs:215:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:222:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:22:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/manifest.rs:360:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:407:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:410:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:413:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:416:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:419:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:422:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:425:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:431:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:438:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:444:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:447:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:450:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:453:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:456:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:459:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:462:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:466:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:470:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:477:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:481:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:488:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/manifest.rs:512:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:516:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:520:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:524:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:528:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:538:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:557:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:561:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:565:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:569:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:577:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:581:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:588:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:617:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:632:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:648:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:659:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:66:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/manifest.rs:670:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:693:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:708:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:723:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:726:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:729:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:735:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:738:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:741:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:744:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:747:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:751:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:754:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:757:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:760:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:763:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:767:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:776:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:780:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:787:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:798:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:800:56 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/manifest.rs:805:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:809:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:818:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:823:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:828:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:831:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:834:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:839:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:85:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/manifest.rs:888:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/manifest.rs:936:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:1075:28 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/package.rs:160:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:170:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:174:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:182:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:186:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:190:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:194:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/package.rs:194:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:198:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:202:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:206:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:210:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:217:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:221:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:222:35 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/package.rs:226:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:227:35 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/package.rs:230:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:239:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:249:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package.rs:287:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/package.rs:385:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:421:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -cargo-0.49.0/src/cargo/core/package.rs:425:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:452:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:453:60 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/package.rs:459:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:473:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:587:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:588:9 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/core/package.rs:682:46 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" -cargo-0.49.0/src/cargo/core/package.rs:682:46 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" -cargo-0.49.0/src/cargo/core/package.rs:682:63 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" -cargo-0.49.0/src/cargo/core/package.rs:682:63 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" -cargo-0.49.0/src/cargo/core/package.rs:731:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package.rs:790:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/package.rs:988:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/package_id.rs:115:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package_id.rs:124:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/package_id.rs:124:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:139:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:145:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:149:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:161:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:169:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id.rs:174:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:101:39 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:160:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:212:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:231:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/package_id_spec.rs:88:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:1004:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:1014:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:1018:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:1028:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:106:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/profiles.rs:143:5 clippy::unnecessary_wraps "this function's return value is unnecessary" -cargo-0.49.0/src/cargo/core/profiles.rs:286:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/profiles.rs:286:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:294:40 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/profiles.rs:30:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/profiles.rs:342:25 clippy::shadow_unrelated "`maker` is being shadowed" -cargo-0.49.0/src/cargo/core/profiles.rs:370:41 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/core/profiles.rs:370:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:372:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" -cargo-0.49.0/src/cargo/core/profiles.rs:382:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/profiles.rs:382:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:383:28 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/profiles.rs:397:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:405:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/profiles.rs:607:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/core/profiles.rs:909:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:923:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:934:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/profiles.rs:987:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/registry.rs:111:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/registry.rs:127:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/registry.rs:168:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/registry.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/registry.rs:240:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/registry.rs:26:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/registry.rs:344:49 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/registry.rs:369:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/registry.rs:424:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/registry.rs:49:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/registry.rs:520:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/registry.rs:763:53 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/registry.rs:765:53 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/registry.rs:807:14 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/registry.rs:814:53 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/conflict_cache.rs:197:29 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/conflict_cache.rs:41:38 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -cargo-0.49.0/src/cargo/core/resolver/context.rs:274:53 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/context.rs:42:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/resolver/context.rs:74:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::too_many_lines "this function has too many lines (164/100)" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:339:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:438:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:449:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:529:34 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:602:59 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:623:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:652:27 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/resolver/encode.rs:674:51 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/errors.rs:103:22 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/errors.rs:104:22 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/errors.rs:206:9 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/resolver/errors.rs:257:45 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/errors.rs:27:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/errors.rs:305:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/core/resolver/errors.rs:70:1 clippy::too_many_lines "this function has too many lines (207/100)" -cargo-0.49.0/src/cargo/core/resolver/features.rs:104:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/resolver/features.rs:111:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/features.rs:162:56 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/features.rs:179:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/resolver/features.rs:186:23 clippy::doc_markdown "you should put `RequestedFeatures` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/resolver/features.rs:187:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/features.rs:199:23 clippy::doc_markdown "you should put `RequestedFeatures` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/resolver/features.rs:200:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/features.rs:221:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/features.rs:231:21 clippy::doc_markdown "you should put `pkg_id/is_build` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/resolver/features.rs:233:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/features.rs:247:58 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/features.rs:278:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/features.rs:394:27 clippy::doc_markdown "you should put `FeatureValue` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/resolver/features.rs:460:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/resolver/features.rs:480:24 clippy::doc_markdown "you should put `FeatureValues` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/resolver/features.rs:496:24 clippy::doc_markdown "you should put `FeatureValues` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/resolver/features.rs:58:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/core/resolver/features.rs:67:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:1017:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:1045:57 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:122:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:142:44 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:180:1 clippy::too_many_lines "this function has too many lines (225/100)" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:311:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:421:52 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:457:69 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:470:37 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:607:11 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:631:21 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:942:15 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/resolver/mod.rs:988:20 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:120:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:132:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:199:24 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:235:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:239:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:255:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:259:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:269:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:273:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:274:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:280:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:284:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:288:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:292:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:296:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:300:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:315:13 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:354:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:362:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:60:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/resolver/resolve.rs:76:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/types.rs:111:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/resolver/types.rs:121:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/types.rs:141:19 clippy::doc_markdown "you should put `ResolveOpts` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/resolver/types.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/types.rs:149:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/resolver/types.rs:181:9 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -cargo-0.49.0/src/cargo/core/resolver/types.rs:187:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -cargo-0.49.0/src/cargo/core/resolver/types.rs:261:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -cargo-0.49.0/src/cargo/core/shell.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:130:9 clippy::single_match_else "you seem to be trying to use `match` for an equality check. Consider using `if`" -cargo-0.49.0/src/cargo/core/shell.rs:148:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:153:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:163:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:18:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:198:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:206:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:214:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:228:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:239:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:250:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:259:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:267:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:26:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:282:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:314:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:322:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/shell.rs:330:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/shell.rs:345:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/shell.rs:459:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/core/shell.rs:98:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/mod.rs:103:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:247:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/source/mod.rs:261:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/mod.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/mod.rs:273:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/mod.rs:291:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/mod.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/mod.rs:307:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/mod.rs:31:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:37:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:39:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:47:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:50:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:52:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:63:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:74:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/mod.rs:83:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:128:50 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/source/source_id.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:162:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:166:19 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/source/source_id.rs:167:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:171:19 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/source/source_id.rs:172:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:178:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:187:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:187:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:18:74 clippy::default_trait_access "calling `std::sync::Mutex::default()` is more clear than this expression" -cargo-0.49.0/src/cargo/core/source/source_id.rs:195:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:207:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:213:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:217:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:225:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:228:16 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" -cargo-0.49.0/src/cargo/core/source/source_id.rs:236:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:241:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:252:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:257:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:262:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:305:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:310:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:318:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:326:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:338:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/source/source_id.rs:355:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/source/source_id.rs:393:61 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:394:42 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:395:42 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:397:71 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:397:71 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:398:47 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:398:47 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:399:47 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:399:47 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:401:63 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:401:63 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:401:63 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:402:43 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:402:43 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:402:43 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:403:43 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:403:43 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:403:43 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:406:21 clippy::enum_glob_use "usage of wildcard import for enum variants" -cargo-0.49.0/src/cargo/core/source/source_id.rs:412:41 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:413:36 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:414:36 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:420:47 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:420:47 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/source/source_id.rs:512:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:513:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:517:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:518:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:525:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:526:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:530:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:531:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:535:33 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:536:37 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:537:42 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:538:38 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/core/source/source_id.rs:548:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/source/source_id.rs:597:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:103:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:123:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:150:1 clippy::too_many_lines "this function has too many lines (141/100)" -cargo-0.49.0/src/cargo/core/summary.rs:158:9 clippy::enum_glob_use "usage of wildcard import for enum variants" -cargo-0.49.0/src/cargo/core/summary.rs:181:21 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/summary.rs:192:28 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/summary.rs:258:32 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/summary.rs:281:28 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/summary.rs:303:28 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/summary.rs:321:51 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/core/summary.rs:344:5 clippy::doc_markdown "you should put `FeatureValue` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/summary.rs:350:85 clippy::doc_markdown "you should put `FeatureValue` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/summary.rs:36:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/summary.rs:378:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:386:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:387:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -cargo-0.49.0/src/cargo/core/summary.rs:407:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -cargo-0.49.0/src/cargo/core/summary.rs:69:34 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/summary.rs:75:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:78:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:81:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:84:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:87:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:90:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:93:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:96:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/summary.rs:99:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/workspace.rs:1056:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -cargo-0.49.0/src/cargo/core/workspace.rs:113:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/workspace.rs:1157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/core/workspace.rs:128:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/core/workspace.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:159:16 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/workspace.rs:197:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:225:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:225:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/workspace.rs:255:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:267:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:317:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/workspace.rs:329:37 clippy::doc_markdown "you should put `VirtualManifest` between ticks in the documentation" -cargo-0.49.0/src/cargo/core/workspace.rs:410:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:440:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -cargo-0.49.0/src/cargo/core/workspace.rs:511:32 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/workspace.rs:561:25 clippy::non_ascii_literal "literal non-ASCII character detected" -cargo-0.49.0/src/cargo/core/workspace.rs:613:13 clippy::filter_map "called `filter_map(..).map(..)` on an `Iterator`" -cargo-0.49.0/src/cargo/core/workspace.rs:615:22 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/core/workspace.rs:762:27 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/core/workspace.rs:784:17 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/core/workspace.rs:849:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:849:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/core/workspace.rs:893:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/core/workspace.rs:906:24 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/core/workspace.rs:932:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/lib.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" -cargo-0.49.0/src/cargo/lib.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" -cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `crossbeam-utils`: 0.6.6, 0.7.2" -cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" -cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" -cargo-0.49.0/src/cargo/ops/cargo_clean.rs:205:23 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_clean.rs:27:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_clean.rs:27:1 clippy::too_many_lines "this function has too many lines (120/100)" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:1078:14 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:109:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:119:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:1227:17 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:127:35 clippy::from_iter_instead_of_collect "usage of `FromIterator::from_iter`" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:173:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:205:36 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:242:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:249:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:258:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:267:16 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::too_many_lines "this function has too many lines (219/100)" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:468:9 clippy::default_trait_access "calling `std::collections::HashMap::default()` is more clear than this expression" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:548:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:556:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:574:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:583:21 clippy::doc_markdown "you should put `CompileFilter` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:584:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:584:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:592:9 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:593:9 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:607:13 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:612:21 clippy::doc_markdown "you should put `CompileFilter` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:613:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:618:9 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:641:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:652:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:655:50 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:673:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:692:49 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:703:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:729:1 clippy::too_many_lines "this function has too many lines (205/100)" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:82:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_compile.rs:874:69 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_doc.rs:20:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_fetch.rs:15:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_fetch.rs:27:46 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:160:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:175:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:22:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::too_many_lines "this function has too many lines (171/100)" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:13:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:148:1 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:148:1 clippy::too_many_lines "this function has too many lines (316/100)" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:178:24 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:202:17 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:236:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:312:64 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:32:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:339:12 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:454:22 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:483:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:683:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_install.rs:708:5 clippy::manual_flatten "unnecessary `if let` since only the `Some` variant of the iterator element is used" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:101:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:245:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:251:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:367:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:405:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:489:5 clippy::doc_markdown "you should put `IgnoreList` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:525:47 clippy::doc_markdown "you should put `IgnoreList` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:525:9 clippy::doc_markdown "you should put `format_existing` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:572:34 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:623:1 clippy::too_many_lines "this function has too many lines (130/100)" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:781:5 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" -cargo-0.49.0/src/cargo/ops/cargo_new.rs:800:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:163:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:27:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:45:45 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:144:1 clippy::too_many_lines "this function has too many lines (112/100)" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:207:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:25:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:307:54 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:394:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:425:61 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:459:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:66:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:69:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/ops/cargo_package.rs:93:20 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/ops/cargo_pkgid.rs:5:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:14:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:171:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:57:49 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:69:37 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/cargo_run.rs:25:24 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/ops/cargo_run.rs:35:9 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/ops/cargo_run.rs:37:16 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/ops/cargo_run.rs:53:9 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/ops/cargo_run.rs:65:16 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/ops/cargo_run.rs:9:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_test.rs:16:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_test.rs:43:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_test.rs:84:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/ops/cargo_uninstall.rs:14:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/cargo_uninstall.rs:7:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:147:9 clippy::doc_markdown "you should put `PackageId` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:233:21 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:244:22 clippy::doc_markdown "you should put `PackageId` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:244:63 clippy::doc_markdown "you should put `PackageId` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:253:17 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:370:5 clippy::unnecessary_wraps "this function's return value is unnecessary" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:505:8 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:525:10 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:542:27 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:542:5 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:561:20 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:613:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:645:41 clippy::doc_markdown "you should put `BTreeSet` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:92:19 clippy::doc_markdown "you should put `InstallTracker` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/fix.rs:200:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/fix.rs:200:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/fix.rs:424:20 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -cargo-0.49.0/src/cargo/ops/fix.rs:455:13 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/ops/fix.rs:506:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/ops/fix.rs:608:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" -cargo-0.49.0/src/cargo/ops/fix.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/fix.rs:619:48 clippy::manual_strip "stripping a prefix manually" -cargo-0.49.0/src/cargo/ops/fix.rs:66:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/fix.rs:66:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/ops/fix.rs:708:18 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/fix.rs:77:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/lockfile.rs:154:13 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/ops/lockfile.rs:217:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/ops/lockfile.rs:30:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/lockfile.rs:35:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/lockfile.rs:35:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/ops/lockfile.rs:87:1 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -cargo-0.49.0/src/cargo/ops/lockfile.rs:8:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/lockfile.rs:8:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/ops/registry.rs:150:21 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/registry.rs:188:1 clippy::too_many_lines "this function has too many lines (130/100)" -cargo-0.49.0/src/cargo/ops/registry.rs:212:32 clippy::if_not_else "unnecessary `!=` operation" -cargo-0.49.0/src/cargo/ops/registry.rs:222:53 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/registry.rs:224:44 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/ops/registry.rs:31:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/registry.rs:346:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:346:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/registry.rs:351:26 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/registry.rs:385:12 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/ops/registry.rs:386:15 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/ops/registry.rs:38:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/ops/registry.rs:477:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:483:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:503:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:505:38 clippy::default_trait_access "calling `util::config::CargoHttpConfig::default()` is more clear than this expression" -cargo-0.49.0/src/cargo/ops/registry.rs:510:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:529:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/registry.rs:53:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:53:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/ops/registry.rs:573:22 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/registry.rs:608:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:621:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:671:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:671:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/registry.rs:674:10 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/ops/registry.rs:678:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/registry.rs:730:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:731:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/registry.rs:785:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/registry.rs:794:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/registry.rs:828:14 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/registry.rs:848:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::too_many_lines "this function has too many lines (137/100)" -cargo-0.49.0/src/cargo/ops/resolve.rs:241:28 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/resolve.rs:28:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/ops/resolve.rs:384:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/resolve.rs:417:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/resolve.rs:589:9 clippy::shadow_unrelated "`keep` is being shadowed" -cargo-0.49.0/src/cargo/ops/resolve.rs:58:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/resolve.rs:58:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/resolve.rs:602:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/resolve.rs:75:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/resolve.rs:75:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/tree/graph.rs:129:26 clippy::doc_markdown "you should put `PackageIds` between ticks in the documentation" -cargo-0.49.0/src/cargo/ops/tree/graph.rs:152:15 clippy::match_on_vec_items "indexing into a vector may panic" -cargo-0.49.0/src/cargo/ops/tree/graph.rs:173:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/ops/tree/graph.rs:234:46 clippy::filter_map "called `filter(..).flat_map(..)` on an `Iterator`" -cargo-0.49.0/src/cargo/ops/tree/graph.rs:328:44 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/tree/graph.rs:330:50 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/tree/graph.rs:563:35 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:112:11 clippy::non_ascii_literal "literal non-ASCII character detected" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:113:10 clippy::non_ascii_literal "literal non-ASCII character detected" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:114:10 clippy::non_ascii_literal "literal non-ASCII character detected" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:115:12 clippy::non_ascii_literal "literal non-ASCII character detected" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:126:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:21:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:21:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:360:30 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/tree/mod.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/ops/vendor.rs:14:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/ops/vendor.rs:215:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/ops/vendor.rs:21:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/ops/vendor.rs:21:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/ops/vendor.rs:314:34 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/ops/vendor.rs:320:29 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" -cargo-0.49.0/src/cargo/ops/vendor.rs:320:60 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" -cargo-0.49.0/src/cargo/ops/vendor.rs:324:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -cargo-0.49.0/src/cargo/ops/vendor.rs:70:1 clippy::too_many_lines "this function has too many lines (175/100)" -cargo-0.49.0/src/cargo/sources/config.rs:102:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/config.rs:111:28 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/sources/config.rs:133:48 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/sources/config.rs:135:67 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/sources/config.rs:206:36 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/sources/config.rs:282:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/sources/config.rs:70:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/config.rs:81:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/config.rs:97:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/sources/directory.rs:14:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/directory.rs:90:56 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/sources/git/source.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/sources/git/source.rs:25:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/source.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/sources/git/source.rs:69:20 clippy::comparison_to_empty "comparison to empty slice" -cargo-0.49.0/src/cargo/sources/git/utils.rs:1025:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/sources/git/utils.rs:1157:36 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" -cargo-0.49.0/src/cargo/sources/git/utils.rs:1158:9 clippy::manual_strip "stripping a suffix manually" -cargo-0.49.0/src/cargo/sources/git/utils.rs:176:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/sources/git/utils.rs:180:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/sources/git/utils.rs:184:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/utils.rs:188:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/utils.rs:242:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/utils.rs:253:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/utils.rs:262:13 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/sources/git/utils.rs:289:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/utils.rs:294:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/sources/git/utils.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/utils.rs:308:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/git/utils.rs:472:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/sources/git/utils.rs:489:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/sources/git/utils.rs:503:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/sources/git/utils.rs:528:28 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/sources/git/utils.rs:537:21 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/sources/git/utils.rs:588:1 clippy::too_many_lines "this function has too many lines (135/100)" -cargo-0.49.0/src/cargo/sources/git/utils.rs:692:9 clippy::vec_init_then_push "calls to `push` immediately after creation" -cargo-0.49.0/src/cargo/sources/git/utils.rs:758:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/sources/git/utils.rs:858:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/path.rs:129:44 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/sources/path.rs:143:44 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/sources/path.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/path.rs:282:50 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/sources/path.rs:313:21 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/sources/path.rs:314:21 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/sources/path.rs:319:21 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/sources/path.rs:339:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/sources/path.rs:339:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -cargo-0.49.0/src/cargo/sources/path.rs:380:9 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/sources/path.rs:419:50 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/sources/path.rs:429:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/path.rs:460:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/sources/path.rs:473:43 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/sources/path.rs:482:43 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/sources/path.rs:63:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/path.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/path.rs:98:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/index.rs:117:23 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/sources/registry/index.rs:121:70 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/sources/registry/index.rs:167:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/index.rs:215:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/index.rs:324:23 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/sources/registry/index.rs:468:40 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" -cargo-0.49.0/src/cargo/sources/registry/index.rs:590:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/sources/registry/index.rs:648:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/sources/registry/index.rs:736:1 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -cargo-0.49.0/src/cargo/sources/registry/index.rs:95:37 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -cargo-0.49.0/src/cargo/sources/registry/local.rs:12:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:192:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:203:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:229:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:372:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:373:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:375:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:381:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:382:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:383:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:384:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:452:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:582:20 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/sources/registry/mod.rs:621:9 clippy::if_not_else "unnecessary `!=` operation" -cargo-0.49.0/src/cargo/sources/registry/remote.rs:139:17 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/sources/registry/remote.rs:32:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/sources/registry/remote.rs:72:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/sources/replaced.rs:12:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/sources/replaced.rs:5:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/canonical_url.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/canonical_url.rs:19:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/canonical_url.rs:50:41 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" -cargo-0.49.0/src/cargo/util/canonical_url.rs:65:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:218:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:222:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:234:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:249:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:264:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:279:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:320:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:328:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:352:13 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/util/command_prelude.rs:363:13 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/util/command_prelude.rs:378:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:387:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:387:5 clippy::too_many_lines "this function has too many lines (104/100)" -cargo-0.49.0/src/cargo/util/command_prelude.rs:39:20 clippy::doc_markdown "you should put `arg_package_spec` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/command_prelude.rs:504:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:516:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:530:40 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/command_prelude.rs:531:43 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/command_prelude.rs:536:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:556:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:575:49 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/command_prelude.rs:580:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/command_prelude.rs:631:18 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/command_prelude.rs:638:18 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/command_prelude.rs:647:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:651:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:662:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/command_prelude.rs:665:51 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/util/config/de.rs:420:16 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/util/config/de.rs:46:25 clippy::doc_markdown "you should put `CV::List` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/config/de.rs:47:24 clippy::doc_markdown "you should put `ConfigSeqAccess` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/config/de.rs:527:53 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/util/config/de.rs:530:53 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/util/config/de.rs:532:68 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/util/config/key.rs:11:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/key.rs:69:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/util/config/mod.rs:100:71 clippy::doc_markdown "you should put `OptValue` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/config/mod.rs:100:71 clippy::doc_markdown "you should put `OptValue` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/config/mod.rs:100:71 clippy::doc_markdown "you should put `OptValue` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/config/mod.rs:1049:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1064:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1090:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1166:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1181:33 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/util/config/mod.rs:1184:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1186:33 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/util/config/mod.rs:1189:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1191:33 clippy::needless_question_mark "question mark operator is useless here" -cargo-0.49.0/src/cargo/util/config/mod.rs:1203:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1211:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1216:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1225:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1229:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:124:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -cargo-0.49.0/src/cargo/util/config/mod.rs:1254:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1279:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1281:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -cargo-0.49.0/src/cargo/util/config/mod.rs:1323:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/config/mod.rs:1339:39 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/util/config/mod.rs:1344:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/config/mod.rs:1420:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/config/mod.rs:1553:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1560:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1567:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1574:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1581:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1588:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/config/mod.rs:1598:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/config/mod.rs:1619:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/config/mod.rs:1623:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1623:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:1623:64 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/util/config/mod.rs:1649:9 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" -cargo-0.49.0/src/cargo/util/config/mod.rs:1699:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/config/mod.rs:1730:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/mod.rs:1757:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/mod.rs:1770:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/mod.rs:1778:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/mod.rs:1804:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/mod.rs:1896:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/config/mod.rs:1901:5 clippy::doc_markdown "you should put `StringList` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/config/mod.rs:214:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -cargo-0.49.0/src/cargo/util/config/mod.rs:259:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:311:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:318:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:353:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:401:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:411:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:419:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:431:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:449:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:454:16 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -cargo-0.49.0/src/cargo/util/config/mod.rs:547:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:556:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:582:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:595:20 clippy::doc_markdown "you should put `StringList` between ticks in the documentation" -cargo-0.49.0/src/cargo/util/config/mod.rs:689:20 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" -cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/config/mod.rs:816:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/config/path.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/path.rs:14:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/config/path.rs:48:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/config/target.rs:12:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/config/target.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/config/value.rs:29:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/config/value.rs:70:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/config/value.rs:80:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/config/value.rs:81:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" -cargo-0.49.0/src/cargo/util/cpu.rs:11:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/cpu.rs:22:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/cpu.rs:82:25 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -cargo-0.49.0/src/cargo/util/cpu.rs:82:9 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -cargo-0.49.0/src/cargo/util/dependency_queue.rs:109:27 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/dependency_queue.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/dependency_queue.rs:151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/dependency_queue.rs:156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/dependency_queue.rs:168:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/dependency_queue.rs:46:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/dependency_queue.rs:91:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/diagnostic_server.rs:218:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/diagnostic_server.rs:230:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/diagnostic_server.rs:242:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/diagnostic_server.rs:58:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/diagnostic_server.rs:96:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/diagnostic_server.rs:96:5 clippy::too_many_lines "this function has too many lines (110/100)" -cargo-0.49.0/src/cargo/util/diagnostic_server.rs:99:21 clippy::shadow_unrelated "`msg` is being shadowed" -cargo-0.49.0/src/cargo/util/errors.rs:101:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:150:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:15:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/errors.rs:237:5 clippy::pub_enum_variant_names "variant name ends with the enum's name" -cargo-0.49.0/src/cargo/util/errors.rs:245:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:321:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:328:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:356:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:391:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/errors.rs:392:13 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/cargo/util/errors.rs:465:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/errors.rs:473:5 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -cargo-0.49.0/src/cargo/util/errors.rs:66:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:115:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:11:5 clippy::wildcard_imports "usage of wildcard import" -cargo-0.49.0/src/cargo/util/flock.rs:134:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/flock.rs:156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:170:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/flock.rs:192:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/flock.rs:29:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/flock.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:321:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/flock.rs:335:23 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value" -cargo-0.49.0/src/cargo/util/flock.rs:335:23 clippy::cast_sign_loss "casting `i64` to `u32` may lose the sign of the value" -cargo-0.49.0/src/cargo/util/flock.rs:335:44 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value" -cargo-0.49.0/src/cargo/util/flock.rs:379:35 clippy::match_same_arms "this `match` has identical arm bodies" -cargo-0.49.0/src/cargo/util/flock.rs:37:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/flock.rs:96:17 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/util/graph.rs:10:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/graph.rs:41:51 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/graph.rs:45:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/hasher.rs:12:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/hasher.rs:9:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/hex.rs:10:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/hex.rs:11:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/hex.rs:12:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/hex.rs:13:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/hex.rs:14:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/hex.rs:15:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/hex.rs:25:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/hex.rs:6:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/hex.rs:6:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/hex.rs:8:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/hex.rs:9:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" -cargo-0.49.0/src/cargo/util/important_paths.rs:23:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/important_paths.rs:6:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/interning.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/into_url.rs:10:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/into_url_with_base.rs:9:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/job.rs:20:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/lev_distance.rs:3:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/lockserver.rs:111:32 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/util/lockserver.rs:158:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/lockserver.rs:46:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/lockserver.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/lockserver.rs:62:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/mod.rs:68:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/mod.rs:79:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/network.rs:12:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/network.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/network.rs:84:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:109:12 clippy::redundant_else "redundant else block" -cargo-0.49.0/src/cargo/util/paths.rs:114:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:121:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:125:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:130:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:14:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name" -cargo-0.49.0/src/cargo/util/paths.rs:151:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:167:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:173:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:178:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:185:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:199:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:215:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:228:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/paths.rs:251:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -cargo-0.49.0/src/cargo/util/paths.rs:267:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:276:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:29:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/paths.rs:303:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:312:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:346:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:415:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:445:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:459:45 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/paths.rs:514:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/util/paths.rs:54:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/paths.rs:61:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/paths.rs:63:19 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" -cargo-0.49.0/src/cargo/util/paths.rs:88:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/paths.rs:93:31 clippy::comparison_to_empty "comparison to empty slice" -cargo-0.49.0/src/cargo/util/process_builder.rs:106:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/process_builder.rs:111:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/process_builder.rs:122:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/process_builder.rs:132:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/process_builder.rs:152:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/process_builder.rs:185:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/process_builder.rs:190:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/process_builder.rs:218:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/process_builder.rs:218:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/process_builder.rs:278:22 clippy::inconsistent_struct_constructor "inconsistent struct constructor" -cargo-0.49.0/src/cargo/util/process_builder.rs:307:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/process_builder.rs:343:39 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -cargo-0.49.0/src/cargo/util/progress.rs:122:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/progress.rs:136:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/progress.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/progress.rs:249:19 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -cargo-0.49.0/src/cargo/util/progress.rs:249:34 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -cargo-0.49.0/src/cargo/util/progress.rs:250:19 clippy::if_not_else "unnecessary boolean `not` operation" -cargo-0.49.0/src/cargo/util/progress.rs:263:22 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -cargo-0.49.0/src/cargo/util/progress.rs:264:22 clippy::cast_possible_truncation "casting `f64` to `usize` may truncate the value" -cargo-0.49.0/src/cargo/util/progress.rs:264:22 clippy::cast_sign_loss "casting `f64` to `usize` may lose the sign of the value" -cargo-0.49.0/src/cargo/util/progress.rs:269:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/util/progress.rs:272:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/util/progress.rs:274:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/util/progress.rs:280:13 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/util/progress.rs:282:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -cargo-0.49.0/src/cargo/util/progress.rs:89:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/progress.rs:97:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/queue.rs:25:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/queue.rs:36:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/queue.rs:42:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/queue.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/queue.rs:69:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/read2.rs:11:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/read2.rs:31:17 clippy::similar_names "binding's name is too similar to existing binding" -cargo-0.49.0/src/cargo/util/restricted_names.rs:13:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/restricted_names.rs:26:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/restricted_names.rs:35:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/restricted_names.rs:45:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/restricted_names.rs:89:21 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/restricted_names.rs:8:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/rustc.rs:114:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -cargo-0.49.0/src/cargo/util/rustc.rs:115:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -cargo-0.49.0/src/cargo/util/rustc.rs:162:17 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/rustc.rs:39:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/sha256.rs:10:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/sha256.rs:16:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -cargo-0.49.0/src/cargo/util/sha256.rs:20:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/sha256.rs:31:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/sha256.rs:40:24 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -cargo-0.49.0/src/cargo/util/to_semver.rs:5:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1005:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1005:5 clippy::too_many_lines "this function has too many lines (282/100)" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1094:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1121:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1197:32 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -cargo-0.49.0/src/cargo/util/toml/mod.rs:124:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1504:9 clippy::unused_self "unused `self` argument" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1526:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1582:19 clippy::default_trait_access "calling `util::toml::DetailedTomlDependency::default()` is more clear than this expression" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1598:5 clippy::too_many_lines "this function has too many lines (153/100)" -cargo-0.49.0/src/cargo/util/toml/mod.rs:1687:33 clippy::unnecessary_lazy_evaluations "unnecessary closure used to substitute value for `Option::None`" -cargo-0.49.0/src/cargo/util/toml/mod.rs:178:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/toml/mod.rs:248:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/toml/mod.rs:274:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/toml/mod.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/toml/mod.rs:281:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/toml/mod.rs:285:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:294:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/toml/mod.rs:31:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:381:35 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value" -cargo-0.49.0/src/cargo/util/toml/mod.rs:381:35 clippy::cast_sign_loss "casting `i64` to `u32` may lose the sign of the value" -cargo-0.49.0/src/cargo/util/toml/mod.rs:388:35 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -cargo-0.49.0/src/cargo/util/toml/mod.rs:398:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/toml/mod.rs:450:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:536:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:783:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/toml/mod.rs:824:1 clippy::module_name_repetitions "item name starts with its containing module's name" -cargo-0.49.0/src/cargo/util/toml/mod.rs:834:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:83:42 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::too_many_lines "this function has too many lines (138/100)" -cargo-0.49.0/src/cargo/util/toml/mod.rs:962:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/toml/mod.rs:979:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/toml/mod.rs:98:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/toml/mod.rs:999:23 clippy::default_trait_access "calling `util::toml::DetailedTomlDependency::default()` is more clear than this expression" -cargo-0.49.0/src/cargo/util/toml/targets.rs:112:27 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/toml/targets.rs:325:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -cargo-0.49.0/src/cargo/util/toml/targets.rs:586:21 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/toml/targets.rs:593:42 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/toml/targets.rs:605:19 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/toml/targets.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/toml/targets.rs:756:36 clippy::redundant_closure_for_method_calls "redundant closure found" -cargo-0.49.0/src/cargo/util/vcs.rs:10:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -cargo-0.49.0/src/cargo/util/vcs.rs:33:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/vcs.rs:37:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/vcs.rs:43:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/vcs.rs:47:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/vcs.rs:59:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/vcs.rs:66:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/workspace.rs:52:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/workspace.rs:56:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/workspace.rs:60:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -cargo-0.49.0/src/cargo/util/workspace.rs:64:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/error.rs:24:1 clippy::module_name_repetitions "item name ends with its containing module's name" -iron-0.6.1/src/iron.rs:105:13 clippy::redundant_field_names "redundant field names in struct initialization" -iron-0.6.1/src/iron.rs:119:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/iron.rs:133:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/iron.rs:143:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/iron.rs:149:13 clippy::redundant_field_names "redundant field names in struct initialization" -iron-0.6.1/src/iron.rs:167:49 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/iron.rs:196:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -iron-0.6.1/src/iron.rs:80:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/iron.rs:85:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/iron.rs:90:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `iron` is missing `package.categories` metadata" -iron-0.6.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `iron` is missing `package.keywords` metadata" -iron-0.6.1/src/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `log`: 0.3.9, 0.4.8" -iron-0.6.1/src/middleware/mod.rs:137:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/middleware/mod.rs:150:1 clippy::module_name_repetitions "item name ends with its containing module's name" -iron-0.6.1/src/middleware/mod.rs:152:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/middleware/mod.rs:159:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/middleware/mod.rs:171:1 clippy::module_name_repetitions "item name ends with its containing module's name" -iron-0.6.1/src/middleware/mod.rs:173:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/middleware/mod.rs:182:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/middleware/mod.rs:192:1 clippy::module_name_repetitions "item name ends with its containing module's name" -iron-0.6.1/src/middleware/mod.rs:217:25 clippy::doc_markdown "you should put `ChainBuilder` between ticks in the documentation" -iron-0.6.1/src/middleware/mod.rs:264:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -iron-0.6.1/src/middleware/mod.rs:328:20 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/middleware/mod.rs:360:16 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/middleware/mod.rs:368:33 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/middleware/mod.rs:428:40 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/middleware/mod.rs:434:40 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/middleware/mod.rs:444:40 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/modifiers.rs:132:14 clippy::expect_fun_call "use of `expect` followed by a function call" -iron-0.6.1/src/request/mod.rs:113:24 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/request/mod.rs:121:13 clippy::redundant_field_names "redundant field names in struct initialization" -iron-0.6.1/src/request/mod.rs:123:13 clippy::redundant_field_names "redundant field names in struct initialization" -iron-0.6.1/src/request/mod.rs:124:13 clippy::redundant_field_names "redundant field names in struct initialization" -iron-0.6.1/src/request/mod.rs:126:13 clippy::redundant_field_names "redundant field names in struct initialization" -iron-0.6.1/src/request/mod.rs:128:13 clippy::redundant_field_names "redundant field names in struct initialization" -iron-0.6.1/src/request/mod.rs:153:69 clippy::doc_markdown "you should put `HttpReader` between ticks in the documentation" -iron-0.6.1/src/request/mod.rs:154:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/mod.rs:32:1 clippy::manual_non_exhaustive "this seems like a manual implementation of the non-exhaustive pattern" -iron-0.6.1/src/request/mod.rs:75:34 clippy::doc_markdown "you should put `HttpRequest` between ticks in the documentation" -iron-0.6.1/src/request/mod.rs:77:39 clippy::doc_markdown "you should put `HttpRequest` between ticks in the documentation" -iron-0.6.1/src/request/mod.rs:78:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/request/mod.rs:82:13 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/request/mod.rs:83:29 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/request/mod.rs:85:24 clippy::similar_names "binding's name is too similar to existing binding" -iron-0.6.1/src/request/url.rs:109:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:117:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:129:1 clippy::from_over_into "an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true" -iron-0.6.1/src/request/url.rs:21:14 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -iron-0.6.1/src/request/url.rs:22:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/request/url.rs:31:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/request/url.rs:47:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:52:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:57:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -iron-0.6.1/src/request/url.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:63:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -iron-0.6.1/src/request/url.rs:63:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:73:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -iron-0.6.1/src/request/url.rs:73:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/request/url.rs:96:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/response.rs:121:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -iron-0.6.1/src/response.rs:125:43 clippy::redundant_closure_for_method_calls "redundant closure found" -iron-0.6.1/src/response.rs:139:41 clippy::redundant_closure_for_method_calls "redundant closure found" -iron-0.6.1/src/response.rs:24:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -iron-0.6.1/src/response.rs:95:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -iron-0.6.1/src/response.rs:95:5 clippy::new_without_default "you should consider adding a `Default` implementation for `response::Response`" -libc-0.2.81/build.rs:114:19 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -libc-0.2.81/build.rs:124:5 clippy::question_mark "this block may be rewritten with the `?` operator" -libc-0.2.81/build.rs:133:5 clippy::question_mark "this block may be rewritten with the `?` operator" -libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:428:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:429:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:431:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:432:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:433:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:434:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:595:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:596:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:597:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:622:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:673:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:696:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:697:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:698:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:699:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:712:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:721:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:722:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:723:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:751:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:752:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:753:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:754:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:755:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:756:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:757:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:758:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:759:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:760:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:768:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:769:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:771:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:772:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:773:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:774:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:775:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:776:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:777:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:778:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:779:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:780:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:781:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:782:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:783:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:784:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:785:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:786:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:787:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:788:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:789:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:790:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:791:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:792:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:794:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:795:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:796:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:797:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:798:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:799:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:800:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:801:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:803:27 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:804:28 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:805:28 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:806:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:807:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:808:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:809:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:810:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:811:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:812:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:813:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:814:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:815:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:816:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:817:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:818:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:821:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:822:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:823:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:824:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:825:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:826:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:827:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:828:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:829:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:830:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:831:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:832:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:833:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:834:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:835:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:836:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:841:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:842:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:843:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:844:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:1120:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:178:34 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:291:5 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:291:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:299:11 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:302:5 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:312:11 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:352:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:355:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:355:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:359:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:359:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:363:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:363:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:367:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:367:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:371:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:371:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:534:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:645:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:727:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:728:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:729:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:731:44 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:732:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:733:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:734:43 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:735:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:736:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:737:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:738:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:741:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:742:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:743:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:744:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:745:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:746:43 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:747:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:748:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:749:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:750:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:751:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:752:43 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:753:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:755:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:756:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:757:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:758:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:759:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:761:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:762:44 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:763:45 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:764:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:765:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:766:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:767:44 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:768:44 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:769:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:770:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:771:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:772:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:773:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:774:45 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:775:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:776:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:803:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:841:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:842:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:982:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:984:46 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1209:36 clippy::cast_possible_truncation "casting `i32` to `i16` may truncate the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1210:36 clippy::cast_possible_truncation "casting `i32` to `i16` may truncate the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1235:39 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1236:41 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1274:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1324:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1333:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1334:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1346:34 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1346:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1346:34 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1347:37 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1347:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1347:37 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1348:36 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1348:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1348:36 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1349:37 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1349:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1349:37 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1350:35 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1350:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1350:35 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1351:36 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1351:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1351:36 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1352:31 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1352:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1352:31 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1419:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1420:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1421:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1422:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1423:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1490:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1561:46 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1562:45 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1567:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1568:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1586:26 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1587:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1588:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1589:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1897:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1898:51 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1900:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1969:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1970:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1971:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1972:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1973:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1974:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1975:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1976:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1977:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1978:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1979:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1980:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1981:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1982:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1983:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1984:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1985:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1986:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1987:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1988:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1989:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1990:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1991:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1992:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1993:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1994:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1995:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1996:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1997:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1998:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:1999:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2000:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2001:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2002:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2003:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2004:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2005:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2032:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2033:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2034:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2035:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2036:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2037:28 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2038:27 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2039:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2041:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2042:28 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2043:27 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2044:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2045:27 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2046:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2048:28 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2049:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2050:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2051:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2052:26 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2053:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2318:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2321:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2331:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2487:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2488:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2489:43 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2490:43 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2491:43 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2493:47 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2494:44 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2495:46 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2496:47 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2497:49 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2498:48 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2499:50 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2500:45 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2572:9 clippy::needless_return "unneeded `return` statement" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2578:20 clippy::zero_ptr "`0 as *mut _` detected" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2588:13 clippy::zero_ptr "`0 as *mut _` detected" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2590:13 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2596:52 clippy::used_underscore_binding "used binding `_dummy` which is prefixed with an underscore. A leading underscore signals that a binding will not be used" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2597:11 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2601:21 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2611:9 clippy::unused_unit "unneeded unit expression" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2619:9 clippy::unused_unit "unneeded unit expression" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2634:9 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2647:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2648:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2649:9 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2654:18 clippy::identity_op "the operation is ineffective. Consider reducing it to `(dev & 0x00000000000000ff)`" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2654:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2655:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2656:9 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2660:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2661:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2663:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2664:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2665:16 clippy::identity_op "the operation is ineffective. Consider reducing it to `(minor & 0x000000ff)`" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2665:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:2666:25 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/linux/mod.rs:954:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1000:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1001:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1002:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1016:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1017:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1018:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1019:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1020:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1029:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1030:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1031:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1032:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1033:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1034:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1035:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1041:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1042:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1043:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1044:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1045:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1046:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1047:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1048:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1049:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1050:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1051:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1053:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1054:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1055:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1056:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1057:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1058:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1059:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1060:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1073:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1074:43 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1075:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1076:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1077:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1078:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1079:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1080:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1081:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1082:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1083:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1084:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1086:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1087:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1089:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1090:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1091:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1094:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1095:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1096:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1097:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1098:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1099:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1100:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1101:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1102:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1105:44 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1106:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1107:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1108:42 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1109:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1110:46 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1111:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1112:44 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1113:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1114:47 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1115:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1126:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1127:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1128:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1179:32 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1180:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:1218:27 clippy::identity_op "the operation is ineffective. Consider reducing it to `IPOPT_CONTROL`" -libc-0.2.81/src/unix/linux_like/mod.rs:1314:9 clippy::precedence "operator precedence can trip the unwary" -libc-0.2.81/src/unix/linux_like/mod.rs:1321:13 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" -libc-0.2.81/src/unix/linux_like/mod.rs:1323:13 clippy::zero_ptr "`0 as *mut _` detected" -libc-0.2.81/src/unix/linux_like/mod.rs:1332:9 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -libc-0.2.81/src/unix/linux_like/mod.rs:1337:9 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -libc-0.2.81/src/unix/linux_like/mod.rs:1341:18 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" -libc-0.2.81/src/unix/linux_like/mod.rs:1344:9 clippy::needless_return "unneeded `return` statement" -libc-0.2.81/src/unix/linux_like/mod.rs:1348:18 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" -libc-0.2.81/src/unix/linux_like/mod.rs:1350:9 clippy::needless_return "unneeded `return` statement" -libc-0.2.81/src/unix/linux_like/mod.rs:1354:18 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" -libc-0.2.81/src/unix/linux_like/mod.rs:1357:9 clippy::needless_return "unneeded `return` statement" -libc-0.2.81/src/unix/linux_like/mod.rs:1361:21 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" -libc-0.2.81/src/unix/linux_like/mod.rs:1381:9 clippy::cast_possible_truncation "casting `i32` to `i8` may truncate the value" -libc-0.2.81/src/unix/linux_like/mod.rs:1389:9 clippy::verbose_bit_mask "bit mask could be simplified with a call to `trailing_zeros`" -libc-0.2.81/src/unix/linux_like/mod.rs:446:31 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:591:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:592:38 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:593:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:594:33 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:595:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:596:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:597:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:598:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:599:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:600:34 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:601:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:602:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:607:37 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:608:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:764:35 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:765:39 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/linux_like/mod.rs:991:30 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/mod.rs:198:29 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/mod.rs:199:28 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/mod.rs:201:35 clippy::unnecessary_cast "casting integer literal to `usize` is unnecessary" -libc-0.2.81/src/unix/mod.rs:202:35 clippy::unnecessary_cast "casting integer literal to `usize` is unnecessary" -libc-0.2.81/src/unix/mod.rs:282:40 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/mod.rs:284:41 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/mod.rs:285:36 clippy::unreadable_literal "long literal lacking separators" -libc-0.2.81/src/unix/mod.rs:34:10 clippy::upper_case_acronyms "name `DIR` contains a capitalized acronym" -libc-0.2.81/src/unix/mod.rs:386:10 clippy::upper_case_acronyms "name `FILE` contains a capitalized acronym" -log-0.4.11/src/lib.rs:1047:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:1053:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:1059:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:1093:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:1093:5 clippy::new_without_default "you should consider adding a `Default` implementation for `MetadataBuilder<'a>`" -log-0.4.11/src/lib.rs:1118:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:1177:1 clippy::inline_always "you have declared `#[inline(always)]` on `max_level`. This is usually a bad idea" -log-0.4.11/src/lib.rs:1178:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:1306:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -log-0.4.11/src/lib.rs:1358:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:1359:5 clippy::if_not_else "unnecessary `!=` operation" -log-0.4.11/src/lib.rs:1407:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:356:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" -log-0.4.11/src/lib.rs:448:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -log-0.4.11/src/lib.rs:500:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:506:28 clippy::trivially_copy_pass_by_ref "this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -log-0.4.11/src/lib.rs:506:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -log-0.4.11/src/lib.rs:506:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:538:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" -log-0.4.11/src/lib.rs:653:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:661:21 clippy::trivially_copy_pass_by_ref "this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -log-0.4.11/src/lib.rs:661:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:677:44 clippy::match_same_arms "this `match` has identical arm bodies" -log-0.4.11/src/lib.rs:758:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:764:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:770:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:776:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:782:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:788:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:794:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:803:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:809:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:818:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:908:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -log-0.4.11/src/lib.rs:908:5 clippy::new_without_default "you should consider adding a `Default` implementation for `RecordBuilder<'a>`" -log-0.4.11/src/lib.rs:995:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/detection.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -proc-macro2-1.0.24/src/fallback.rs:108:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -proc-macro2-1.0.24/src/fallback.rs:269:20 clippy::unused_self "unused `self` argument" -proc-macro2-1.0.24/src/fallback.rs:430:24 clippy::trivially_copy_pass_by_ref "this argument (0 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/fallback.rs:437:23 clippy::trivially_copy_pass_by_ref "this argument (0 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/fallback.rs:437:23 clippy::unused_self "unused `self` argument" -proc-macro2-1.0.24/src/fallback.rs:471:17 clippy::trivially_copy_pass_by_ref "this argument (0 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/fallback.rs:471:17 clippy::unused_self "unused `self` argument" -proc-macro2-1.0.24/src/fallback.rs:654:5 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -proc-macro2-1.0.24/src/fallback.rs:655:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -proc-macro2-1.0.24/src/fallback.rs:661:5 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -proc-macro2-1.0.24/src/fallback.rs:662:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -proc-macro2-1.0.24/src/fallback.rs:664:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -proc-macro2-1.0.24/src/fallback.rs:674:37 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -proc-macro2-1.0.24/src/fallback.rs:678:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -proc-macro2-1.0.24/src/fallback.rs:85:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -proc-macro2-1.0.24/src/fallback.rs:882:43 clippy::unused_self "unused `self` argument" -proc-macro2-1.0.24/src/lib.rs:1017:9 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1081:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1099:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1117:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1135:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1141:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1146:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:1156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:152:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:373:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:383:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:397:24 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/lib.rs:397:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:403:23 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/lib.rs:403:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:418:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:425:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:464:17 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/lib.rs:500:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:626:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:633:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:641:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:652:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:662:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:672:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:734:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:743:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:752:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:757:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:788:19 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" -proc-macro2-1.0.24/src/lib.rs:788:69 clippy::doc_markdown "you should put `XID_Continue` between ticks in the documentation" -proc-macro2-1.0.24/src/lib.rs:891:36 clippy::doc_markdown "you should put `syn::parse_str` between ticks in the documentation" -proc-macro2-1.0.24/src/lib.rs:894:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:911:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/lib.rs:996:9 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -proc-macro2-1.0.24/src/parse.rs:552:5 clippy::while_let_on_iterator "this loop could be written as a `for` loop" -proc-macro2-1.0.24/src/parse.rs:584:21 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" -proc-macro2-1.0.24/src/parse.rs:602:20 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -proc-macro2-1.0.24/src/parse.rs:696:29 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" -proc-macro2-1.0.24/src/parse.rs:702:34 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" -proc-macro2-1.0.24/src/parse.rs:708:34 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" -proc-macro2-1.0.24/src/parse.rs:793:5 clippy::vec_init_then_push "calls to `push` immediately after creation" -proc-macro2-1.0.24/src/parse.rs:803:15 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" -proc-macro2-1.0.24/src/parse.rs:808:15 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" -proc-macro2-1.0.24/src/wrapper.rs:415:24 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/wrapper.rs:429:23 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -proc-macro2-1.0.24/src/wrapper.rs:492:17 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:158:15 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:175:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin-imgui/src/ui.rs:183:5 clippy::too_many_lines "this function has too many lines (115/100)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -puffin-02dd4a3/puffin-imgui/src/ui.rs:207:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -puffin-02dd4a3/puffin-imgui/src/ui.rs:271:67 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -puffin-02dd4a3/puffin-imgui/src/ui.rs:376:29 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:381:44 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:453:9 clippy::similar_names "binding's name is too similar to existing binding" -puffin-02dd4a3/puffin-imgui/src/ui.rs:540:14 clippy::cast_possible_truncation "casting `f64` to `f32` may truncate the value" -puffin-02dd4a3/puffin-imgui/src/ui.rs:551:5 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:584:39 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:59:26 clippy::unsafe_derive_deserialize "you are deriving `serde::Deserialize` on a type that has methods using `unsafe`" -puffin-02dd4a3/puffin-imgui/src/ui.rs:61:1 clippy::module_name_repetitions "item name ends with its containing module's name" -puffin-02dd4a3/puffin-imgui/src/ui.rs:627:39 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:674:47 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -puffin-02dd4a3/puffin-imgui/src/ui.rs:690:9 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" -puffin-02dd4a3/puffin/src/data.rs:102:25 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -puffin-02dd4a3/puffin/src/data.rs:112:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/data.rs:116:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -puffin-02dd4a3/puffin/src/data.rs:137:24 clippy::match_same_arms "this `match` has identical arm bodies" -puffin-02dd4a3/puffin/src/data.rs:177:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -puffin-02dd4a3/puffin/src/data.rs:211:21 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -puffin-02dd4a3/puffin/src/data.rs:24:5 clippy::wildcard_imports "usage of wildcard import" -puffin-02dd4a3/puffin/src/lib.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:147:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -puffin-02dd4a3/puffin/src/lib.rs:147:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -puffin-02dd4a3/puffin/src/lib.rs:165:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -puffin-02dd4a3/puffin/src/lib.rs:200:21 clippy::default_trait_access "calling `Stream::default()` is more clear than this expression" -puffin-02dd4a3/puffin/src/lib.rs:257:78 clippy::default_trait_access "calling `std::cell::RefCell::default()` is more clear than this expression" -puffin-02dd4a3/puffin/src/lib.rs:297:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:308:28 clippy::default_trait_access "calling `FullProfileData::default()` is more clear than this expression" -puffin-02dd4a3/puffin/src/lib.rs:316:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:321:5 clippy::cast_possible_truncation "casting `u128` to `i64` may truncate the value" -puffin-02dd4a3/puffin/src/lib.rs:348:28 clippy::default_trait_access "calling `std::marker::PhantomData::default()` is more clear than this expression" -puffin-02dd4a3/puffin/src/lib.rs:359:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:375:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:376:5 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -puffin-02dd4a3/puffin/src/lib.rs:377:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -puffin-02dd4a3/puffin/src/lib.rs:406:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:408:5 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -puffin-02dd4a3/puffin/src/lib.rs:69:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:73:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/lib.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/merge.rs:21:1 clippy::module_name_repetitions "item name starts with its containing module's name" -puffin-02dd4a3/puffin/src/merge.rs:28:1 clippy::module_name_repetitions "item name starts with its containing module's name" -puffin-02dd4a3/puffin/src/merge.rs:28:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -puffin-02dd4a3/puffin/src/merge.rs:35:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -puffin-02dd4a3/puffin/src/merge.rs:35:1 clippy::module_name_repetitions "item name starts with its containing module's name" -puffin-02dd4a3/puffin/src/merge.rs:64:43 clippy::default_trait_access "calling `std::vec::Vec::default()` is more clear than this expression" -puffin-02dd4a3/puffin/src/merge.rs:65:54 clippy::default_trait_access "calling `std::collections::HashMap::default()` is more clear than this expression" -puffin-02dd4a3/puffin/src/merge.rs:9:1 clippy::module_name_repetitions "item name starts with its containing module's name" -quote-1.0.7/src/ext.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" -quote-1.0.7/src/ext.rs:7:5 clippy::doc_markdown "you should put `TokenStream` between ticks in the documentation" -quote-1.0.7/src/ident_fragment.rs:13:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -quote-1.0.7/src/ident_fragment.rs:51:31 clippy::manual_strip "stripping a prefix manually" -quote-1.0.7/src/runtime.rs:52:5 clippy::module_name_repetitions "item name ends with its containing module's name" -quote-1.0.7/src/runtime.rs:63:5 clippy::module_name_repetitions "item name ends with its containing module's name" -quote-1.0.7/src/runtime.rs:66:33 clippy::doc_markdown "you should put `DoesNotHaveIter` between ticks in the documentation" -quote-1.0.7/src/runtime.rs:80:5 clippy::module_name_repetitions "item name ends with its containing module's name" -rand-0.7.3/src/distributions/bernoulli.rs:103:20 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" -rand-0.7.3/src/distributions/bernoulli.rs:103:20 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" -rand-0.7.3/src/distributions/bernoulli.rs:116:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/distributions/bernoulli.rs:123:21 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" -rand-0.7.3/src/distributions/bernoulli.rs:123:21 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" -rand-0.7.3/src/distributions/bernoulli.rs:63:26 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/bernoulli.rs:63:27 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -rand-0.7.3/src/distributions/bernoulli.rs:67:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/distributions/bernoulli.rs:95:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/distributions/bernoulli.rs:96:13 clippy::manual_range_contains "manual `Range::contains` implementation" -rand-0.7.3/src/distributions/binomial.rs:107:23 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:112:44 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:116:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rand-0.7.3/src/distributions/binomial.rs:150:28 clippy::redundant_else "redundant else block" -rand-0.7.3/src/distributions/binomial.rs:153:24 clippy::if_not_else "unnecessary boolean `not` operation" -rand-0.7.3/src/distributions/binomial.rs:158:28 clippy::redundant_else "redundant else block" -rand-0.7.3/src/distributions/binomial.rs:164:33 clippy::cast_sign_loss "casting `i64` to `u64` may lose the sign of the value" -rand-0.7.3/src/distributions/binomial.rs:166:28 clippy::redundant_else "redundant else block" -rand-0.7.3/src/distributions/binomial.rs:175:47 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:185:38 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:194:38 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:202:28 clippy::redundant_else "redundant else block" -rand-0.7.3/src/distributions/binomial.rs:209:25 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:221:26 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:222:26 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:223:25 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:224:25 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:226:17 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rand-0.7.3/src/distributions/binomial.rs:233:32 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:234:27 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:251:22 clippy::cast_sign_loss "casting `i64` to `u64` may lose the sign of the value" -rand-0.7.3/src/distributions/binomial.rs:255:9 clippy::if_not_else "unnecessary `!=` operation" -rand-0.7.3/src/distributions/binomial.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/binomial.rs:45:17 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:46:5 clippy::cast_possible_truncation "casting `f64` to `i64` may truncate the value" -rand-0.7.3/src/distributions/binomial.rs:50:5 clippy::too_many_lines "this function has too many lines (143/100)" -rand-0.7.3/src/distributions/binomial.rs:76:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rand-0.7.3/src/distributions/binomial.rs:78:12 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:81:21 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:82:32 clippy::cast_possible_truncation "casting `u64` to `i32` may truncate the value" -rand-0.7.3/src/distributions/binomial.rs:88:26 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/binomial.rs:99:21 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/distributions/cauchy.rs:33:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/dirichlet.rs:52:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/dirichlet.rs:64:32 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" -rand-0.7.3/src/distributions/dirichlet.rs:65:23 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" -rand-0.7.3/src/distributions/exponential.rs:76:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/float.rs:73:1 clippy::module_name_repetitions "item name ends with its containing module's name" -rand-0.7.3/src/distributions/gamma.rs:13:5 clippy::enum_glob_use "usage of wildcard import for enum variants" -rand-0.7.3/src/distributions/gamma.rs:14:5 clippy::enum_glob_use "usage of wildcard import for enum variants" -rand-0.7.3/src/distributions/gamma.rs:189:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/gamma.rs:230:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/gamma.rs:259:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/gamma.rs:287:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/gamma.rs:90:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/integer.rs:23:9 clippy::cast_possible_truncation "casting `u32` to `u8` may truncate the value" -rand-0.7.3/src/distributions/integer.rs:30:9 clippy::cast_possible_truncation "casting `u32` to `u16` may truncate the value" -rand-0.7.3/src/distributions/integer.rs:69:9 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -rand-0.7.3/src/distributions/mod.rs:263:5 clippy::inline_always "you have declared `#[inline(always)]` on `next`. This is usually a bad idea" -rand-0.7.3/src/distributions/normal.rs:100:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/normal.rs:119:1 clippy::module_name_repetitions "item name ends with its containing module's name" -rand-0.7.3/src/distributions/normal.rs:131:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/normal.rs:31:1 clippy::module_name_repetitions "item name ends with its containing module's name" -rand-0.7.3/src/distributions/normal.rs:47:25 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" -rand-0.7.3/src/distributions/normal.rs:48:25 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" -rand-0.7.3/src/distributions/other.rs:89:9 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -rand-0.7.3/src/distributions/pareto.rs:32:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/poisson.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/poisson.rs:87:30 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" -rand-0.7.3/src/distributions/poisson.rs:87:30 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" -rand-0.7.3/src/distributions/triangular.rs:32:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/uniform.rs:146:4 clippy::needless_doctest_main "needless `fn main` in doctest" -rand-0.7.3/src/distributions/uniform.rs:199:1 clippy::module_name_repetitions "item name ends with its containing module's name" -rand-0.7.3/src/distributions/uniform.rs:214:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/distributions/uniform.rs:283:14 clippy::doc_markdown "you should put `SampleUniform` between ticks in the documentation" -rand-0.7.3/src/distributions/uniform.rs:283:46 clippy::doc_markdown "you should put `SampleUniform` between ticks in the documentation" -rand-0.7.3/src/distributions/uniform.rs:296:5 clippy::inline_always "you have declared `#[inline(always)]` on `borrow`. This is usually a bad idea" -rand-0.7.3/src/distributions/uniform.rs:304:5 clippy::inline_always "you have declared `#[inline(always)]` on `borrow`. This is usually a bad idea" -rand-0.7.3/src/distributions/uniform.rs:350:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" -rand-0.7.3/src/distributions/uniform.rs:56:10 clippy::doc_markdown "you should put `SampleBorrow` between ticks in the documentation" -rand-0.7.3/src/distributions/uniform.rs:647:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/distributions/uniform.rs:840:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/distributions/uniform.rs:913:13 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" -rand-0.7.3/src/distributions/uniform.rs:943:54 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -rand-0.7.3/src/distributions/unit_circle.rs:30:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/unit_sphere.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/distributions/unit_sphere.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/utils.rs:247:15 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" -rand-0.7.3/src/distributions/utils.rs:248:20 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" -rand-0.7.3/src/distributions/utils.rs:249:18 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" -rand-0.7.3/src/distributions/utils.rs:254:5 clippy::inline_always "you have declared `#[inline(always)]` on `lanes`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:258:5 clippy::inline_always "you have declared `#[inline(always)]` on `splat`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:262:5 clippy::inline_always "you have declared `#[inline(always)]` on `extract`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:267:5 clippy::inline_always "you have declared `#[inline(always)]` on `replace`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:281:5 clippy::inline_always "you have declared `#[inline(always)]` on `any`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:286:5 clippy::inline_always "you have declared `#[inline(always)]` on `all`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:291:5 clippy::inline_always "you have declared `#[inline(always)]` on `none`. This is usually a bad idea" -rand-0.7.3/src/distributions/utils.rs:488:17 clippy::doc_markdown "you should put `x_i` between ticks in the documentation" -rand-0.7.3/src/distributions/utils.rs:489:50 clippy::doc_markdown "you should put `x_i` between ticks in the documentation" -rand-0.7.3/src/distributions/utils.rs:489:63 clippy::doc_markdown "you should put `f(x_i` between ticks in the documentation" -rand-0.7.3/src/distributions/utils.rs:490:40 clippy::doc_markdown "you should put `f(x_i` between ticks in the documentation" -rand-0.7.3/src/distributions/utils.rs:490:49 clippy::doc_markdown "you should put `f(x_{i+1` between ticks in the documentation" -rand-0.7.3/src/distributions/utils.rs:518:17 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -rand-0.7.3/src/distributions/weibull.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/distributions/weighted/alias_method.rs:113:21 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" -rand-0.7.3/src/distributions/weighted/alias_method.rs:125:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rand-0.7.3/src/distributions/weighted/alias_method.rs:131:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rand-0.7.3/src/distributions/weighted/alias_method.rs:180:36 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -rand-0.7.3/src/distributions/weighted/alias_method.rs:182:34 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -rand-0.7.3/src/distributions/weighted/alias_method.rs:259:28 clippy::clone_on_copy "using `clone` on type `distributions::uniform::Uniform` which implements the `Copy` trait" -rand-0.7.3/src/distributions/weighted/alias_method.rs:296:9 clippy::map_clone "you are using an explicit closure for copying elements" -rand-0.7.3/src/distributions/weighted/alias_method.rs:321:9 clippy::map_clone "you are using an explicit closure for copying elements" -rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::too_many_lines "this function has too many lines (106/100)" -rand-0.7.3/src/distributions/weighted/alias_method.rs:85:17 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -rand-0.7.3/src/distributions/weighted/alias_method.rs:87:31 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -rand-0.7.3/src/distributions/weighted/mod.rs:100:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/distributions/weighted/mod.rs:144:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/distributions/weighted/mod.rs:144:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -rand-0.7.3/src/distributions/weighted/mod.rs:169:16 clippy::int_plus_one "unnecessary `>= y + 1` or `x - 1 >=`" -rand-0.7.3/src/distributions/weighted/mod.rs:386:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/distributions/weighted/mod.rs:85:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/lib.rs:333:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/lib.rs:404:14 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" -rand-0.7.3/src/lib.rs:552:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -rand-0.7.3/src/rngs/adapter/read.rs:47:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/rngs/adapter/read.rs:89:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/rngs/adapter/reseeding.rs:100:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/rngs/adapter/reseeding.rs:112:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" -rand-0.7.3/src/rngs/adapter/reseeding.rs:117:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" -rand-0.7.3/src/rngs/adapter/reseeding.rs:198:13 clippy::cast_possible_wrap "casting `u64` to `i64` may wrap around the value" -rand-0.7.3/src/rngs/adapter/reseeding.rs:231:9 clippy::cast_possible_wrap "casting `usize` to `isize` may wrap around the value" -rand-0.7.3/src/rngs/adapter/reseeding.rs:249:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -rand-0.7.3/src/rngs/adapter/reseeding.rs:27:28 clippy::doc_markdown "you should put `ChaCha` between ticks in the documentation" -rand-0.7.3/src/rngs/adapter/reseeding.rs:79:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/rngs/entropy.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/rngs/entropy.rs:34:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/rngs/mock.rs:36:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/rngs/mock.rs:47:9 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -rand-0.7.3/src/rngs/mod.rs:61:74 clippy::doc_markdown "you should put `ChaCha20` between ticks in the documentation" -rand-0.7.3/src/rngs/std.rs:25:39 clippy::doc_markdown "you should put `ChaCha` between ticks in the documentation" -rand-0.7.3/src/rngs/std.rs:32:10 clippy::doc_markdown "you should put `rand_chacha` between ticks in the documentation" -rand-0.7.3/src/rngs/std.rs:36:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/rngs/std.rs:39:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" -rand-0.7.3/src/rngs/std.rs:44:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" -rand-0.7.3/src/rngs/std.rs:49:5 clippy::inline_always "you have declared `#[inline(always)]` on `fill_bytes`. This is usually a bad idea" -rand-0.7.3/src/rngs/std.rs:54:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" -rand-0.7.3/src/rngs/std.rs:63:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea" -rand-0.7.3/src/rngs/std.rs:68:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea" -rand-0.7.3/src/rngs/thread.rs:57:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/rngs/thread.rs:80:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -rand-0.7.3/src/rngs/thread.rs:80:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/rngs/thread.rs:80:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -rand-0.7.3/src/rngs/thread.rs:81:35 clippy::redundant_closure_for_method_calls "redundant closure found" -rand-0.7.3/src/rngs/thread.rs:93:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" -rand-0.7.3/src/rngs/thread.rs:98:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" -rand-0.7.3/src/seq/index.rs:127:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/seq/index.rs:139:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -rand-0.7.3/src/seq/index.rs:159:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/seq/index.rs:171:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -rand-0.7.3/src/seq/index.rs:180:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -rand-0.7.3/src/seq/index.rs:223:18 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -rand-0.7.3/src/seq/index.rs:224:18 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -rand-0.7.3/src/seq/index.rs:233:25 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" -rand-0.7.3/src/seq/index.rs:236:27 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" -rand-0.7.3/src/seq/index.rs:244:12 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" -rand-0.7.3/src/seq/index.rs:244:37 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" -rand-0.7.3/src/seq/index.rs:29:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand-0.7.3/src/seq/index.rs:39:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/seq/index.rs:48:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/seq/index.rs:60:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/seq/index.rs:69:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/seq/index.rs:78:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/seq/index.rs:87:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand-0.7.3/src/seq/index.rs:87:5 clippy::should_implement_trait "method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`" -rand-0.7.3/src/seq/index.rs:97:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -rand-0.7.3/src/seq/mod.rs:141:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/seq/mod.rs:168:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand-0.7.3/src/seq/mod.rs:229:4 clippy::needless_doctest_main "needless `fn main` in doctest" -rand-0.7.3/src/seq/mod.rs:292:29 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -rand-0.7.3/src/seq/mod.rs:410:23 clippy::default_trait_access "calling `std::marker::PhantomData::default()` is more clear than this expression" -rand-0.7.3/src/seq/mod.rs:45:4 clippy::needless_doctest_main "needless `fn main` in doctest" -rand-0.7.3/src/seq/mod.rs:527:26 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -rand_core-0.6.0/src/block.rs:117:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand_core-0.6.0/src/block.rs:153:5 clippy::inline_always "you have declared `#[inline(always)]` on `index`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:230:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:240:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:245:5 clippy::inline_always "you have declared `#[inline(always)]` on `seed_from_u64`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:250:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:280:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand_core-0.6.0/src/block.rs:319:5 clippy::inline_always "you have declared `#[inline(always)]` on `index`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:405:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:415:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:420:5 clippy::inline_always "you have declared `#[inline(always)]` on `seed_from_u64`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:425:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea" -rand_core-0.6.0/src/block.rs:67:14 clippy::doc_markdown "you should put `module][crate::block` between ticks in the documentation" -rand_core-0.6.0/src/block.rs:68:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rand_core-0.6.0/src/error.rs:106:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand_core-0.6.0/src/error.rs:87:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand_core-0.6.0/src/error.rs:95:74 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -rand_core-0.6.0/src/lib.rs:179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand_core-0.6.0/src/lib.rs:301:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rand_core-0.6.0/src/lib.rs:303:26 clippy::unreadable_literal "long literal lacking separators" -rand_core-0.6.0/src/lib.rs:304:26 clippy::unreadable_literal "long literal lacking separators" -rand_core-0.6.0/src/lib.rs:313:30 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -rand_core-0.6.0/src/lib.rs:314:23 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -rand_core-0.6.0/src/lib.rs:346:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -rand_core-0.6.0/src/lib.rs:381:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" -rand_core-0.6.0/src/lib.rs:386:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" -rand_core-0.6.0/src/lib.rs:391:5 clippy::inline_always "you have declared `#[inline(always)]` on `fill_bytes`. This is usually a bad idea" -rand_core-0.6.0/src/lib.rs:396:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" -rayon-1.5.0/src/collections/binary_heap.rs:7:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/binary_heap.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/btree_map.rs:7:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/btree_map.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/btree_set.rs:7:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/btree_set.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/hash_map.rs:10:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/hash_map.rs:9:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/hash_set.rs:10:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/hash_set.rs:9:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/linked_list.rs:7:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/linked_list.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/mod.rs:59:32 clippy::mem_replace_with_default "replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`" -rayon-1.5.0/src/collections/vec_deque.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/collections/vec_deque.rs:9:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/compile_fail/cannot_collect_filtermap_data.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" -rayon-1.5.0/src/compile_fail/cannot_zip_filtered_data.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" -rayon-1.5.0/src/compile_fail/cell_par_iter.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" -rayon-1.5.0/src/compile_fail/no_send_par_iter.rs:25:1 clippy::needless_doctest_main "needless `fn main` in doctest" -rayon-1.5.0/src/compile_fail/no_send_par_iter.rs:46:1 clippy::needless_doctest_main "needless `fn main` in doctest" -rayon-1.5.0/src/compile_fail/no_send_par_iter.rs:4:1 clippy::needless_doctest_main "needless `fn main` in doctest" -rayon-1.5.0/src/compile_fail/rc_par_iter.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" -rayon-1.5.0/src/iter/chain.rs:103:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/chain.rs:122:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/chain.rs:128:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/chain.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/chain.rs:221:36 clippy::doc_markdown "you should put `ExactSizeIterator` between ticks in the documentation" -rayon-1.5.0/src/iter/chain.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/chain.rs:51:38 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" -rayon-1.5.0/src/iter/chain.rs:58:14 clippy::shadow_unrelated "`a` is being shadowed" -rayon-1.5.0/src/iter/chain.rs:58:17 clippy::shadow_unrelated "`b` is being shadowed" -rayon-1.5.0/src/iter/chain.rs:78:14 clippy::shadow_unrelated "`a` is being shadowed" -rayon-1.5.0/src/iter/chain.rs:78:17 clippy::shadow_unrelated "`b` is being shadowed" -rayon-1.5.0/src/iter/chain.rs:97:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/chunks.rs:29:9 clippy::inconsistent_struct_constructor "inconsistent struct constructor" -rayon-1.5.0/src/iter/chunks.rs:3:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/chunks.rs:4:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/chunks.rs:77:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/chunks.rs:83:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/cloned.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/cloned.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/cloned.rs:71:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/cloned.rs:75:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/collect/consumer.rs:141:5 clippy::doc_markdown "you should put `CollectReducer` between ticks in the documentation" -rayon-1.5.0/src/iter/collect/consumer.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/collect/consumer.rs:28:5 clippy::doc_markdown "you should put `CollectResult` between ticks in the documentation" -rayon-1.5.0/src/iter/collect/consumer.rs:36:37 clippy::mut_mut "generally you want to avoid `&mut &mut _` if possible" -rayon-1.5.0/src/iter/collect/consumer.rs:36:37 clippy::mut_mut "generally you want to avoid `&mut &mut _` if possible" -rayon-1.5.0/src/iter/collect/mod.rs:154:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -rayon-1.5.0/src/iter/copied.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/copied.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/copied.rs:71:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/copied.rs:75:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/empty.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/empty.rs:24:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -rayon-1.5.0/src/iter/empty.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/enumerate.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/enumerate.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/enumerate.rs:64:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/enumerate.rs:68:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/extend.rs:143:63 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:182:57 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:218:32 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:218:59 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:25:42 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:287:62 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:322:56 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:41:27 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:47:30 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:47:56 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:47:74 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:53:29 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:57:36 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/extend.rs:59:61 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" -rayon-1.5.0/src/iter/filter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/filter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/filter_map.rs:123:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -rayon-1.5.0/src/iter/filter_map.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/filter_map.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/find.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/find.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/find_first_last/mod.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/find_first_last/mod.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/find_first_last/mod.rs:32:67 clippy::doc_markdown "you should put `MatchPosition` between ticks in the documentation" -rayon-1.5.0/src/iter/flat_map.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/flat_map.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/flat_map_iter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/flat_map_iter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/flatten.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/flatten.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/flatten_iter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/flatten_iter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/fold.rs:158:13 clippy::similar_names "binding's name is too similar to existing binding" -rayon-1.5.0/src/iter/fold.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/fold.rs:204:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rayon-1.5.0/src/iter/fold.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/for_each.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/for_each.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/inspect.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/inspect.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/inspect.rs:83:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/inspect.rs:88:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/interleave.rs:111:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/interleave.rs:119:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/interleave.rs:195:30 clippy::doc_markdown "you should put `self.i_len` between ticks in the documentation" -rayon-1.5.0/src/iter/interleave.rs:195:43 clippy::doc_markdown "you should put `self.j_len` between ticks in the documentation" -rayon-1.5.0/src/iter/interleave.rs:199:23 clippy::doc_markdown "you should put `self.i_len` between ticks in the documentation" -rayon-1.5.0/src/iter/interleave.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/interleave.rs:200:23 clippy::doc_markdown "you should put `self.j_len` between ticks in the documentation" -rayon-1.5.0/src/iter/interleave.rs:249:41 clippy::doc_markdown "you should put `DoubleEndedIterator` between ticks in the documentation" -rayon-1.5.0/src/iter/interleave.rs:250:5 clippy::doc_markdown "you should put `ExactSizeIterator` between ticks in the documentation" -rayon-1.5.0/src/iter/interleave.rs:263:33 clippy::doc_markdown "you should put `InterleaveSeq` between ticks in the documentation" -rayon-1.5.0/src/iter/interleave.rs:280:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -rayon-1.5.0/src/iter/interleave.rs:285:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -rayon-1.5.0/src/iter/interleave.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/interleave.rs:313:9 clippy::comparison_chain "`if` chain can be rewritten with `match`" -rayon-1.5.0/src/iter/interleave.rs:82:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/interleave.rs:90:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/interleave_shortest.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/intersperse.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/intersperse.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/intersperse.rs:90:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/intersperse.rs:96:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/len.rs:12:1 clippy::module_name_repetitions "item name ends with its containing module's name" -rayon-1.5.0/src/iter/len.rs:146:1 clippy::module_name_repetitions "item name ends with its containing module's name" -rayon-1.5.0/src/iter/len.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/len.rs:200:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/len.rs:205:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/len.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/len.rs:66:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/len.rs:71:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/map.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/map.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/map.rs:84:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/map.rs:89:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/map_with.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/map_with.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/map_with.rs:419:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/map_with.rs:425:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/map_with.rs:90:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/map_with.rs:96:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/mod.rs:1874:24 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -rayon-1.5.0/src/iter/mod.rs:2171:1 clippy::len_without_is_empty "trait `IndexedParallelIterator` has a `len` method but no (possibly inherited) `is_empty` method" -rayon-1.5.0/src/iter/mod.rs:2371:26 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -rayon-1.5.0/src/iter/mod.rs:2411:26 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -rayon-1.5.0/src/iter/mod.rs:82:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/multizip.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/multizip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/noop.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/once.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/once.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/panic_fuse.rs:102:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/panic_fuse.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/panic_fuse.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/panic_fuse.rs:98:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/par_bridge.rs:136:28 clippy::redundant_else "redundant else block" -rayon-1.5.0/src/iter/par_bridge.rs:163:28 clippy::redundant_else "redundant else block" -rayon-1.5.0/src/iter/plumbing/mod.rs:216:58 clippy::doc_markdown "you should put `find_first` between ticks in the documentation" -rayon-1.5.0/src/iter/plumbing/mod.rs:359:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/plumbing/mod.rs:364:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/plumbing/mod.rs:399:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/plumbing/mod.rs:53:19 clippy::doc_markdown "you should put `DoubleEndedIterator` between ticks in the documentation" -rayon-1.5.0/src/iter/plumbing/mod.rs:53:43 clippy::doc_markdown "you should put `ExactSizeIterator` between ticks in the documentation" -rayon-1.5.0/src/iter/plumbing/mod.rs:54:31 clippy::doc_markdown "you should put `IntoIterator` between ticks in the documentation" -rayon-1.5.0/src/iter/plumbing/mod.rs:55:5 clippy::doc_markdown "you should put `IntoIterator` between ticks in the documentation" -rayon-1.5.0/src/iter/positions.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/positions.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/product.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/reduce.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/repeat.rs:103:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rayon-1.5.0/src/iter/repeat.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/repeat.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/rev.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/rev.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/rev.rs:63:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/rev.rs:68:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/skip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/skip.rs:3:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/skip.rs:68:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/skip.rs:73:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/splitter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/splitter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/step_by.rs:4:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/step_by.rs:5:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/step_by.rs:73:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/step_by.rs:79:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/sum.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/take.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/take.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/take.rs:67:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/take.rs:72:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/try_fold.rs:190:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rayon-1.5.0/src/iter/try_fold.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/try_fold.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/try_reduce.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/try_reduce_with.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/unzip.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/unzip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/update.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/update.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/update.rs:82:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/update.rs:87:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/while_some.rs:130:22 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -rayon-1.5.0/src/iter/while_some.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/while_some.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/zip.rs:102:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/zip.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/zip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/zip.rs:74:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/zip.rs:79:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/zip.rs:97:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/iter/zip_eq.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/iter/zip_eq.rs:2:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/option.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/option.rs:9:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/par_either.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/par_either.rs:3:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/private.rs:9:1 clippy::module_name_repetitions "item name starts with its containing module's name" -rayon-1.5.0/src/range.rs:19:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/range.rs:20:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/range_inclusive.rs:194:9 clippy::range_plus_one "an inclusive range would be more readable" -rayon-1.5.0/src/range_inclusive.rs:194:9 clippy::range_plus_one "an inclusive range would be more readable" -rayon-1.5.0/src/range_inclusive.rs:19:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/range_inclusive.rs:209:9 clippy::range_plus_one "an inclusive range would be more readable" -rayon-1.5.0/src/range_inclusive.rs:209:9 clippy::range_plus_one "an inclusive range would be more readable" -rayon-1.5.0/src/range_inclusive.rs:20:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/range_inclusive.rs:231:9 clippy::range_plus_one "an inclusive range would be more readable" -rayon-1.5.0/src/range_inclusive.rs:231:9 clippy::range_plus_one "an inclusive range would be more readable" -rayon-1.5.0/src/result.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/result.rs:9:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/slice/mergesort.rs:102:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mergesort.rs:109:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mergesort.rs:114:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mergesort.rs:211:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mergesort.rs:217:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mergesort.rs:251:5 clippy::doc_markdown "you should put `TimSort` between ticks in the documentation" -rayon-1.5.0/src/slice/mergesort.rs:252:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -rayon-1.5.0/src/slice/mergesort.rs:286:59 clippy::doc_markdown "you should put `TimSort` between ticks in the documentation" -rayon-1.5.0/src/slice/mergesort.rs:333:24 clippy::redundant_else "redundant else block" -rayon-1.5.0/src/slice/mergesort.rs:513:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mergesort.rs:521:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mergesort.rs:7:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/slice/mergesort.rs:98:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/mod.rs:15:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/slice/mod.rs:16:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/slice/mod.rs:17:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/slice/mod.rs:25:1 clippy::module_name_repetitions "item name ends with its containing module's name" -rayon-1.5.0/src/slice/mod.rs:657:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rayon-1.5.0/src/slice/mod.rs:971:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -rayon-1.5.0/src/slice/quicksort.rs:230:36 clippy::doc_markdown "you should put `BlockQuicksort` between ticks in the documentation" -rayon-1.5.0/src/slice/quicksort.rs:233:1 clippy::too_many_lines "this function has too many lines (117/100)" -rayon-1.5.0/src/slice/quicksort.rs:258:26 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -rayon-1.5.0/src/slice/quicksort.rs:265:26 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -rayon-1.5.0/src/slice/quicksort.rs:268:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -rayon-1.5.0/src/slice/quicksort.rs:308:30 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -rayon-1.5.0/src/slice/quicksort.rs:325:30 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -rayon-1.5.0/src/slice/quicksort.rs:393:36 clippy::cast_possible_wrap "casting `u8` to `isize` may wrap around the value on targets with 32-bit wide pointers" -rayon-1.5.0/src/slice/quicksort.rs:405:40 clippy::cast_possible_wrap "casting `u8` to `isize` may wrap around the value on targets with 32-bit wide pointers" -rayon-1.5.0/src/slice/quicksort.rs:430:14 clippy::shadow_unrelated "`pivot` is being shadowed" -rayon-1.5.0/src/slice/quicksort.rs:439:13 clippy::shadow_unrelated "`pivot` is being shadowed" -rayon-1.5.0/src/slice/quicksort.rs:482:10 clippy::shadow_unrelated "`pivot` is being shadowed" -rayon-1.5.0/src/slice/quicksort.rs:491:9 clippy::shadow_unrelated "`pivot` is being shadowed" -rayon-1.5.0/src/slice/quicksort.rs:534:26 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -rayon-1.5.0/src/slice/quicksort.rs:545:17 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -rayon-1.5.0/src/slice/quicksort.rs:588:17 clippy::identity_op "the operation is ineffective. Consider reducing it to `len / 4`" -rayon-1.5.0/src/slice/quicksort.rs:716:14 clippy::shadow_unrelated "`pivot` is being shadowed" -rayon-1.5.0/src/split_producer.rs:56:16 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" -rayon-1.5.0/src/split_producer.rs:92:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" -rayon-1.5.0/src/str.rs:16:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/str.rs:17:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/str.rs:18:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/str.rs:25:5 clippy::cast_possible_wrap "casting `u8` to `i8` may wrap around the value" -rayon-1.5.0/src/str.rs:715:9 clippy::manual_strip "stripping a suffix manually" -rayon-1.5.0/src/string.rs:5:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/vec.rs:137:12 clippy::len_zero "length comparison to zero" -rayon-1.5.0/src/vec.rs:8:5 clippy::wildcard_imports "usage of wildcard import" -rayon-1.5.0/src/vec.rs:9:5 clippy::wildcard_imports "usage of wildcard import" -regex-1.3.2/src/backtrack.rs:100:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/backtrack.rs:133:17 clippy::same_item_push "it looks like the same item is being pushed into this Vec" -regex-1.3.2/src/backtrack.rs:145:20 clippy::if_not_else "unnecessary boolean `not` operation" -regex-1.3.2/src/backtrack.rs:199:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/backtrack.rs:223:29 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/backtrack.rs:230:66 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/backtrack.rs:284:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" -regex-1.3.2/src/backtrack.rs:287:5 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/backtrack.rs:97:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/backtrack.rs:98:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/backtrack.rs:99:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:1005:32 clippy::unreadable_literal "long literal lacking separators" -regex-1.3.2/src/compile.rs:1006:21 clippy::unreadable_literal "long literal lacking separators" -regex-1.3.2/src/compile.rs:1008:18 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" -regex-1.3.2/src/compile.rs:1009:18 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" -regex-1.3.2/src/compile.rs:1010:9 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -regex-1.3.2/src/compile.rs:102:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/compile.rs:1037:37 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" -regex-1.3.2/src/compile.rs:1037:55 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" -regex-1.3.2/src/compile.rs:1040:28 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" -regex-1.3.2/src/compile.rs:1040:38 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" -regex-1.3.2/src/compile.rs:1051:25 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -regex-1.3.2/src/compile.rs:1071:8 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" -regex-1.3.2/src/compile.rs:112:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/compile.rs:154:30 clippy::redundant_closure_for_method_calls "redundant closure found" -regex-1.3.2/src/compile.rs:156:30 clippy::redundant_closure_for_method_calls "redundant closure found" -regex-1.3.2/src/compile.rs:185:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -regex-1.3.2/src/compile.rs:187:40 clippy::redundant_closure_for_method_calls "redundant closure found" -regex-1.3.2/src/compile.rs:201:53 clippy::doc_markdown "you should put `MaybeInsts` between ticks in the documentation" -regex-1.3.2/src/compile.rs:241:63 clippy::doc_markdown "you should put `c_concat` between ticks in the documentation" -regex-1.3.2/src/compile.rs:245:5 clippy::too_many_lines "this function has too many lines (111/100)" -regex-1.3.2/src/compile.rs:247:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/compile.rs:373:24 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:373:36 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:378:12 clippy::if_not_else "unnecessary boolean `not` operation" -regex-1.3.2/src/compile.rs:400:37 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:407:51 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:409:24 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:417:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -regex-1.3.2/src/compile.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/compile.rs:42:5 clippy::new_without_default "you should consider adding a `Default` implementation for `compile::Compiler`" -regex-1.3.2/src/compile.rs:444:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -regex-1.3.2/src/compile.rs:445:57 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:446:20 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:466:20 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:466:32 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:519:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/compile.rs:55:57 clippy::doc_markdown "you should put `size_limit` between ticks in the documentation" -regex-1.3.2/src/compile.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/compile.rs:748:41 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:74:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/compile.rs:751:54 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:765:41 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:765:55 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:825:39 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:825:51 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:828:49 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:828:61 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:830:59 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:830:71 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:832:43 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:835:41 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:835:53 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:835:67 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/compile.rs:896:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -regex-1.3.2/src/compile.rs:905:17 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:953:17 clippy::doc_markdown "you should put `HashMap` between ticks in the documentation" -regex-1.3.2/src/compile.rs:95:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/compile.rs:980:26 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -regex-1.3.2/src/compile.rs:994:44 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/compile.rs:994:54 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:1007:17 clippy::similar_names "binding's name is too similar to existing binding" -regex-1.3.2/src/dfa.rs:1010:22 clippy::similar_names "binding's name is too similar to existing binding" -regex-1.3.2/src/dfa.rs:1059:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/dfa.rs:1060:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/dfa.rs:1084:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1087:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1090:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1093:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1096:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1101:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1104:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1107:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1117:30 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1120:47 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1121:30 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1129:13 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1134:13 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1185:68 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1193:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/dfa.rs:1244:50 clippy::doc_markdown "you should put `current_state` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1338:58 clippy::doc_markdown "you should put `STATE_DEAD` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1339:9 clippy::doc_markdown "you should put `STATE_UNKNOWN` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1366:25 clippy::doc_markdown "you should put `STATE_DEAD` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1366:46 clippy::doc_markdown "you should put `STATE_UNKNOWN` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1367:41 clippy::inline_always "you have declared `#[inline(always)]` on `start_state`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:1380:14 clippy::identity_op "the operation is ineffective. Consider reducing it to `(empty_flags.start as u8)`" -regex-1.3.2/src/dfa.rs:1388:15 clippy::match_on_vec_items "indexing into a vector may panic" -regex-1.3.2/src/dfa.rs:1412:20 clippy::unused_self "unused `self` argument" -regex-1.3.2/src/dfa.rs:1438:9 clippy::unused_self "unused `self` argument" -regex-1.3.2/src/dfa.rs:1472:9 clippy::doc_markdown "you should put `StatePtr` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1490:54 clippy::cast_possible_truncation "casting `i32` to `u8` may truncate the value" -regex-1.3.2/src/dfa.rs:1490:54 clippy::cast_sign_loss "casting `i32` to `u8` may lose the sign of the value" -regex-1.3.2/src/dfa.rs:1521:20 clippy::doc_markdown "you should put `num_byte_classes` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1529:41 clippy::inline_always "you have declared `#[inline(always)]` on `byte_class`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:1537:14 clippy::doc_markdown "you should put `byte_class` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1538:41 clippy::inline_always "you have declared `#[inline(always)]` on `u8_class`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:1562:18 clippy::doc_markdown "you should put `STATE_START` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:1614:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:1651:38 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:1700:17 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -regex-1.3.2/src/dfa.rs:1701:18 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/dfa.rs:1705:19 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/dfa.rs:1708:16 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -regex-1.3.2/src/dfa.rs:1709:18 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/dfa.rs:1713:19 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/dfa.rs:1716:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -regex-1.3.2/src/dfa.rs:1717:18 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/dfa.rs:1721:19 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/dfa.rs:1727:14 clippy::cast_lossless "casting `u8` to `u16` may become silently lossy if you later change the type" -regex-1.3.2/src/dfa.rs:1732:15 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -regex-1.3.2/src/dfa.rs:1736:22 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -regex-1.3.2/src/dfa.rs:1741:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" -regex-1.3.2/src/dfa.rs:1747:16 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -regex-1.3.2/src/dfa.rs:1751:18 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" -regex-1.3.2/src/dfa.rs:1815:38 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" -regex-1.3.2/src/dfa.rs:1821:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" -regex-1.3.2/src/dfa.rs:1824:5 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:1848:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -regex-1.3.2/src/dfa.rs:1850:18 clippy::cast_sign_loss "casting `i32` to `u32` may lose the sign of the value" -regex-1.3.2/src/dfa.rs:1857:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -regex-1.3.2/src/dfa.rs:1860:17 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -regex-1.3.2/src/dfa.rs:1867:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -regex-1.3.2/src/dfa.rs:1870:19 clippy::cast_possible_truncation "casting `u32` to `u8` may truncate the value" -regex-1.3.2/src/dfa.rs:1873:15 clippy::cast_possible_truncation "casting `u32` to `u8` may truncate the value" -regex-1.3.2/src/dfa.rs:1876:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -regex-1.3.2/src/dfa.rs:1882:26 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/dfa.rs:1884:15 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/dfa.rs:277:17 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -regex-1.3.2/src/dfa.rs:277:31 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" -regex-1.3.2/src/dfa.rs:295:20 clippy::cast_possible_truncation "casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/dfa.rs:295:20 clippy::cast_possible_wrap "casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers" -regex-1.3.2/src/dfa.rs:299:21 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" -regex-1.3.2/src/dfa.rs:34:46 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -regex-1.3.2/src/dfa.rs:398:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -regex-1.3.2/src/dfa.rs:446:41 clippy::inline_always "you have declared `#[inline(always)]` on `forward`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:457:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:459:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:460:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:476:41 clippy::inline_always "you have declared `#[inline(always)]` on `reverse`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:487:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:489:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:490:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:506:41 clippy::inline_always "you have declared `#[inline(always)]` on `forward_many`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:518:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:520:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/dfa.rs:554:41 clippy::inline_always "you have declared `#[inline(always)]` on `exec_at`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:555:5 clippy::too_many_lines "this function has too many lines (101/100)" -regex-1.3.2/src/dfa.rs:58:9 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/dfa.rs:667:21 clippy::similar_names "binding's name is too similar to existing binding" -regex-1.3.2/src/dfa.rs:747:41 clippy::inline_always "you have declared `#[inline(always)]` on `exec_at_reverse`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:795:21 clippy::similar_names "binding's name is too similar to existing binding" -regex-1.3.2/src/dfa.rs:848:9 clippy::doc_markdown "you should put `next_si` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:852:41 clippy::inline_always "you have declared `#[inline(always)]` on `next_si`. This is usually a bad idea" -regex-1.3.2/src/dfa.rs:885:12 clippy::doc_markdown "you should put `STATE_DEAD` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:889:9 clippy::doc_markdown "you should put `STATE_UNKNOWN` between ticks in the documentation" -regex-1.3.2/src/dfa.rs:897:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/dfa.rs:979:29 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" -regex-1.3.2/src/error.rs:6:1 clippy::manual_non_exhaustive "this seems like a manual implementation of the non-exhaustive pattern" -regex-1.3.2/src/exec.rs:1000:14 clippy::doc_markdown "you should put `captures_nfa` between ticks in the documentation" -regex-1.3.2/src/exec.rs:100:1 clippy::module_name_repetitions "item name starts with its containing module's name" -regex-1.3.2/src/exec.rs:1028:5 clippy::too_many_arguments "this function has too many arguments (9/7)" -regex-1.3.2/src/exec.rs:1039:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/exec.rs:1144:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/exec.rs:1179:26 clippy::match_same_arms "this `match` has identical arm bodies" -regex-1.3.2/src/exec.rs:122:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:1250:41 clippy::inline_always "you have declared `#[inline(always)]` on `searcher`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:1260:41 clippy::inline_always "you have declared `#[inline(always)]` on `searcher_str`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:1270:17 clippy::doc_markdown "you should put `RegexSet` between ticks in the documentation" -regex-1.3.2/src/exec.rs:1280:17 clippy::doc_markdown "you should put `RegexSet` between ticks in the documentation" -regex-1.3.2/src/exec.rs:137:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" -regex-1.3.2/src/exec.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:158:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:168:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:181:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:195:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:204:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:210:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/exec.rs:245:62 clippy::if_same_then_else "this `if` has identical blocks" -regex-1.3.2/src/exec.rs:251:21 clippy::if_not_else "unnecessary boolean `not` operation" -regex-1.3.2/src/exec.rs:262:60 clippy::if_same_then_else "this `if` has identical blocks" -regex-1.3.2/src/exec.rs:268:21 clippy::if_not_else "unnecessary boolean `not` operation" -regex-1.3.2/src/exec.rs:278:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:281:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:286:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/exec.rs:300:30 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:308:17 clippy::similar_names "binding's name is too similar to existing binding" -regex-1.3.2/src/exec.rs:329:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:330:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:331:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:334:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:340:19 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/exec.rs:344:27 clippy::unused_self "unused `self` argument" -regex-1.3.2/src/exec.rs:383:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_match_at`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:388:41 clippy::inline_always "you have declared `#[inline(always)]` on `is_match_at`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:393:41 clippy::inline_always "you have declared `#[inline(always)]` on `find_at`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:398:41 clippy::inline_always "you have declared `#[inline(always)]` on `captures_read_at`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:425:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_match_at`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:44:1 clippy::module_name_repetitions "item name starts with its containing module's name" -regex-1.3.2/src/exec.rs:473:9 clippy::doc_markdown "you should put `shortest_match(...).is_some` between ticks in the documentation" -regex-1.3.2/src/exec.rs:474:41 clippy::inline_always "you have declared `#[inline(always)]` on `is_match_at`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:524:41 clippy::inline_always "you have declared `#[inline(always)]` on `find_at`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:52:1 clippy::module_name_repetitions "item name starts with its containing module's name" -regex-1.3.2/src/exec.rs:686:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/exec.rs:727:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/exec.rs:767:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/exec.rs:783:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_dfa`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:791:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_dfa_reverse_suffix`. This is usually a bad idea" -regex-1.3.2/src/exec.rs:823:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/exec.rs:868:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/exec.rs:897:31 clippy::doc_markdown "you should put `shortest_nfa(...).is_some` between ticks in the documentation" -regex-1.3.2/src/exec.rs:899:9 clippy::doc_markdown "you should put `shortest_nfa` between ticks in the documentation" -regex-1.3.2/src/exec.rs:905:14 clippy::doc_markdown "you should put `match_nfa` between ticks in the documentation" -regex-1.3.2/src/exec.rs:930:14 clippy::doc_markdown "you should put `shortest_nfa` between ticks in the documentation" -regex-1.3.2/src/exec.rs:981:14 clippy::doc_markdown "you should put `find_nfa` between ticks in the documentation" -regex-1.3.2/src/expand.rs:170:27 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -regex-1.3.2/src/expand.rs:171:5 clippy::match_like_matches_macro "match expression looks like `matches!` macro" -regex-1.3.2/src/expand.rs:22:13 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -regex-1.3.2/src/expand.rs:27:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -regex-1.3.2/src/expand.rs:30:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -regex-1.3.2/src/expand.rs:38:30 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -regex-1.3.2/src/expand.rs:42:21 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -regex-1.3.2/src/expand.rs:50:1 clippy::module_name_repetitions "item name starts with its containing module's name" -regex-1.3.2/src/expand.rs:69:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -regex-1.3.2/src/expand.rs:80:28 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -regex-1.3.2/src/expand.rs:84:21 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" -regex-1.3.2/src/expand.rs:8:1 clippy::module_name_repetitions "item name starts with its containing module's name" -regex-1.3.2/src/input.rs:142:1 clippy::module_name_repetitions "item name ends with its containing module's name" -regex-1.3.2/src/input.rs:146:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" -regex-1.3.2/src/input.rs:165:31 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/input.rs:178:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/input.rs:228:1 clippy::module_name_repetitions "item name ends with its containing module's name" -regex-1.3.2/src/input.rs:236:21 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/input.rs:236:33 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/input.rs:24:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:271:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/input.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:362:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:370:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:371:42 clippy::redundant_closure_for_method_calls "redundant closure found" -regex-1.3.2/src/input.rs:37:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:388:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:47:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:53:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/input.rs:63:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/lib.rs:1:null clippy::cargo_common_metadata "package `regex` is missing `package.keywords` metadata" -regex-1.3.2/src/literal/imp.rs:101:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:114:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:127:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:139:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:144:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:149:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:154:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:155:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/literal/imp.rs:160:30 clippy::match_same_arms "this `match` has identical arm bodies" -regex-1.3.2/src/literal/imp.rs:167:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:168:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/literal/imp.rs:211:20 clippy::redundant_else "redundant else block" -regex-1.3.2/src/literal/imp.rs:276:50 clippy::match_same_arms "this `match` has identical arm bodies" -regex-1.3.2/src/literal/imp.rs:342:41 clippy::inline_always "you have declared `#[inline(always)]` on `find`. This is usually a bad idea" -regex-1.3.2/src/literal/imp.rs:435:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:436:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:437:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:438:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:439:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:440:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:455:41 clippy::inline_always "you have declared `#[inline(always)]` on `find`. This is usually a bad idea" -regex-1.3.2/src/literal/imp.rs:46:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:481:41 clippy::inline_always "you have declared `#[inline(always)]` on `is_suffix`. This is usually a bad idea" -regex-1.3.2/src/literal/imp.rs:51:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:579:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:580:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:583:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:602:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -regex-1.3.2/src/literal/imp.rs:622:24 clippy::redundant_else "redundant else block" -regex-1.3.2/src/literal/imp.rs:62:18 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -regex-1.3.2/src/literal/imp.rs:637:24 clippy::redundant_else "redundant else block" -regex-1.3.2/src/literal/imp.rs:648:9 clippy::needless_return "unneeded `return` statement" -regex-1.3.2/src/literal/imp.rs:651:44 clippy::doc_markdown "you should put `BoyerMooreSearch` between ticks in the documentation" -regex-1.3.2/src/literal/imp.rs:65:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:68:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/literal/imp.rs:783:32 clippy::redundant_else "redundant else block" -regex-1.3.2/src/literal/imp.rs:786:42 clippy::manual_saturating_arithmetic "manual saturating arithmetic" -regex-1.3.2/src/literal/imp.rs:78:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:84:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/literal/imp.rs:850:20 clippy::unreadable_literal "long literal lacking separators" -regex-1.3.2/src/literal/imp.rs:85:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/pikevm.rs:103:15 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/pikevm.rs:103:52 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/pikevm.rs:114:5 clippy::too_many_arguments "this function has too many arguments (8/7)" -regex-1.3.2/src/pikevm.rs:117:13 clippy::similar_names "binding's name is too similar to existing binding" -regex-1.3.2/src/pikevm.rs:124:17 clippy::similar_names "binding's name is too similar to existing binding" -regex-1.3.2/src/pikevm.rs:220:9 clippy::doc_markdown "you should put `thread_caps` between ticks in the documentation" -regex-1.3.2/src/pikevm.rs:222:16 clippy::doc_markdown "you should put `at_next` between ticks in the documentation" -regex-1.3.2/src/pikevm.rs:223:9 clippy::doc_markdown "you should put `at_next` between ticks in the documentation" -regex-1.3.2/src/pikevm.rs:224:5 clippy::too_many_arguments "this function has too many arguments (8/7)" -regex-1.3.2/src/pikevm.rs:234:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/pikevm.rs:303:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/pikevm.rs:331:29 clippy::mut_mut "this expression mutably borrows a mutable reference. Consider reborrowing" -regex-1.3.2/src/pikevm.rs:88:5 clippy::too_many_arguments "this function has too many arguments (8/7)" -regex-1.3.2/src/prog.rs:102:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:120:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" -regex-1.3.2/src/prog.rs:128:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:134:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:141:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:164:41 clippy::inline_always "you have declared `#[inline(always)]` on `deref`. This is usually a bad idea" -regex-1.3.2/src/prog.rs:172:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -regex-1.3.2/src/prog.rs:18:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -regex-1.3.2/src/prog.rs:236:13 clippy::write_with_newline "using `write!()` with a format string that ends in a single newline" -regex-1.3.2/src/prog.rs:300:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:301:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" -regex-1.3.2/src/prog.rs:382:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:409:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:80:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/prog.rs:80:5 clippy::new_without_default "you should consider adding a `Default` implementation for `prog::Program`" -regex-1.3.2/src/re_builder.rs:267:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_builder.rs:267:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_builder.rs:4:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -regex-1.3.2/src/re_builder.rs:57:17 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_builder.rs:57:17 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_builder.rs:68:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_builder.rs:68:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_bytes.rs:1017:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -regex-1.3.2/src/re_bytes.rs:1039:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -regex-1.3.2/src/re_bytes.rs:1093:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -regex-1.3.2/src/re_bytes.rs:1118:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -regex-1.3.2/src/re_bytes.rs:1133:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -regex-1.3.2/src/re_bytes.rs:118:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_bytes.rs:256:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_bytes.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:483:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -regex-1.3.2/src/re_bytes.rs:48:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:558:29 clippy::doc_markdown "you should put `shortest_match` between ticks in the documentation" -regex-1.3.2/src/re_bytes.rs:55:33 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_bytes.rs:55:47 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_bytes.rs:572:29 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" -regex-1.3.2/src/re_bytes.rs:720:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_bytes.rs:817:5 clippy::doc_markdown "you should put `CaptureLocations` between ticks in the documentation" -regex-1.3.2/src/re_bytes.rs:843:1 clippy::len_without_is_empty "item `re_bytes::CaptureLocations` has a public `len` method but no corresponding `is_empty` method" -regex-1.3.2/src/re_bytes.rs:849:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:858:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:869:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:891:1 clippy::len_without_is_empty "item `re_bytes::Captures<'t>` has a public `len` method but no corresponding `is_empty` method" -regex-1.3.2/src/re_bytes.rs:911:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:917:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:926:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_bytes.rs:955:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:179:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_set.rs:179:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_set.rs:251:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:251:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_set.rs:94:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_set.rs:94:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_trait.rs:136:29 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_unicode.rs:1019:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -regex-1.3.2/src/re_unicode.rs:1041:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -regex-1.3.2/src/re_unicode.rs:1088:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_unicode.rs:1135:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -regex-1.3.2/src/re_unicode.rs:1160:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -regex-1.3.2/src/re_unicode.rs:174:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -regex-1.3.2/src/re_unicode.rs:21:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:313:13 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_unicode.rs:38:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:44:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:51:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:533:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -regex-1.3.2/src/re_unicode.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:617:29 clippy::doc_markdown "you should put `shortest_match` between ticks in the documentation" -regex-1.3.2/src/re_unicode.rs:631:29 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" -regex-1.3.2/src/re_unicode.rs:64:33 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_unicode.rs:64:47 clippy::redundant_field_names "redundant field names in struct initialization" -regex-1.3.2/src/re_unicode.rs:834:5 clippy::doc_markdown "you should put `CaptureLocations` between ticks in the documentation" -regex-1.3.2/src/re_unicode.rs:860:1 clippy::len_without_is_empty "item `re_unicode::CaptureLocations` has a public `len` method but no corresponding `is_empty` method" -regex-1.3.2/src/re_unicode.rs:866:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:875:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:886:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:908:1 clippy::len_without_is_empty "item `re_unicode::Captures<'t>` has a public `len` method but no corresponding `is_empty` method" -regex-1.3.2/src/re_unicode.rs:928:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:934:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:943:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/re_unicode.rs:972:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -regex-1.3.2/src/sparse.rs:10:37 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -regex-1.3.2/src/sparse.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" -regex-1.3.2/src/utf8.rs:100:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:103:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:106:22 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:107:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:108:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:109:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:111:27 clippy::unreadable_literal "long literal lacking separators" -regex-1.3.2/src/utf8.rs:121:1 clippy::module_name_repetitions "item name ends with its containing module's name" -regex-1.3.2/src/utf8.rs:143:24 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:143:9 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:23:1 clippy::module_name_repetitions "item name ends with its containing module's name" -regex-1.3.2/src/utf8.rs:30:20 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:51:1 clippy::module_name_repetitions "item name ends with its containing module's name" -regex-1.3.2/src/utf8.rs:58:23 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:58:9 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:63:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:66:22 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:66:54 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:77:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:80:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:83:22 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:84:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:85:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" -regex-1.3.2/src/utf8.rs:92:23 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:92:9 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -regex-1.3.2/src/utf8.rs:97:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" -ripgrep-12.1.1/build.rs:133:19 clippy::option_as_ref_deref "called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `githash.as_deref()` instead" -ripgrep-12.1.1/build.rs:18:18 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -ripgrep-12.1.1/build.rs:225:14 clippy::redundant_closure_for_method_calls "redundant closure found" -ripgrep-12.1.1/build.rs:92:19 clippy::option_as_ref_deref "called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `githash.as_deref()` instead" -ripgrep-12.1.1/crates/core/app.rs:1408:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1408:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1409:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1409:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:152:32 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:152:32 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:156:39 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:156:39 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:156:5 clippy::doc_markdown "you should put `RGArg` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:156:5 clippy::doc_markdown "you should put `RGArg` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:1668:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1668:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1669:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1669:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1821:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1821:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1822:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:1822:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:2999:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:2999:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:3000:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:3000:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -ripgrep-12.1.1/crates/core/app.rs:367:54 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:367:54 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:414:59 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:414:59 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/app.rs:75:9 clippy::doc_markdown "you should put `RIPGREP_BUILD_GIT_HASH` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:75:9 clippy::doc_markdown "you should put `RIPGREP_BUILD_GIT_HASH` between ticks in the documentation" -ripgrep-12.1.1/crates/core/app.rs:87:5 clippy::if_not_else "unnecessary boolean `not` operation" -ripgrep-12.1.1/crates/core/app.rs:87:5 clippy::if_not_else "unnecessary boolean `not` operation" -ripgrep-12.1.1/crates/core/args.rs:1143:22 clippy::unused_self "unused `self` argument" -ripgrep-12.1.1/crates/core/args.rs:11:1 clippy::single_component_path_imports "this import is redundant" -ripgrep-12.1.1/crates/core/args.rs:1209:74 clippy::if_same_then_else "this `if` has identical blocks" -ripgrep-12.1.1/crates/core/args.rs:1282:13 clippy::similar_names "binding's name is too similar to existing binding" -ripgrep-12.1.1/crates/core/args.rs:1430:22 clippy::unused_self "unused `self` argument" -ripgrep-12.1.1/crates/core/args.rs:1438:21 clippy::doc_markdown "you should put `OsStr` between ticks in the documentation" -ripgrep-12.1.1/crates/core/args.rs:1520:44 clippy::redundant_closure_for_method_calls "redundant closure found" -ripgrep-12.1.1/crates/core/args.rs:1524:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -ripgrep-12.1.1/crates/core/args.rs:1635:14 clippy::doc_markdown "you should put `values_of_lossy` between ticks in the documentation" -ripgrep-12.1.1/crates/core/args.rs:1693:41 clippy::redundant_closure_for_method_calls "redundant closure found" -ripgrep-12.1.1/crates/core/args.rs:1770:17 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -ripgrep-12.1.1/crates/core/args.rs:1829:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -ripgrep-12.1.1/crates/core/args.rs:287:13 clippy::similar_names "binding's name is too similar to existing binding" -ripgrep-12.1.1/crates/core/args.rs:33:1 clippy::single_component_path_imports "this import is redundant" -ripgrep-12.1.1/crates/core/args.rs:34:1 clippy::single_component_path_imports "this import is redundant" -ripgrep-12.1.1/crates/core/args.rs:35:1 clippy::single_component_path_imports "this import is redundant" -ripgrep-12.1.1/crates/core/args.rs:369:5 clippy::upper_case_acronyms "name `JSON` contains a capitalized acronym" -ripgrep-12.1.1/crates/core/args.rs:410:14 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -ripgrep-12.1.1/crates/core/args.rs:475:18 clippy::match_same_arms "this `match` has identical arm bodies" -ripgrep-12.1.1/crates/core/args.rs:512:19 clippy::doc_markdown "you should put `ArgMatches` between ticks in the documentation" -ripgrep-12.1.1/crates/core/args.rs:549:16 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" -ripgrep-12.1.1/crates/core/args.rs:76:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -ripgrep-12.1.1/crates/core/args.rs:77:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -ripgrep-12.1.1/crates/core/args.rs:923:42 clippy::doc_markdown "you should put `BinaryDetection::quit` between ticks in the documentation" -ripgrep-12.1.1/crates/core/config.rs:13:1 clippy::single_component_path_imports "this import is redundant" -ripgrep-12.1.1/crates/core/config.rs:58:6 clippy::type_complexity "very complex type used. Consider factoring parts into `type` definitions" -ripgrep-12.1.1/crates/core/config.rs:79:6 clippy::type_complexity "very complex type used. Consider factoring parts into `type` definitions" -ripgrep-12.1.1/crates/core/logger.rs:11:30 clippy::doc_markdown "you should put `max_level` between ticks in the documentation" -ripgrep-12.1.1/crates/core/logger.rs:15:16 clippy::redundant_static_lifetimes "constants have by default a `'static` lifetime" -ripgrep-12.1.1/crates/core/main.rs:114:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -ripgrep-12.1.1/crates/core/main.rs:189:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -ripgrep-12.1.1/crates/core/main.rs:55:19 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -ripgrep-12.1.1/crates/core/main.rs:56:9 clippy::enum_glob_use "usage of wildcard import for enum variants" -ripgrep-12.1.1/crates/core/messages.rs:46:1 clippy::module_name_repetitions "item name ends with its containing module's name" -ripgrep-12.1.1/crates/core/messages.rs:51:1 clippy::module_name_repetitions "item name ends with its containing module's name" -ripgrep-12.1.1/crates/core/messages.rs:62:1 clippy::module_name_repetitions "item name ends with its containing module's name" -ripgrep-12.1.1/crates/core/path_printer.rs:27:1 clippy::module_name_repetitions "item name starts with its containing module's name" -ripgrep-12.1.1/crates/core/path_printer.rs:89:9 clippy::if_not_else "unnecessary boolean `not` operation" -ripgrep-12.1.1/crates/core/search.rs:185:1 clippy::module_name_repetitions "item name starts with its containing module's name" -ripgrep-12.1.1/crates/core/search.rs:224:5 clippy::upper_case_acronyms "name `JSON` contains a capitalized acronym" -ripgrep-12.1.1/crates/core/search.rs:292:9 clippy::write_with_newline "using `write!()` with a format string that ends in a single newline" -ripgrep-12.1.1/crates/core/search.rs:311:1 clippy::module_name_repetitions "item name starts with its containing module's name" -ripgrep-12.1.1/crates/core/search.rs:377:12 clippy::nonminimal_bool "this boolean expression can be simplified" -ripgrep-12.1.1/crates/core/search.rs:423:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -ripgrep-12.1.1/crates/core/search.rs:447:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -ripgrep-12.1.1/crates/core/search.rs:472:24 clippy::map_clone "you are using an explicit closure for cloning elements" -ripgrep-12.1.1/crates/core/search.rs:472:41 clippy::redundant_closure_for_method_calls "redundant closure found" -ripgrep-12.1.1/crates/core/search.rs:480:24 clippy::map_clone "you are using an explicit closure for cloning elements" -ripgrep-12.1.1/crates/core/search.rs:480:41 clippy::redundant_closure_for_method_calls "redundant closure found" -ripgrep-12.1.1/crates/core/search.rs:49:1 clippy::module_name_repetitions "item name starts with its containing module's name" -ripgrep-12.1.1/crates/core/search.rs:509:24 clippy::map_clone "you are using an explicit closure for cloning elements" -ripgrep-12.1.1/crates/core/search.rs:509:41 clippy::redundant_closure_for_method_calls "redundant closure found" -ripgrep-12.1.1/crates/core/search.rs:517:24 clippy::map_clone "you are using an explicit closure for cloning elements" -ripgrep-12.1.1/crates/core/search.rs:517:41 clippy::redundant_closure_for_method_calls "redundant closure found" -ripgrep-12.1.1/crates/core/search.rs:533:36 clippy::cast_lossless "casting `u32` to `f64` may become silently lossy if you later change the type" -ripgrep-12.1.1/crates/core/search.rs:533:5 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -ripgrep-12.1.1/crates/core/subject.rs:20:1 clippy::module_name_repetitions "item name starts with its containing module's name" -ripgrep-12.1.1/crates/core/subject.rs:4:1 clippy::single_component_path_imports "this import is redundant" -serde-1.0.118/src/de/mod.rs:1592:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -serde-1.0.118/src/de/mod.rs:1616:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -serde-1.0.118/src/de/mod.rs:1627:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -serde-1.0.118/src/de/mod.rs:1638:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -serde-1.0.118/src/de/mod.rs:1649:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -serde-1.0.118/src/de/mod.rs:952:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -serde-1.0.118/src/de/mod.rs:986:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" -syn-1.0.54/build.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata" -syn-1.0.54/src/lib.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata" -syn-1.0.54/src/lit.rs:1397:40 clippy::redundant_else "redundant else block" -syn-1.0.54/src/lit.rs:1405:28 clippy::redundant_else "redundant else block" -syn-1.0.54/src/lit.rs:1485:32 clippy::redundant_else "redundant else block" -syn-1.0.54/src/token.rs:974:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -unicode-xid-0.2.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `unicode-xid` is missing `package.categories` metadata" -unicode-xid-0.2.1/src/lib.rs:57:64 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:60:10 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:62:27 clippy::doc_markdown "you should put `ID_Start` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:62:67 clippy::doc_markdown "you should put `NFKx` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:63:21 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" -unicode-xid-0.2.1/src/lib.rs:65:61 clippy::doc_markdown "you should put `XID_Continue` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:68:10 clippy::doc_markdown "you should put `XID_Continue` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:70:28 clippy::doc_markdown "you should put `ID_Continue` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:70:72 clippy::doc_markdown "you should put `NFKx` between ticks in the documentation" -unicode-xid-0.2.1/src/lib.rs:71:24 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" -xsv-0.13.0/src/cmd/cat.rs:101:34 clippy::redundant_closure_for_method_calls "redundant closure found" -xsv-0.13.0/src/cmd/cat.rs:42:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -xsv-0.13.0/src/cmd/cat.rs:53:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/cat.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/count.rs:32:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/count.rs:38:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -xsv-0.13.0/src/cmd/count.rs:42:33 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -xsv-0.13.0/src/cmd/count.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/fixlengths.rs:45:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/fixlengths.rs:50:18 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -xsv-0.13.0/src/cmd/fixlengths.rs:62:30 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -xsv-0.13.0/src/cmd/fixlengths.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/flatten.rs:10:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/flatten.rs:51:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/fmt.rs:50:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/fmt.rs:55:13 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/fmt.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/frequency.rs:148:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/frequency.rs:149:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/frequency.rs:15:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/frequency.rs:169:13 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/frequency.rs:176:17 clippy::if_not_else "unnecessary boolean `not` operation" -xsv-0.13.0/src/cmd/frequency.rs:178:24 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -xsv-0.13.0/src/cmd/frequency.rs:77:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/frequency.rs:93:31 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" -xsv-0.13.0/src/cmd/headers.rs:43:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/headers.rs:49:17 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" -xsv-0.13.0/src/cmd/headers.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/index.rs:11:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/index.rs:45:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/input.rs:42:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/input.rs:47:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/input.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/join.rs:17:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/join.rs:194:29 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/join.rs:224:22 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/join.rs:293:14 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/join.rs:293:20 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/join.rs:297:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/join.rs:298:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/join.rs:299:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/join.rs:300:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/join.rs:308:9 clippy::unused_self "unused `self` argument" -xsv-0.13.0/src/cmd/join.rs:342:38 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -xsv-0.13.0/src/cmd/join.rs:342:46 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" -xsv-0.13.0/src/cmd/join.rs:347:9 clippy::if_not_else "unnecessary boolean `not` operation" -xsv-0.13.0/src/cmd/join.rs:372:44 clippy::redundant_closure_for_method_calls "redundant closure found" -xsv-0.13.0/src/cmd/join.rs:375:33 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/join.rs:392:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/join.rs:403:29 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" -xsv-0.13.0/src/cmd/join.rs:426:13 clippy::if_not_else "unnecessary boolean `not` operation" -xsv-0.13.0/src/cmd/join.rs:77:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -xsv-0.13.0/src/cmd/join.rs:94:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/partition.rs:105:22 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/partition.rs:106:22 clippy::redundant_slicing "redundant slicing of the whole range" -xsv-0.13.0/src/cmd/partition.rs:139:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/partition.rs:15:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/partition.rs:169:9 clippy::if_not_else "unnecessary boolean `not` operation" -xsv-0.13.0/src/cmd/partition.rs:56:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/partition.rs:77:9 clippy::unused_self "unused `self` argument" -xsv-0.13.0/src/cmd/sample.rs:105:44 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/sample.rs:115:21 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/sample.rs:11:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/sample.rs:51:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/sample.rs:58:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -xsv-0.13.0/src/cmd/sample.rs:69:9 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -xsv-0.13.0/src/cmd/sample.rs:75:16 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" -xsv-0.13.0/src/cmd/sample.rs:91:42 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/sample.rs:92:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/search.rs:51:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/search.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/select.rs:60:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/select.rs:8:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/slice.rs:57:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/slice.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/sort.rs:11:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/sort.rs:138:47 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -xsv-0.13.0/src/cmd/sort.rs:139:51 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -xsv-0.13.0/src/cmd/sort.rs:48:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/sort.rs:91:14 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" -xsv-0.13.0/src/cmd/split.rs:14:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/split.rs:61:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/split.rs:94:5 clippy::unnecessary_wraps "this function's return value is unnecessary" -xsv-0.13.0/src/cmd/split.rs:96:14 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -xsv-0.13.0/src/cmd/split.rs:99:13 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/stats.rs:110:36 clippy::redundant_closure_for_method_calls "redundant closure found" -xsv-0.13.0/src/cmd/stats.rs:127:14 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -xsv-0.13.0/src/cmd/stats.rs:138:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/stats.rs:139:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -xsv-0.13.0/src/cmd/stats.rs:162:25 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" -xsv-0.13.0/src/cmd/stats.rs:22:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/stats.rs:231:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -xsv-0.13.0/src/cmd/stats.rs:262:35 clippy::default_trait_access "calling `cmd::stats::TypedSum::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:263:40 clippy::default_trait_access "calling `cmd::stats::TypedMinMax::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:264:39 clippy::default_trait_access "calling `stats::OnlineStats::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:265:58 clippy::default_trait_access "calling `stats::Unsorted::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:266:41 clippy::default_trait_access "calling `stats::Unsorted::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:268:18 clippy::default_trait_access "calling `cmd::stats::FieldType::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:269:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/stats.rs:270:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/stats.rs:271:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/stats.rs:272:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/stats.rs:273:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/stats.rs:274:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/cmd/stats.rs:283:9 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" -xsv-0.13.0/src/cmd/stats.rs:284:9 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" -xsv-0.13.0/src/cmd/stats.rs:285:9 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" -xsv-0.13.0/src/cmd/stats.rs:290:21 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" -xsv-0.13.0/src/cmd/stats.rs:293:25 clippy::match_same_arms "this `match` has identical arm bodies" -xsv-0.13.0/src/cmd/stats.rs:297:25 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" -xsv-0.13.0/src/cmd/stats.rs:301:21 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" -xsv-0.13.0/src/cmd/stats.rs:302:21 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" -xsv-0.13.0/src/cmd/stats.rs:308:18 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" -xsv-0.13.0/src/cmd/stats.rs:318:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -xsv-0.13.0/src/cmd/stats.rs:322:45 clippy::redundant_closure_for_method_calls "redundant closure found" -xsv-0.13.0/src/cmd/stats.rs:322:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -xsv-0.13.0/src/cmd/stats.rs:327:9 clippy::if_not_else "unnecessary boolean `not` operation" -xsv-0.13.0/src/cmd/stats.rs:330:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -xsv-0.13.0/src/cmd/stats.rs:338:45 clippy::redundant_closure_for_method_calls "redundant closure found" -xsv-0.13.0/src/cmd/stats.rs:402:16 clippy::redundant_pattern_matching "redundant pattern matching, consider using `is_ok()`" -xsv-0.13.0/src/cmd/stats.rs:403:16 clippy::redundant_pattern_matching "redundant pattern matching, consider using `is_ok()`" -xsv-0.13.0/src/cmd/stats.rs:407:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -xsv-0.13.0/src/cmd/stats.rs:411:16 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -xsv-0.13.0/src/cmd/stats.rs:427:56 clippy::match_same_arms "this `match` has identical arm bodies" -xsv-0.13.0/src/cmd/stats.rs:429:56 clippy::match_same_arms "this `match` has identical arm bodies" -xsv-0.13.0/src/cmd/stats.rs:430:60 clippy::match_same_arms "this `match` has identical arm bodies" -xsv-0.13.0/src/cmd/stats.rs:430:60 clippy::match_same_arms "this `match` has identical arm bodies" -xsv-0.13.0/src/cmd/stats.rs:454:5 clippy::doc_markdown "you should put `TypedSum` between ticks in the documentation" -xsv-0.13.0/src/cmd/stats.rs:473:43 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -xsv-0.13.0/src/cmd/stats.rs:504:56 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -xsv-0.13.0/src/cmd/stats.rs:505:51 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -xsv-0.13.0/src/cmd/stats.rs:511:5 clippy::doc_markdown "you should put `TypedMinMax` between ticks in the documentation" -xsv-0.13.0/src/cmd/stats.rs:536:35 clippy::cast_possible_truncation "casting `f64` to `i64` may truncate the value" -xsv-0.13.0/src/cmd/stats.rs:544:33 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -xsv-0.13.0/src/cmd/stats.rs:592:22 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:593:22 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:594:23 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:595:21 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" -xsv-0.13.0/src/cmd/stats.rs:71:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -xsv-0.13.0/src/cmd/stats.rs:86:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/table.rs:10:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/cmd/table.rs:50:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/cmd/table.rs:54:9 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/config.rs:113:43 clippy::or_fun_call "use of `unwrap_or` followed by a function call" -xsv-0.13.0/src/config.rs:58:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -xsv-0.13.0/src/config.rs:77:28 clippy::explicit_deref_methods "explicit deref method call" -xsv-0.13.0/src/config.rs:90:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/index.rs:31:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/main.rs:164:49 clippy::redundant_clone "redundant clone" -xsv-0.13.0/src/main.rs:1:null clippy::cargo_common_metadata "package `xsv` is missing `package.categories` metadata" -xsv-0.13.0/src/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `rand_core`: 0.3.1, 0.4.2" -xsv-0.13.0/src/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `rand`: 0.3.23, 0.4.6" -xsv-0.13.0/src/main.rs:75:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" -xsv-0.13.0/src/select.rs:13:1 clippy::module_name_repetitions "item name starts with its containing module's name" -xsv-0.13.0/src/select.rs:154:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -xsv-0.13.0/src/select.rs:250:33 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/select.rs:250:43 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/select.rs:255:39 clippy::range_plus_one "an inclusive range would be more readable" -xsv-0.13.0/src/select.rs:280:20 clippy::len_zero "length comparison to zero" -xsv-0.13.0/src/select.rs:29:13 clippy::redundant_field_names "redundant field names in struct initialization" -xsv-0.13.0/src/select.rs:360:62 clippy::trivially_copy_pass_by_ref "this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" -xsv-0.13.0/src/select.rs:360:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Option`" -xsv-0.13.0/src/select.rs:375:9 clippy::stable_sort_primitive "used `sort` on primitive type `usize`" -xsv-0.13.0/src/select.rs:379:18 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" -xsv-0.13.0/src/select.rs:416:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" -xsv-0.13.0/src/select.rs:419:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Option`" -xsv-0.13.0/src/select.rs:420:27 clippy::option_option "consider using `Option` instead of `Option>` or a custom enum if you need to distinguish all 3 cases" -xsv-0.13.0/src/select.rs:99:17 clippy::similar_names "binding's name is too similar to existing binding" -xsv-0.13.0/src/util.rs:150:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" -xsv-0.13.0/src/util.rs:37:33 clippy::map_clone "you are using an explicit closure for copying elements" -xsv-0.13.0/src/util.rs:90:1 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" +target/lintcheck/sources/cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:104:34 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:121:5 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:157:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:184:41 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:196:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:200:39 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:231:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:23:56 clippy::implicit_clone "implicitly cloning a `String` by calling `to_owned` on its dereferenced type" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:245:22 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:247:47 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:257:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:26:20 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:7:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/bench.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/bench.rs:76:59 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/build.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/check.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/clean.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/doc.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/fetch.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/fetch.rs:22:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/fix.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/generate_lockfile.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/git_checkout.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/help.rs:20:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/init.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/install.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/install.rs:97:16 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/locate_project.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/login.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/metadata.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/mod.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/new.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/new.rs:20:24 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:38:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:39:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:40:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:43:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:46:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/package.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/pkgid.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/publish.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/publish.rs:40:47 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/read_manifest.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/run.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/rustc.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/rustdoc.rs:3:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/search.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/test.rs:127:54 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/test.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/tree.rs:149:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/tree.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/uninstall.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/update.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/vendor.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/vendor.rs:96:16 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/verify_project.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/version.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:32:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:33:35 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:34:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:35:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:100:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:118:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:137:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:148:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:174:57 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:18:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `crossbeam-utils`: 0.6.6, 0.7.2" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:72:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:94:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:96:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:98:60 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:155:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:170:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:175:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:180:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:186:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:197:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:205:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:51:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:69:48 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:96:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/mod.rs:44:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/mod.rs:83:20 clippy::doc_markdown "you should put `x86_64` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:108:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:121:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:149:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:411:9 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:420:69 clippy::doc_markdown "you should put `mode/target_kind` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:423:19 clippy::doc_markdown "you should put `CrateTypes` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:424:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:469:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:603:19 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:665:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:697:12 clippy::inconsistent_struct_constructor "inconsistent struct constructor" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:82:31 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:84:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:96:31 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:98:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:4:9 clippy::doc_markdown "you should put `BuildPlan` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:5:66 clippy::doc_markdown "you should put `BuildPlan` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:66:40 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:169:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:185:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:193:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:194:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:198:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:314:16 clippy::doc_markdown "you should put `rustc_tool` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:91:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:118:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:123:18 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:157:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:33:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:49:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:69:48 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:204:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:277:22 clippy::doc_markdown "you should put `OUT_DIR` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:324:66 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:393:37 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:426:71 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::too_many_lines "this function has too many lines (107/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:270:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:286:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:308:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:308:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:340:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:340:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:349:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:349:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:354:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:358:21 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:361:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:374:43 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:378:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:383:41 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:384:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:391:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:397:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:523:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:538:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:542:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:83:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:92:25 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:16:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:40:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/crate_type.rs:60:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:150:1 clippy::too_many_lines "this function has too many lines (230/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:353:56 clippy::manual_strip "stripping a prefix manually" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:448:27 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:464:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:481:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:481:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:48:56 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:561:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:567:20 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:576:28 clippy::shadow_unrelated "`mut value` is being shadowed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:606:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:688:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:756:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:762:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:762:5 clippy::unnecessary_wraps "this function's return value is unnecessary" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:823:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1021:51 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1656:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1664:5 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1787:5 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1795:5 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1882:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1894:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1906:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1917:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1923:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1956:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1962:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1963:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1964:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1965:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1966:22 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1980:24 clippy::manual_strip "stripping a prefix manually" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1986:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:2016:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:61:5 clippy::doc_markdown "you should put `CompileMode` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:63:12 clippy::doc_markdown "you should put `CompileKind` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:67:7 clippy::doc_markdown "you should put `CARGO_DEFAULT_LIB_METADATA[^4` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:68:5 clippy::doc_markdown "you should put `package_id` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:71:19 clippy::doc_markdown "you should put `test/bench/for_host/edition` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:755:52 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:77:5 clippy::doc_markdown "you should put `is_std` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:816:5 clippy::too_many_lines "this function has too many lines (127/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:863:64 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:875:33 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:876:32 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:896:30 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:897:30 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:991:37 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:12:5 clippy::doc_markdown "you should put `src/librustc_jobserver/lib.rs` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:329:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:332:23 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:34:53 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:35:6 clippy::doc_markdown "you should put `ReleaseToken` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:37:6 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:40:5 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:40:56 clippy::doc_markdown "you should put `NeedsToken` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:43:6 clippy::doc_markdown "you should put `ReleaseToken` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:748:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:749:13 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:786:26 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:81:61 clippy::doc_markdown "you should put `DrainState` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:865:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:871:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:890:9 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:93:24 clippy::doc_markdown "you should put `JobQueue` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/links.rs:8:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1016:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1094:19 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1131:1 clippy::unnecessary_wraps "this function's return value is unnecessary" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1268:34 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1277:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:179:1 clippy::too_many_lines "this function has too many lines (162/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:198:78 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:201:25 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:267:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:324:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::unnecessary_wraps "this function's return value is unnecessary" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:392:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:415:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:464:18 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:488:61 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:654:46 clippy::implicit_clone "implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:667:15 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:693:1 clippy::unnecessary_wraps "this function's return value is unnecessary" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:725:42 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:736:1 clippy::too_many_lines "this function has too many lines (141/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:73:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:777:12 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:873:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/output_depinfo.rs:41:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:16:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:57:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:72:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:134:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:16:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:30:28 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:16:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:192:64 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:212:58 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:234:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:355:13 clippy::cast_possible_truncation "casting `f64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:355:13 clippy::cast_sign_loss "casting `f64` to `u32` may lose the sign of the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:397:38 clippy::cast_possible_truncation "casting `f64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:397:38 clippy::cast_sign_loss "casting `f64` to `u32` may lose the sign of the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:484:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:605:38 clippy::doc_markdown "you should put `rmeta_time` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:605:50 clippy::doc_markdown "you should put `codegen_time` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:641:26 clippy::non_ascii_literal "literal non-ASCII character detected" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit.rs:100:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit.rs:151:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit.rs:161:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit.rs:35:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:154:29 clippy::doc_markdown "you should put `state.unit_dependencies` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:213:1 clippy::too_many_lines "this function has too many lines (110/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:52:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit_dependencies.rs:52:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit_graph.rs:65:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/unit_graph.rs:65:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:157:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:182:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:203:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:224:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:23:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:248:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:270:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:274:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:278:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:287:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:291:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:305:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:311:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:319:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:337:75 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:397:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:403:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:408:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:415:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:419:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:424:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:428:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:433:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:438:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:443:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:449:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:450:9 clippy::if_not_else "unnecessary `!=` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:119:17 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:229:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:274:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:278:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:306:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:338:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:362:25 clippy::option_option "consider using `Option` instead of `Option>` or a custom enum if you need to distinguish all 3 cases" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:380:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:401:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:409:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:412:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:416:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:419:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:424:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:431:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:477:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:509:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:518:5 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:542:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:543:37 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:547:60 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:556:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:563:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:116:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:118:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:130:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:159:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:162:34 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:169:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:17:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:189:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:215:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:222:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:22:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:320:46 clippy::implicit_clone "implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:360:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:407:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:410:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:413:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:416:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:419:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:422:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:425:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:431:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:438:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:444:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:447:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:450:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:453:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:456:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:459:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:462:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:466:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:470:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:477:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:481:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:488:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:512:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:516:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:520:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:524:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:528:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:538:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:557:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:561:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:565:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:569:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:577:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:581:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:588:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:617:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:632:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:648:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:659:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:66:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:670:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:693:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:708:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:723:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:726:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:729:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:735:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:738:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:741:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:744:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:747:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:751:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:754:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:757:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:760:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:763:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:767:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:776:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:780:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:787:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:798:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:800:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:805:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:809:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:818:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:823:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:828:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:831:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:834:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:839:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:85:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:888:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:936:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:1075:28 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:160:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:170:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:174:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:182:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:186:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:190:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:194:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:194:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:198:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:202:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:206:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:210:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:217:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:221:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:222:35 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:226:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:227:35 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:230:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:239:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:249:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:287:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:385:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:421:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:425:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:452:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:453:60 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:459:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:473:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:587:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:588:9 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:682:46 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:682:46 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:682:63 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:682:63 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:731:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:790:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:988:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:115:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:124:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:124:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:139:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:145:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:149:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:161:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:169:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:174:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:101:39 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:160:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:212:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:231:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:88:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:1004:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:1014:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:1018:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:1028:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:106:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:143:5 clippy::unnecessary_wraps "this function's return value is unnecessary" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:204:54 clippy::implicit_clone "implicitly cloning a `InternedString` by calling `to_owned` on its dereferenced type" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:286:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:286:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:294:40 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:30:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:342:25 clippy::shadow_unrelated "`maker` is being shadowed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:370:41 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:370:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:372:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:382:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:382:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:383:28 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:397:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:405:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:607:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:909:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:923:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:934:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/profiles.rs:987:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:111:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:127:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:168:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:240:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:26:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:344:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:369:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:424:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:49:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:520:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:763:53 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:765:53 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:807:14 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:814:53 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/conflict_cache.rs:197:29 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/conflict_cache.rs:41:38 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/context.rs:274:53 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/context.rs:42:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/context.rs:74:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::too_many_lines "this function has too many lines (164/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:339:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:438:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:449:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:529:34 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:602:59 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:623:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:652:27 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:674:51 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:103:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:104:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:206:9 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:257:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:27:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:305:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:70:1 clippy::too_many_lines "this function has too many lines (207/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:104:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:111:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:162:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:179:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:186:23 clippy::doc_markdown "you should put `RequestedFeatures` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:187:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:199:23 clippy::doc_markdown "you should put `RequestedFeatures` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:200:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:221:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:231:21 clippy::doc_markdown "you should put `pkg_id/is_build` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:233:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:247:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:278:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:394:27 clippy::doc_markdown "you should put `FeatureValue` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:460:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:480:24 clippy::doc_markdown "you should put `FeatureValues` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:496:24 clippy::doc_markdown "you should put `FeatureValues` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:58:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:67:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:1017:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:1045:57 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:122:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:142:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:180:1 clippy::too_many_lines "this function has too many lines (225/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:311:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:421:52 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:457:69 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:470:37 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:607:11 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:631:21 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:942:15 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:988:20 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:120:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:132:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:199:24 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:235:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:239:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:255:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:259:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:269:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:273:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:274:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:280:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:284:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:288:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:292:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:296:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:300:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:315:13 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:354:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:362:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:60:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/resolve.rs:76:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:111:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:121:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:141:19 clippy::doc_markdown "you should put `ResolveOpts` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:149:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:181:9 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:187:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/types.rs:261:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:130:9 clippy::single_match_else "you seem to be trying to use `match` for an equality check. Consider using `if`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:148:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:153:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:163:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:18:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:198:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:206:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:214:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:228:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:239:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:250:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:259:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:267:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:26:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:282:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:314:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:322:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:330:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:345:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:459:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/shell.rs:98:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:103:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:247:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:261:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:273:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:291:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:307:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:31:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:37:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:39:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:47:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:50:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:52:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:63:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:74:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:83:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:128:50 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:162:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:166:19 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:167:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:171:19 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:172:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:178:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:187:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:187:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:18:74 clippy::default_trait_access "calling `std::sync::Mutex::default()` is more clear than this expression" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:195:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:207:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:213:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:217:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:225:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:228:16 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:236:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:241:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:252:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:257:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:262:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:305:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:310:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:318:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:326:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:338:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:355:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:393:61 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:394:42 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:395:42 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:397:71 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:397:71 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:398:47 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:398:47 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:399:47 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:399:47 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:401:63 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:401:63 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:401:63 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:402:43 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:402:43 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:402:43 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:403:43 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:403:43 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:403:43 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:406:21 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:412:41 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:413:36 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:414:36 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:420:47 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:420:47 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:512:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:513:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:517:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:518:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:525:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:526:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:530:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:531:17 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:535:33 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:536:37 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:537:42 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:538:38 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:548:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:597:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:103:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:123:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:150:1 clippy::too_many_lines "this function has too many lines (141/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:158:9 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:181:21 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:192:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:258:32 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:281:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:303:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:321:51 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:344:5 clippy::doc_markdown "you should put `FeatureValue` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:350:85 clippy::doc_markdown "you should put `FeatureValue` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:36:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:378:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:386:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:387:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:407:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:69:34 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:75:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:78:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:81:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:84:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:87:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:90:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:93:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:96:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:99:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:1056:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:113:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:1157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:128:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:159:16 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:197:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:225:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:225:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:255:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:267:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:317:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:329:37 clippy::doc_markdown "you should put `VirtualManifest` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:410:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:440:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:511:32 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:561:25 clippy::non_ascii_literal "literal non-ASCII character detected" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:613:13 clippy::filter_map "called `filter_map(..).map(..)` on an `Iterator`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:615:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:762:27 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:784:17 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:849:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:849:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:893:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:906:24 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:932:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `crossbeam-utils`: 0.6.6, 0.7.2" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_clean.rs:205:23 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_clean.rs:27:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_clean.rs:27:1 clippy::too_many_lines "this function has too many lines (120/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:1078:14 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:109:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:119:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:1227:17 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:127:35 clippy::from_iter_instead_of_collect "usage of `FromIterator::from_iter`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:173:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:205:36 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:242:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:249:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:258:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:267:16 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::too_many_lines "this function has too many lines (219/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:468:9 clippy::default_trait_access "calling `std::collections::HashMap::default()` is more clear than this expression" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:548:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:556:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:574:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:583:21 clippy::doc_markdown "you should put `CompileFilter` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:584:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:584:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:592:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:593:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:607:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:612:21 clippy::doc_markdown "you should put `CompileFilter` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:613:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:618:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:641:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:652:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:655:50 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:673:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:692:49 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:703:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:729:1 clippy::too_many_lines "this function has too many lines (205/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:82:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:874:69 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_doc.rs:20:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_fetch.rs:15:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_fetch.rs:27:46 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:160:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:175:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:22:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::too_many_lines "this function has too many lines (171/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:13:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:148:1 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:148:1 clippy::too_many_lines "this function has too many lines (316/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:178:24 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:202:17 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:236:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:312:64 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:32:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:339:12 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:454:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:483:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:683:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:708:5 clippy::manual_flatten "unnecessary `if let` since only the `Some` variant of the iterator element is used" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:101:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:245:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:251:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:367:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:405:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:489:5 clippy::doc_markdown "you should put `IgnoreList` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:525:47 clippy::doc_markdown "you should put `IgnoreList` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:525:9 clippy::doc_markdown "you should put `format_existing` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:572:34 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:623:1 clippy::too_many_lines "this function has too many lines (130/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:781:5 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:800:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:163:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:27:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:45:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:144:1 clippy::too_many_lines "this function has too many lines (112/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:207:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:25:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:307:54 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:394:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:425:61 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:459:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:66:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:69:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:93:20 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_pkgid.rs:5:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:14:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:171:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:57:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:69:37 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:25:24 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:35:9 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:37:16 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:53:9 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:65:16 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:82:23 clippy::implicit_clone "implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:9:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_test.rs:16:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_test.rs:43:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_test.rs:84:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_uninstall.rs:14:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_uninstall.rs:7:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:147:9 clippy::doc_markdown "you should put `PackageId` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:233:21 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:244:22 clippy::doc_markdown "you should put `PackageId` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:244:63 clippy::doc_markdown "you should put `PackageId` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:253:17 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:370:5 clippy::unnecessary_wraps "this function's return value is unnecessary" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:505:8 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:525:10 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:542:27 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:542:5 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:561:20 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:613:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:645:41 clippy::doc_markdown "you should put `BTreeSet` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:92:19 clippy::doc_markdown "you should put `InstallTracker` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:200:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:200:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:424:20 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:455:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:506:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:608:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:619:48 clippy::manual_strip "stripping a prefix manually" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:66:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:66:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:708:18 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:77:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:154:13 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:217:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:30:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:35:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:35:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:87:1 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:8:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:8:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:150:21 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:188:1 clippy::too_many_lines "this function has too many lines (130/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:212:32 clippy::if_not_else "unnecessary `!=` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:222:53 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:224:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:31:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:346:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:346:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:351:26 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:385:12 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:386:15 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:38:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:477:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:483:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:503:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:505:38 clippy::default_trait_access "calling `util::config::CargoHttpConfig::default()` is more clear than this expression" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:510:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:529:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:53:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:53:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:573:22 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:608:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:621:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:671:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:671:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:674:10 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:678:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:730:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:731:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:785:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:794:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:828:14 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:848:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::too_many_lines "this function has too many lines (137/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:241:28 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:28:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:384:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:417:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:589:9 clippy::shadow_unrelated "`keep` is being shadowed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:58:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:58:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:602:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:75:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/resolve.rs:75:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/graph.rs:129:26 clippy::doc_markdown "you should put `PackageIds` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/graph.rs:152:15 clippy::match_on_vec_items "indexing into a vector may panic" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/graph.rs:173:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/graph.rs:234:46 clippy::filter_map "called `filter(..).flat_map(..)` on an `Iterator`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/graph.rs:328:44 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/graph.rs:330:50 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/graph.rs:563:35 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:112:11 clippy::non_ascii_literal "literal non-ASCII character detected" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:113:10 clippy::non_ascii_literal "literal non-ASCII character detected" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:114:10 clippy::non_ascii_literal "literal non-ASCII character detected" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:115:12 clippy::non_ascii_literal "literal non-ASCII character detected" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:126:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:21:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:21:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:360:30 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/tree/mod.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:14:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:215:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:21:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:21:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:314:34 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:320:29 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:320:60 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:324:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:70:1 clippy::too_many_lines "this function has too many lines (175/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:102:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:111:28 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:133:48 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:135:67 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:206:36 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:282:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:70:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:81:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:97:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/directory.rs:14:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/directory.rs:90:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:25:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:69:20 clippy::comparison_to_empty "comparison to empty slice" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:1025:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:1157:36 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:1158:9 clippy::manual_strip "stripping a suffix manually" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:176:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:180:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:184:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:188:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:242:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:253:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:262:13 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:289:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:294:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:308:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:472:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:489:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:503:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:528:28 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:537:21 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:588:1 clippy::too_many_lines "this function has too many lines (135/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:692:9 clippy::vec_init_then_push "calls to `push` immediately after creation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:758:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:858:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:129:44 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:143:44 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:282:50 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:313:21 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:314:21 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:319:21 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:339:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:339:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:380:9 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:419:50 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:429:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:460:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:473:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:482:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:63:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:98:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:117:23 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:121:70 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:167:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:215:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:324:23 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:468:40 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:590:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:648:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:736:1 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:95:37 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/local.rs:12:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:192:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:203:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:229:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:372:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:373:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:375:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:381:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:382:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:383:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:384:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:452:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:582:20 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/mod.rs:621:9 clippy::if_not_else "unnecessary `!=` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/remote.rs:139:17 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/remote.rs:32:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/remote.rs:72:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/replaced.rs:12:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/replaced.rs:5:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/canonical_url.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/canonical_url.rs:19:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/canonical_url.rs:50:41 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/canonical_url.rs:65:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:218:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:222:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:234:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:249:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:264:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:279:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:320:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:328:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:352:13 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:363:13 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:378:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:387:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:387:5 clippy::too_many_lines "this function has too many lines (104/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:39:20 clippy::doc_markdown "you should put `arg_package_spec` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:504:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:516:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:530:40 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:531:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:536:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:556:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:575:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:580:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:631:18 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:638:18 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:647:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:651:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:662:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:665:51 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/de.rs:420:16 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/de.rs:46:25 clippy::doc_markdown "you should put `CV::List` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/de.rs:47:24 clippy::doc_markdown "you should put `ConfigSeqAccess` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/de.rs:527:53 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/de.rs:530:53 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/de.rs:532:68 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/key.rs:11:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/key.rs:69:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:100:71 clippy::doc_markdown "you should put `OptValue` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:100:71 clippy::doc_markdown "you should put `OptValue` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:100:71 clippy::doc_markdown "you should put `OptValue` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1049:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1064:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1090:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1166:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1181:33 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1184:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1186:33 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1189:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1191:33 clippy::needless_question_mark "question mark operator is useless here" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1203:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1211:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1216:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1225:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1229:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:124:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1254:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1279:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1281:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1323:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1339:39 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1344:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1420:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1553:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1560:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1567:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1574:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1581:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1588:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1598:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1619:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1623:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1623:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1623:64 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1649:9 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1699:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1730:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1757:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1770:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1778:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1804:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1896:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:1901:5 clippy::doc_markdown "you should put `StringList` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:214:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:259:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:298:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:311:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:318:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:353:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:401:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:411:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:419:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:431:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:449:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:454:16 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:547:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:556:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:582:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:595:20 clippy::doc_markdown "you should put `StringList` between ticks in the documentation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:689:20 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:816:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/path.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/path.rs:14:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/path.rs:48:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/target.rs:12:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/target.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/value.rs:29:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/value.rs:70:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/value.rs:80:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/value.rs:81:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:11:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:22:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:82:25 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:82:9 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:109:27 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:168:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:46:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:91:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/diagnostic_server.rs:218:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/diagnostic_server.rs:230:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/diagnostic_server.rs:242:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/diagnostic_server.rs:58:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/diagnostic_server.rs:96:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/diagnostic_server.rs:96:5 clippy::too_many_lines "this function has too many lines (110/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/diagnostic_server.rs:99:21 clippy::shadow_unrelated "`msg` is being shadowed" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:101:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:150:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:15:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:237:5 clippy::pub_enum_variant_names "variant name ends with the enum's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:245:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:321:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:328:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:356:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:391:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:392:13 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:465:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:473:5 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/errors.rs:66:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:115:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:11:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:134:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:170:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:192:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:29:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:321:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:335:23 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:335:23 clippy::cast_sign_loss "casting `i64` to `u32` may lose the sign of the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:335:44 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:379:35 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:37:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:96:17 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/graph.rs:10:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/graph.rs:41:51 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/graph.rs:45:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hasher.rs:12:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hasher.rs:9:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:10:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:11:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:12:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:13:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:14:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:15:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:25:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:6:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:6:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:8:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hex.rs:9:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/important_paths.rs:23:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/important_paths.rs:6:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/interning.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/into_url.rs:10:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/into_url_with_base.rs:9:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/job.rs:20:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/lev_distance.rs:3:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/lockserver.rs:111:32 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/lockserver.rs:158:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/lockserver.rs:46:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/lockserver.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/lockserver.rs:62:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/mod.rs:68:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/mod.rs:79:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/network.rs:12:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/network.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/network.rs:84:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:109:12 clippy::redundant_else "redundant else block" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:114:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:121:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:125:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:130:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:14:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:151:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:167:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:173:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:178:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:185:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:199:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:215:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:228:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:251:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:267:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:276:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:29:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:303:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:312:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:346:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:415:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:445:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:459:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:514:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:54:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:61:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:63:19 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:88:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:93:31 clippy::comparison_to_empty "comparison to empty slice" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:106:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:111:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:122:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:132:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:152:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:185:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:190:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:218:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:218:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:278:22 clippy::inconsistent_struct_constructor "inconsistent struct constructor" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:307:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/process_builder.rs:343:39 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:122:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:136:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:249:19 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:249:34 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:250:19 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:263:22 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:264:22 clippy::cast_possible_truncation "casting `f64` to `usize` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:264:22 clippy::cast_sign_loss "casting `f64` to `usize` may lose the sign of the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:269:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:272:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:274:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:280:13 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:282:9 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:89:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/progress.rs:97:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/queue.rs:25:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/queue.rs:36:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/queue.rs:42:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/queue.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/queue.rs:69:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/read2.rs:11:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/read2.rs:31:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:13:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:26:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:35:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:45:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:89:21 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:8:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:114:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:115:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:162:17 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:39:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/sha256.rs:10:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/sha256.rs:16:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/sha256.rs:20:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/sha256.rs:31:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/sha256.rs:40:24 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/to_semver.rs:5:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1005:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1005:5 clippy::too_many_lines "this function has too many lines (282/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1094:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1121:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1197:32 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:124:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1504:9 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1526:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1582:19 clippy::default_trait_access "calling `util::toml::DetailedTomlDependency::default()` is more clear than this expression" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1598:5 clippy::too_many_lines "this function has too many lines (153/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1687:33 clippy::unnecessary_lazy_evaluations "unnecessary closure used to substitute value for `Option::None`" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:178:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:248:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:274:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:281:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:285:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:294:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:31:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:381:35 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:381:35 clippy::cast_sign_loss "casting `i64` to `u32` may lose the sign of the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:388:35 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:398:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:450:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:536:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:783:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:824:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:834:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:83:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::too_many_lines "this function has too many lines (138/100)" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:962:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:979:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:98:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:999:23 clippy::default_trait_access "calling `util::toml::DetailedTomlDependency::default()` is more clear than this expression" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:112:27 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:325:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:586:21 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:593:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:605:19 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:756:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:10:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:33:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:37:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:43:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:47:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:59:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:66:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:52:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:56:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:60:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:64:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/error.rs:24:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:105:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:119:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:133:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:143:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:149:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:167:49 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:196:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:80:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:85:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/iron.rs:90:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `iron` is missing `package.categories` metadata" +target/lintcheck/sources/iron-0.6.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `iron` is missing `package.keywords` metadata" +target/lintcheck/sources/iron-0.6.1/src/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `log`: 0.3.9, 0.4.8" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:137:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:150:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:152:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:159:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:171:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:173:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:182:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:192:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:217:25 clippy::doc_markdown "you should put `ChainBuilder` between ticks in the documentation" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:264:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:328:20 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:360:16 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:368:33 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:428:40 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:434:40 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/middleware/mod.rs:444:40 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/modifiers.rs:132:14 clippy::expect_fun_call "use of `expect` followed by a function call" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:113:24 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:121:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:123:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:124:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:126:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:128:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:153:69 clippy::doc_markdown "you should put `HttpReader` between ticks in the documentation" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:154:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:32:1 clippy::manual_non_exhaustive "this seems like a manual implementation of the non-exhaustive pattern" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:75:34 clippy::doc_markdown "you should put `HttpRequest` between ticks in the documentation" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:77:39 clippy::doc_markdown "you should put `HttpRequest` between ticks in the documentation" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:78:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:82:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:83:29 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/request/mod.rs:85:24 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:109:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:117:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:129:1 clippy::from_over_into "an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:21:14 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:22:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:31:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:47:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:52:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:57:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:63:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:63:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:73:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:73:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/request/url.rs:96:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/response.rs:121:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/iron-0.6.1/src/response.rs:125:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/iron-0.6.1/src/response.rs:139:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/iron-0.6.1/src/response.rs:24:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/iron-0.6.1/src/response.rs:95:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/iron-0.6.1/src/response.rs:95:5 clippy::new_without_default "you should consider adding a `Default` implementation for `response::Response`" +target/lintcheck/sources/libc-0.2.81/build.rs:114:19 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/libc-0.2.81/build.rs:124:5 clippy::question_mark "this block may be rewritten with the `?` operator" +target/lintcheck/sources/libc-0.2.81/build.rs:133:5 clippy::question_mark "this block may be rewritten with the `?` operator" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:428:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:429:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:431:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:432:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:433:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:434:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:595:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:596:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:597:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:622:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:673:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:696:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:697:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:698:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:699:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:712:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:721:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:722:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:723:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:751:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:752:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:753:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:754:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:755:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:756:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:757:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:758:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:759:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:760:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:768:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:769:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:771:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:772:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:773:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:774:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:775:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:776:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:777:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:778:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:779:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:780:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:781:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:782:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:783:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:784:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:785:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:786:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:787:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:788:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:789:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:790:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:791:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:792:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:794:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:795:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:796:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:797:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:798:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:799:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:800:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:801:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:803:27 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:804:28 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:805:28 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:806:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:807:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:808:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:809:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:810:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:811:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:812:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:813:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:814:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:815:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:816:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:817:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:818:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:821:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:822:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:823:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:824:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:825:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:826:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:827:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:828:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:829:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:830:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:831:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:832:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:833:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:834:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:835:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:836:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:841:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:842:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:843:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:844:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:1120:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:178:34 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:291:5 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:291:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:299:11 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:302:5 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:312:11 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:352:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:355:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:355:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:359:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:359:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:363:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:363:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:367:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:367:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:371:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:371:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:534:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:645:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:727:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:728:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:729:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:731:44 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:732:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:733:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:734:43 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:735:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:736:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:737:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:738:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:741:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:742:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:743:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:744:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:745:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:746:43 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:747:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:748:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:749:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:750:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:751:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:752:43 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:753:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:755:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:756:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:757:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:758:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:759:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:761:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:762:44 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:763:45 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:764:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:765:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:766:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:767:44 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:768:44 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:769:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:770:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:771:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:772:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:773:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:774:45 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:775:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:776:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:803:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:841:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:842:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:982:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:984:46 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1209:36 clippy::cast_possible_truncation "casting `i32` to `i16` may truncate the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1210:36 clippy::cast_possible_truncation "casting `i32` to `i16` may truncate the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1235:39 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1236:41 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1274:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1324:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1333:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1334:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1346:34 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1346:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1346:34 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1347:37 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1347:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1347:37 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1348:36 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1348:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1348:36 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1349:37 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1349:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1349:37 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1350:35 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1350:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1350:35 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1351:36 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1351:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1351:36 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1352:31 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1352:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1352:31 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1419:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1420:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1421:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1422:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1423:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1490:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1561:46 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1562:45 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1567:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1568:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1586:26 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1587:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1588:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1589:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1897:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1898:51 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1900:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1969:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1970:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1971:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1972:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1973:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1974:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1975:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1976:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1977:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1978:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1979:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1980:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1981:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1982:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1983:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1984:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1985:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1986:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1987:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1988:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1989:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1990:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1991:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1992:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1993:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1994:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1995:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1996:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1997:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1998:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:1999:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2000:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2001:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2002:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2003:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2004:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2005:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2032:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2033:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2034:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2035:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2036:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2037:28 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2038:27 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2039:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2041:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2042:28 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2043:27 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2044:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2045:27 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2046:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2048:28 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2049:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2050:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2051:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2052:26 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2053:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2318:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2321:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2331:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2487:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2488:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2489:43 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2490:43 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2491:43 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2493:47 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2494:44 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2495:46 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2496:47 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2497:49 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2498:48 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2499:50 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2500:45 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2572:9 clippy::needless_return "unneeded `return` statement" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2578:20 clippy::zero_ptr "`0 as *mut _` detected" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2588:13 clippy::zero_ptr "`0 as *mut _` detected" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2590:13 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2596:52 clippy::used_underscore_binding "used binding `_dummy` which is prefixed with an underscore. A leading underscore signals that a binding will not be used" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2597:11 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2601:21 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2611:9 clippy::unused_unit "unneeded unit expression" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2619:9 clippy::unused_unit "unneeded unit expression" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2634:9 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2647:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2648:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2649:9 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2654:18 clippy::identity_op "the operation is ineffective. Consider reducing it to `(dev & 0x00000000000000ff)`" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2654:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2655:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2656:9 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2660:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2661:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2663:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2664:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2665:16 clippy::identity_op "the operation is ineffective. Consider reducing it to `(minor & 0x000000ff)`" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2665:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2666:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:954:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1000:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1001:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1002:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1016:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1017:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1018:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1019:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1020:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1029:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1030:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1031:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1032:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1033:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1034:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1035:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1041:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1042:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1043:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1044:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1045:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1046:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1047:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1048:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1049:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1050:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1051:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1053:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1054:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1055:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1056:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1057:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1058:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1059:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1060:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1073:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1074:43 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1075:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1076:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1077:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1078:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1079:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1080:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1081:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1082:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1083:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1084:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1086:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1087:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1089:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1090:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1091:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1094:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1095:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1096:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1097:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1098:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1099:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1100:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1101:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1102:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1105:44 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1106:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1107:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1108:42 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1109:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1110:46 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1111:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1112:44 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1113:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1114:47 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1115:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1126:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1127:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1128:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1179:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1180:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1218:27 clippy::identity_op "the operation is ineffective. Consider reducing it to `IPOPT_CONTROL`" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1314:9 clippy::precedence "operator precedence can trip the unwary" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1321:13 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1323:13 clippy::zero_ptr "`0 as *mut _` detected" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1332:9 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1337:9 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1341:18 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1344:9 clippy::needless_return "unneeded `return` statement" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1348:18 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1350:9 clippy::needless_return "unneeded `return` statement" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1354:18 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1357:9 clippy::needless_return "unneeded `return` statement" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1361:21 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1381:9 clippy::cast_possible_truncation "casting `i32` to `i8` may truncate the value" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1389:9 clippy::verbose_bit_mask "bit mask could be simplified with a call to `trailing_zeros`" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:446:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:591:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:592:38 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:593:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:594:33 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:595:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:596:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:597:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:598:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:599:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:600:34 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:601:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:602:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:607:37 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:608:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:764:35 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:765:39 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:991:30 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:198:29 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:199:28 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:201:35 clippy::unnecessary_cast "casting integer literal to `usize` is unnecessary" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:202:35 clippy::unnecessary_cast "casting integer literal to `usize` is unnecessary" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:282:40 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:284:41 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:285:36 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:34:10 clippy::upper_case_acronyms "name `DIR` contains a capitalized acronym" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:386:10 clippy::upper_case_acronyms "name `FILE` contains a capitalized acronym" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1047:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1053:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1059:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1093:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1093:5 clippy::new_without_default "you should consider adding a `Default` implementation for `MetadataBuilder<'a>`" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1118:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1177:1 clippy::inline_always "you have declared `#[inline(always)]` on `max_level`. This is usually a bad idea" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1178:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1306:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1358:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1359:5 clippy::if_not_else "unnecessary `!=` operation" +target/lintcheck/sources/log-0.4.11/src/lib.rs:1407:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:356:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/log-0.4.11/src/lib.rs:448:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/log-0.4.11/src/lib.rs:500:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:506:28 clippy::trivially_copy_pass_by_ref "this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/log-0.4.11/src/lib.rs:506:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/log-0.4.11/src/lib.rs:506:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:538:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/log-0.4.11/src/lib.rs:653:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:661:21 clippy::trivially_copy_pass_by_ref "this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/log-0.4.11/src/lib.rs:661:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:677:44 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/log-0.4.11/src/lib.rs:758:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:764:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:770:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:776:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:782:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:788:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:794:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:803:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:809:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:818:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:908:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/log-0.4.11/src/lib.rs:908:5 clippy::new_without_default "you should consider adding a `Default` implementation for `RecordBuilder<'a>`" +target/lintcheck/sources/log-0.4.11/src/lib.rs:995:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/detection.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:108:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:269:20 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:430:24 clippy::trivially_copy_pass_by_ref "this argument (0 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:437:23 clippy::trivially_copy_pass_by_ref "this argument (0 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:437:23 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:471:17 clippy::trivially_copy_pass_by_ref "this argument (0 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:471:17 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:654:5 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:655:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:661:5 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:662:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:664:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:674:37 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:678:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:85:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/proc-macro2-1.0.24/src/fallback.rs:882:43 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1017:9 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1081:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1099:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1117:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1135:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1141:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1146:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:1156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:152:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:373:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:383:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:397:24 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:397:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:403:23 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:403:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:418:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:425:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:464:17 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:500:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:626:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:633:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:641:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:652:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:662:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:672:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:734:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:743:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:752:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:757:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:788:19 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:788:69 clippy::doc_markdown "you should put `XID_Continue` between ticks in the documentation" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:891:36 clippy::doc_markdown "you should put `syn::parse_str` between ticks in the documentation" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:894:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:911:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/lib.rs:996:9 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:552:5 clippy::while_let_on_iterator "this loop could be written as a `for` loop" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:584:21 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:602:20 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:696:29 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:702:34 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:708:34 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:793:5 clippy::vec_init_then_push "calls to `push` immediately after creation" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:803:15 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" +target/lintcheck/sources/proc-macro2-1.0.24/src/parse.rs:808:15 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" +target/lintcheck/sources/proc-macro2-1.0.24/src/wrapper.rs:415:24 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/wrapper.rs:429:23 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/proc-macro2-1.0.24/src/wrapper.rs:492:17 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:158:15 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:175:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:183:5 clippy::too_many_lines "this function has too many lines (115/100)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:207:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:271:67 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:376:29 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:381:44 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:453:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:540:14 clippy::cast_possible_truncation "casting `f64` to `f32` may truncate the value" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:551:5 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:584:39 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:59:26 clippy::unsafe_derive_deserialize "you are deriving `serde::Deserialize` on a type that has methods using `unsafe`" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:61:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:627:39 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:674:47 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin-imgui/src/ui.rs:690:9 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/data.rs:102:25 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/data.rs:112:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/data.rs:116:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/data.rs:137:24 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/data.rs:177:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/data.rs:211:21 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/data.rs:24:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:147:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:147:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:165:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:200:21 clippy::default_trait_access "calling `Stream::default()` is more clear than this expression" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:257:78 clippy::default_trait_access "calling `std::cell::RefCell::default()` is more clear than this expression" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:297:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:308:28 clippy::default_trait_access "calling `FullProfileData::default()` is more clear than this expression" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:316:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:321:5 clippy::cast_possible_truncation "casting `u128` to `i64` may truncate the value" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:348:28 clippy::default_trait_access "calling `std::marker::PhantomData::default()` is more clear than this expression" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:359:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:375:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:376:5 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:377:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:406:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:408:5 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:69:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:73:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/lib.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:21:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:28:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:28:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:35:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:35:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:64:43 clippy::default_trait_access "calling `std::vec::Vec::default()` is more clear than this expression" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:65:54 clippy::default_trait_access "calling `std::collections::HashMap::default()` is more clear than this expression" +target/lintcheck/sources/puffin-02dd4a3/puffin/src/merge.rs:9:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/quote-1.0.7/src/ext.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/quote-1.0.7/src/ext.rs:7:5 clippy::doc_markdown "you should put `TokenStream` between ticks in the documentation" +target/lintcheck/sources/quote-1.0.7/src/ident_fragment.rs:13:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/quote-1.0.7/src/ident_fragment.rs:51:31 clippy::manual_strip "stripping a prefix manually" +target/lintcheck/sources/quote-1.0.7/src/runtime.rs:52:5 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/quote-1.0.7/src/runtime.rs:63:5 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/quote-1.0.7/src/runtime.rs:66:33 clippy::doc_markdown "you should put `DoesNotHaveIter` between ticks in the documentation" +target/lintcheck/sources/quote-1.0.7/src/runtime.rs:80:5 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:103:20 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:103:20 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:116:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:123:21 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:123:21 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:63:26 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:63:27 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:67:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:95:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/distributions/bernoulli.rs:96:13 clippy::manual_range_contains "manual `Range::contains` implementation" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:107:23 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:112:44 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:116:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:150:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:153:24 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:158:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:164:33 clippy::cast_sign_loss "casting `i64` to `u64` may lose the sign of the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:166:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:175:47 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:185:38 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:194:38 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:202:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:209:25 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:221:26 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:222:26 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:223:25 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:224:25 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:226:17 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:233:32 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:234:27 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:251:22 clippy::cast_sign_loss "casting `i64` to `u64` may lose the sign of the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:255:9 clippy::if_not_else "unnecessary `!=` operation" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:45:17 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:46:5 clippy::cast_possible_truncation "casting `f64` to `i64` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:50:5 clippy::too_many_lines "this function has too many lines (143/100)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:76:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:78:12 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:81:21 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:82:32 clippy::cast_possible_truncation "casting `u64` to `i32` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:88:26 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/binomial.rs:99:21 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/distributions/cauchy.rs:33:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/dirichlet.rs:52:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/dirichlet.rs:64:32 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" +target/lintcheck/sources/rand-0.7.3/src/distributions/dirichlet.rs:65:23 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" +target/lintcheck/sources/rand-0.7.3/src/distributions/exponential.rs:76:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/float.rs:73:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/gamma.rs:13:5 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/rand-0.7.3/src/distributions/gamma.rs:14:5 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/rand-0.7.3/src/distributions/gamma.rs:189:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/gamma.rs:230:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/gamma.rs:259:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/gamma.rs:287:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/gamma.rs:90:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/integer.rs:23:9 clippy::cast_possible_truncation "casting `u32` to `u8` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/integer.rs:30:9 clippy::cast_possible_truncation "casting `u32` to `u16` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/integer.rs:69:9 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/rand-0.7.3/src/distributions/mod.rs:263:5 clippy::inline_always "you have declared `#[inline(always)]` on `next`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/normal.rs:100:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/normal.rs:119:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/normal.rs:131:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/normal.rs:31:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/normal.rs:47:25 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" +target/lintcheck/sources/rand-0.7.3/src/distributions/normal.rs:48:25 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore" +target/lintcheck/sources/rand-0.7.3/src/distributions/other.rs:89:9 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/pareto.rs:32:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/poisson.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/poisson.rs:87:30 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/poisson.rs:87:30 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/triangular.rs:32:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:146:4 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:199:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:214:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:283:14 clippy::doc_markdown "you should put `SampleUniform` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:283:46 clippy::doc_markdown "you should put `SampleUniform` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:296:5 clippy::inline_always "you have declared `#[inline(always)]` on `borrow`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:304:5 clippy::inline_always "you have declared `#[inline(always)]` on `borrow`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:350:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:407:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:441:31 clippy::invalid_upcast_comparisons "because of the numeric bounds on `::core::u16::MAX` prior to casting, this expression is always false" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:56:10 clippy::doc_markdown "you should put `SampleBorrow` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:647:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:840:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:913:13 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" +target/lintcheck/sources/rand-0.7.3/src/distributions/uniform.rs:943:54 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/distributions/unit_circle.rs:30:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/unit_sphere.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/unit_sphere.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:247:15 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:248:20 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:249:18 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:254:5 clippy::inline_always "you have declared `#[inline(always)]` on `lanes`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:258:5 clippy::inline_always "you have declared `#[inline(always)]` on `splat`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:262:5 clippy::inline_always "you have declared `#[inline(always)]` on `extract`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:267:5 clippy::inline_always "you have declared `#[inline(always)]` on `replace`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:281:5 clippy::inline_always "you have declared `#[inline(always)]` on `any`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:286:5 clippy::inline_always "you have declared `#[inline(always)]` on `all`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:291:5 clippy::inline_always "you have declared `#[inline(always)]` on `none`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:488:17 clippy::doc_markdown "you should put `x_i` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:489:50 clippy::doc_markdown "you should put `x_i` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:489:63 clippy::doc_markdown "you should put `f(x_i` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:490:40 clippy::doc_markdown "you should put `f(x_i` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:490:49 clippy::doc_markdown "you should put `f(x_{i+1` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/distributions/utils.rs:518:17 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/rand-0.7.3/src/distributions/weibull.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:113:21 clippy::explicit_iter_loop "it is more concise to loop over references to containers instead of using explicit iteration methods" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:125:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:131:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:180:36 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:182:34 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:259:28 clippy::clone_on_copy "using `clone` on type `distributions::uniform::Uniform` which implements the `Copy` trait" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:296:9 clippy::map_clone "you are using an explicit closure for copying elements" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:321:9 clippy::map_clone "you are using an explicit closure for copying elements" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::too_many_lines "this function has too many lines (106/100)" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:85:17 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/alias_method.rs:87:31 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/mod.rs:100:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/mod.rs:144:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/mod.rs:144:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/mod.rs:169:16 clippy::int_plus_one "unnecessary `>= y + 1` or `x - 1 >=`" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/mod.rs:386:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/distributions/weighted/mod.rs:85:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/lib.rs:333:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/lib.rs:404:14 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" +target/lintcheck/sources/rand-0.7.3/src/lib.rs:552:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/read.rs:47:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/read.rs:89:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:100:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:112:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:117:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:198:13 clippy::cast_possible_wrap "casting `u64` to `i64` may wrap around the value" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:231:9 clippy::cast_possible_wrap "casting `usize` to `isize` may wrap around the value" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:249:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:27:28 clippy::doc_markdown "you should put `ChaCha` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/rngs/adapter/reseeding.rs:79:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/rngs/entropy.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/rngs/entropy.rs:34:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/rngs/mock.rs:36:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/rngs/mock.rs:47:9 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/rand-0.7.3/src/rngs/mod.rs:61:74 clippy::doc_markdown "you should put `ChaCha20` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:25:39 clippy::doc_markdown "you should put `ChaCha` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:32:10 clippy::doc_markdown "you should put `rand_chacha` between ticks in the documentation" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:36:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:39:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:44:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:49:5 clippy::inline_always "you have declared `#[inline(always)]` on `fill_bytes`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:54:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:63:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/std.rs:68:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:57:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:80:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:80:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:80:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:81:35 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:93:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:98:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:127:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:139:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:159:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:171:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:180:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:223:18 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:224:18 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:233:25 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:236:27 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:244:12 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:244:37 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:29:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:39:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:48:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:60:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:69:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:78:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:87:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:87:5 clippy::should_implement_trait "method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`" +target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:97:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/rand-0.7.3/src/seq/mod.rs:141:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/seq/mod.rs:168:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand-0.7.3/src/seq/mod.rs:229:4 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rand-0.7.3/src/seq/mod.rs:292:29 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/rand-0.7.3/src/seq/mod.rs:410:23 clippy::default_trait_access "calling `std::marker::PhantomData::default()` is more clear than this expression" +target/lintcheck/sources/rand-0.7.3/src/seq/mod.rs:45:4 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rand-0.7.3/src/seq/mod.rs:527:26 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:117:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:153:5 clippy::inline_always "you have declared `#[inline(always)]` on `index`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:230:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:240:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:245:5 clippy::inline_always "you have declared `#[inline(always)]` on `seed_from_u64`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:250:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:280:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:319:5 clippy::inline_always "you have declared `#[inline(always)]` on `index`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:405:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:415:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:420:5 clippy::inline_always "you have declared `#[inline(always)]` on `seed_from_u64`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:425:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:67:14 clippy::doc_markdown "you should put `module][crate::block` between ticks in the documentation" +target/lintcheck/sources/rand_core-0.6.0/src/block.rs:68:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rand_core-0.6.0/src/error.rs:106:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand_core-0.6.0/src/error.rs:87:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand_core-0.6.0/src/error.rs:95:74 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:301:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:303:26 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:304:26 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:313:30 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:314:23 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:346:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:381:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:386:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:391:5 clippy::inline_always "you have declared `#[inline(always)]` on `fill_bytes`. This is usually a bad idea" +target/lintcheck/sources/rand_core-0.6.0/src/lib.rs:396:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea" +target/lintcheck/sources/rayon-1.5.0/src/collections/binary_heap.rs:7:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/binary_heap.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/btree_map.rs:7:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/btree_map.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/btree_set.rs:7:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/btree_set.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/hash_map.rs:10:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/hash_map.rs:9:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/hash_set.rs:10:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/hash_set.rs:9:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/linked_list.rs:7:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/linked_list.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/mod.rs:59:32 clippy::mem_replace_with_default "replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`" +target/lintcheck/sources/rayon-1.5.0/src/collections/vec_deque.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/collections/vec_deque.rs:9:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/compile_fail/cannot_collect_filtermap_data.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rayon-1.5.0/src/compile_fail/cannot_zip_filtered_data.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rayon-1.5.0/src/compile_fail/cell_par_iter.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rayon-1.5.0/src/compile_fail/no_send_par_iter.rs:25:1 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rayon-1.5.0/src/compile_fail/no_send_par_iter.rs:46:1 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rayon-1.5.0/src/compile_fail/no_send_par_iter.rs:4:1 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rayon-1.5.0/src/compile_fail/rc_par_iter.rs:2:1 clippy::needless_doctest_main "needless `fn main` in doctest" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:103:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:122:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:128:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:221:36 clippy::doc_markdown "you should put `ExactSizeIterator` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:51:38 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:58:14 clippy::shadow_unrelated "`a` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:58:17 clippy::shadow_unrelated "`b` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:78:14 clippy::shadow_unrelated "`a` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:78:17 clippy::shadow_unrelated "`b` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/iter/chain.rs:97:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/chunks.rs:29:9 clippy::inconsistent_struct_constructor "inconsistent struct constructor" +target/lintcheck/sources/rayon-1.5.0/src/iter/chunks.rs:3:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/chunks.rs:4:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/chunks.rs:77:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/chunks.rs:83:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/cloned.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/cloned.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/cloned.rs:71:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/cloned.rs:75:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/collect/consumer.rs:141:5 clippy::doc_markdown "you should put `CollectReducer` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/collect/consumer.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/collect/consumer.rs:28:5 clippy::doc_markdown "you should put `CollectResult` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/collect/consumer.rs:36:37 clippy::mut_mut "generally you want to avoid `&mut &mut _` if possible" +target/lintcheck/sources/rayon-1.5.0/src/iter/collect/consumer.rs:36:37 clippy::mut_mut "generally you want to avoid `&mut &mut _` if possible" +target/lintcheck/sources/rayon-1.5.0/src/iter/collect/mod.rs:154:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/rayon-1.5.0/src/iter/copied.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/copied.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/copied.rs:71:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/copied.rs:75:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/empty.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/empty.rs:24:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/rayon-1.5.0/src/iter/empty.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/enumerate.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/enumerate.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/enumerate.rs:64:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/enumerate.rs:68:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:143:63 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:182:57 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:218:32 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:218:59 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:25:42 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:287:62 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:322:56 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:41:27 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:47:30 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:47:56 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:47:74 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:53:29 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:57:36 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/extend.rs:59:61 clippy::linkedlist "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?" +target/lintcheck/sources/rayon-1.5.0/src/iter/filter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/filter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/filter_map.rs:123:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/rayon-1.5.0/src/iter/filter_map.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/filter_map.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/find.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/find.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/find_first_last/mod.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/find_first_last/mod.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/find_first_last/mod.rs:32:67 clippy::doc_markdown "you should put `MatchPosition` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/flat_map.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/flat_map.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/flat_map_iter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/flat_map_iter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/flatten.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/flatten.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/flatten_iter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/flatten_iter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/fold.rs:158:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/rayon-1.5.0/src/iter/fold.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/fold.rs:204:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rayon-1.5.0/src/iter/fold.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/for_each.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/for_each.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/inspect.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/inspect.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/inspect.rs:83:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/inspect.rs:88:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:111:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:119:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:195:30 clippy::doc_markdown "you should put `self.i_len` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:195:43 clippy::doc_markdown "you should put `self.j_len` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:199:23 clippy::doc_markdown "you should put `self.i_len` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:200:23 clippy::doc_markdown "you should put `self.j_len` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:249:41 clippy::doc_markdown "you should put `DoubleEndedIterator` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:250:5 clippy::doc_markdown "you should put `ExactSizeIterator` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:263:33 clippy::doc_markdown "you should put `InterleaveSeq` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:280:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:285:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:313:9 clippy::comparison_chain "`if` chain can be rewritten with `match`" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:82:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave.rs:90:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/interleave_shortest.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/intersperse.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/intersperse.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/intersperse.rs:90:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/intersperse.rs:96:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:12:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:146:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:200:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:205:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:66:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/len.rs:71:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/map.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/map.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/map.rs:84:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/map.rs:89:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/map_with.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/map_with.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/map_with.rs:419:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/map_with.rs:425:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/map_with.rs:90:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/map_with.rs:96:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/mod.rs:1874:24 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/rayon-1.5.0/src/iter/mod.rs:2171:1 clippy::len_without_is_empty "trait `IndexedParallelIterator` has a `len` method but no (possibly inherited) `is_empty` method" +target/lintcheck/sources/rayon-1.5.0/src/iter/mod.rs:2371:26 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/rayon-1.5.0/src/iter/mod.rs:2411:26 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/rayon-1.5.0/src/iter/mod.rs:82:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/multizip.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/multizip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/noop.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/once.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/once.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/panic_fuse.rs:102:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/panic_fuse.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/panic_fuse.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/panic_fuse.rs:98:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/par_bridge.rs:136:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/rayon-1.5.0/src/iter/par_bridge.rs:163:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:216:58 clippy::doc_markdown "you should put `find_first` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:359:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:364:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:399:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:53:19 clippy::doc_markdown "you should put `DoubleEndedIterator` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:53:43 clippy::doc_markdown "you should put `ExactSizeIterator` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:54:31 clippy::doc_markdown "you should put `IntoIterator` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/plumbing/mod.rs:55:5 clippy::doc_markdown "you should put `IntoIterator` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/iter/positions.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/positions.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/product.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/reduce.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/repeat.rs:103:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rayon-1.5.0/src/iter/repeat.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/repeat.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/rev.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/rev.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/rev.rs:63:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/rev.rs:68:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/skip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/skip.rs:3:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/skip.rs:68:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/skip.rs:73:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/splitter.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/splitter.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/step_by.rs:4:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/step_by.rs:5:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/step_by.rs:73:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/step_by.rs:79:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/sum.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/take.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/take.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/take.rs:67:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/take.rs:72:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/try_fold.rs:190:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rayon-1.5.0/src/iter/try_fold.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/try_fold.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/try_reduce.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/try_reduce_with.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/unzip.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/unzip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/update.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/update.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/update.rs:82:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/update.rs:87:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/while_some.rs:130:22 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/rayon-1.5.0/src/iter/while_some.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/while_some.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip.rs:102:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip.rs:74:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip.rs:79:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip.rs:97:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip_eq.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/iter/zip_eq.rs:2:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/option.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/option.rs:9:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/par_either.rs:1:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/par_either.rs:3:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/private.rs:9:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/rayon-1.5.0/src/range.rs:19:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/range.rs:20:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:194:9 clippy::range_plus_one "an inclusive range would be more readable" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:194:9 clippy::range_plus_one "an inclusive range would be more readable" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:19:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:209:9 clippy::range_plus_one "an inclusive range would be more readable" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:209:9 clippy::range_plus_one "an inclusive range would be more readable" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:20:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:231:9 clippy::range_plus_one "an inclusive range would be more readable" +target/lintcheck/sources/rayon-1.5.0/src/range_inclusive.rs:231:9 clippy::range_plus_one "an inclusive range would be more readable" +target/lintcheck/sources/rayon-1.5.0/src/result.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/result.rs:9:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:102:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:109:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:114:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:211:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:217:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:251:5 clippy::doc_markdown "you should put `TimSort` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:252:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:286:59 clippy::doc_markdown "you should put `TimSort` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:333:24 clippy::redundant_else "redundant else block" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:513:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:521:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:7:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/slice/mergesort.rs:98:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/mod.rs:15:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/slice/mod.rs:16:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/slice/mod.rs:17:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/slice/mod.rs:25:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/rayon-1.5.0/src/slice/mod.rs:657:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rayon-1.5.0/src/slice/mod.rs:971:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:230:36 clippy::doc_markdown "you should put `BlockQuicksort` between ticks in the documentation" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:233:1 clippy::too_many_lines "this function has too many lines (117/100)" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:258:26 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:265:26 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:268:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:308:30 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:325:30 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:393:36 clippy::cast_possible_wrap "casting `u8` to `isize` may wrap around the value on targets with 32-bit wide pointers" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:405:40 clippy::cast_possible_wrap "casting `u8` to `isize` may wrap around the value on targets with 32-bit wide pointers" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:430:14 clippy::shadow_unrelated "`pivot` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:439:13 clippy::shadow_unrelated "`pivot` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:482:10 clippy::shadow_unrelated "`pivot` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:491:9 clippy::shadow_unrelated "`pivot` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:534:26 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:545:17 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:588:17 clippy::identity_op "the operation is ineffective. Consider reducing it to `len / 4`" +target/lintcheck/sources/rayon-1.5.0/src/slice/quicksort.rs:716:14 clippy::shadow_unrelated "`pivot` is being shadowed" +target/lintcheck/sources/rayon-1.5.0/src/split_producer.rs:56:16 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else" +target/lintcheck/sources/rayon-1.5.0/src/split_producer.rs:92:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else" +target/lintcheck/sources/rayon-1.5.0/src/str.rs:16:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/str.rs:17:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/str.rs:18:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/str.rs:25:5 clippy::cast_possible_wrap "casting `u8` to `i8` may wrap around the value" +target/lintcheck/sources/rayon-1.5.0/src/str.rs:715:9 clippy::manual_strip "stripping a suffix manually" +target/lintcheck/sources/rayon-1.5.0/src/string.rs:5:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/vec.rs:137:12 clippy::len_zero "length comparison to zero" +target/lintcheck/sources/rayon-1.5.0/src/vec.rs:8:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/rayon-1.5.0/src/vec.rs:9:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:100:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:133:17 clippy::same_item_push "it looks like the same item is being pushed into this Vec" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:145:20 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:199:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:223:29 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:230:66 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:284:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:287:5 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:97:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:98:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/backtrack.rs:99:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1005:32 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1006:21 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1008:18 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1009:18 clippy::cast_lossless "casting `u8` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1010:9 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:102:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1037:37 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1037:55 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1040:28 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1040:38 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1051:25 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:1071:8 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:112:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:154:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:156:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:185:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:187:40 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:201:53 clippy::doc_markdown "you should put `MaybeInsts` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:241:63 clippy::doc_markdown "you should put `c_concat` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:245:5 clippy::too_many_lines "this function has too many lines (111/100)" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:247:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:373:24 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:373:36 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:378:12 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:400:37 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:407:51 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:409:24 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:417:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:42:5 clippy::new_without_default "you should consider adding a `Default` implementation for `compile::Compiler`" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:444:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:445:57 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:446:20 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:466:20 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:466:32 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:519:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:55:57 clippy::doc_markdown "you should put `size_limit` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:748:41 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:74:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:751:54 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:765:41 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:765:55 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:825:39 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:825:51 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:828:49 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:828:61 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:830:59 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:830:71 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:832:43 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:835:41 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:835:53 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:835:67 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:896:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:905:17 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:953:17 clippy::doc_markdown "you should put `HashMap` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:95:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:980:26 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:994:44 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:994:54 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1007:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1010:22 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1059:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1060:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1084:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1087:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1090:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1093:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1096:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1101:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1104:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1107:38 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1117:30 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1120:47 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1121:30 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1129:13 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1134:13 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1185:68 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1193:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1244:50 clippy::doc_markdown "you should put `current_state` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1338:58 clippy::doc_markdown "you should put `STATE_DEAD` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1339:9 clippy::doc_markdown "you should put `STATE_UNKNOWN` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1366:25 clippy::doc_markdown "you should put `STATE_DEAD` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1366:46 clippy::doc_markdown "you should put `STATE_UNKNOWN` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1367:41 clippy::inline_always "you have declared `#[inline(always)]` on `start_state`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1380:14 clippy::identity_op "the operation is ineffective. Consider reducing it to `(empty_flags.start as u8)`" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1388:15 clippy::match_on_vec_items "indexing into a vector may panic" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1412:20 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1438:9 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1472:9 clippy::doc_markdown "you should put `StatePtr` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1490:54 clippy::cast_possible_truncation "casting `i32` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1490:54 clippy::cast_sign_loss "casting `i32` to `u8` may lose the sign of the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1521:20 clippy::doc_markdown "you should put `num_byte_classes` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1529:41 clippy::inline_always "you have declared `#[inline(always)]` on `byte_class`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1537:14 clippy::doc_markdown "you should put `byte_class` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1538:41 clippy::inline_always "you have declared `#[inline(always)]` on `u8_class`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1562:18 clippy::doc_markdown "you should put `STATE_START` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1614:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1651:38 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1700:17 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1701:18 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1705:19 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1708:16 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1709:18 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1713:19 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1716:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1717:18 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1721:19 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1727:14 clippy::cast_lossless "casting `u8` to `u16` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1732:15 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1736:22 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1741:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1747:16 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1751:18 clippy::cast_possible_truncation "casting `u16` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1815:38 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1821:21 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1824:5 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1848:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1850:18 clippy::cast_sign_loss "casting `i32` to `u32` may lose the sign of the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1857:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1860:17 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1867:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1870:19 clippy::cast_possible_truncation "casting `u32` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1873:15 clippy::cast_possible_truncation "casting `u32` to `u8` may truncate the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1876:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1882:26 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:1884:15 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:277:17 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:277:31 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:295:20 clippy::cast_possible_truncation "casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:295:20 clippy::cast_possible_wrap "casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:299:21 clippy::cast_sign_loss "casting `i32` to `usize` may lose the sign of the value" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:34:46 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:398:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:446:41 clippy::inline_always "you have declared `#[inline(always)]` on `forward`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:457:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:459:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:460:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:476:41 clippy::inline_always "you have declared `#[inline(always)]` on `reverse`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:487:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:489:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:490:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:506:41 clippy::inline_always "you have declared `#[inline(always)]` on `forward_many`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:518:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:520:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:554:41 clippy::inline_always "you have declared `#[inline(always)]` on `exec_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:555:5 clippy::too_many_lines "this function has too many lines (101/100)" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:58:9 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:667:21 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:747:41 clippy::inline_always "you have declared `#[inline(always)]` on `exec_at_reverse`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:795:21 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:848:9 clippy::doc_markdown "you should put `next_si` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:852:41 clippy::inline_always "you have declared `#[inline(always)]` on `next_si`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:885:12 clippy::doc_markdown "you should put `STATE_DEAD` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:889:9 clippy::doc_markdown "you should put `STATE_UNKNOWN` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:897:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/dfa.rs:979:29 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers" +target/lintcheck/sources/regex-1.3.2/src/error.rs:6:1 clippy::manual_non_exhaustive "this seems like a manual implementation of the non-exhaustive pattern" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1000:14 clippy::doc_markdown "you should put `captures_nfa` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:100:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1028:5 clippy::too_many_arguments "this function has too many arguments (9/7)" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1039:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1144:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1179:26 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:122:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1250:41 clippy::inline_always "you have declared `#[inline(always)]` on `searcher`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1260:41 clippy::inline_always "you have declared `#[inline(always)]` on `searcher_str`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1270:17 clippy::doc_markdown "you should put `RegexSet` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:1280:17 clippy::doc_markdown "you should put `RegexSet` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:137:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:158:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:168:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:181:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:195:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:204:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:210:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:245:62 clippy::if_same_then_else "this `if` has identical blocks" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:251:21 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:262:60 clippy::if_same_then_else "this `if` has identical blocks" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:268:21 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:278:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:281:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:286:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:300:30 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:308:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:329:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:330:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:331:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:334:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:340:19 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:344:27 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:383:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_match_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:388:41 clippy::inline_always "you have declared `#[inline(always)]` on `is_match_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:393:41 clippy::inline_always "you have declared `#[inline(always)]` on `find_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:398:41 clippy::inline_always "you have declared `#[inline(always)]` on `captures_read_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:425:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_match_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:44:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:473:9 clippy::doc_markdown "you should put `shortest_match(...).is_some` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:474:41 clippy::inline_always "you have declared `#[inline(always)]` on `is_match_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:524:41 clippy::inline_always "you have declared `#[inline(always)]` on `find_at`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:52:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:686:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:727:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:767:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:783:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_dfa`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:791:41 clippy::inline_always "you have declared `#[inline(always)]` on `shortest_dfa_reverse_suffix`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:823:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:868:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:897:31 clippy::doc_markdown "you should put `shortest_nfa(...).is_some` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:899:9 clippy::doc_markdown "you should put `shortest_nfa` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:905:14 clippy::doc_markdown "you should put `match_nfa` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:930:14 clippy::doc_markdown "you should put `shortest_nfa` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/exec.rs:981:14 clippy::doc_markdown "you should put `find_nfa` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:170:27 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:171:5 clippy::match_like_matches_macro "match expression looks like `matches!` macro" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:22:13 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:27:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:30:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:38:30 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:42:21 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:50:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:69:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:80:28 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:84:21 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/expand.rs:8:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/input.rs:142:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/input.rs:146:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/input.rs:165:31 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/input.rs:178:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/input.rs:228:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/input.rs:236:21 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/input.rs:236:33 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/input.rs:24:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:271:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/input.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:362:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:370:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:371:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/regex-1.3.2/src/input.rs:37:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:388:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:47:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:53:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/input.rs:63:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/lib.rs:1:null clippy::cargo_common_metadata "package `regex` is missing `package.keywords` metadata" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:101:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:114:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:127:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:139:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:144:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:149:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:154:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:155:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:160:30 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:167:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:168:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:211:20 clippy::redundant_else "redundant else block" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:276:50 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:342:41 clippy::inline_always "you have declared `#[inline(always)]` on `find`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:435:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:436:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:437:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:438:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:439:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:440:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:455:41 clippy::inline_always "you have declared `#[inline(always)]` on `find`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:46:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:481:41 clippy::inline_always "you have declared `#[inline(always)]` on `is_suffix`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:51:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:579:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:580:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:583:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:602:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:622:24 clippy::redundant_else "redundant else block" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:62:18 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:637:24 clippy::redundant_else "redundant else block" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:648:9 clippy::needless_return "unneeded `return` statement" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:651:44 clippy::doc_markdown "you should put `BoyerMooreSearch` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:65:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:68:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:783:32 clippy::redundant_else "redundant else block" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:786:42 clippy::manual_saturating_arithmetic "manual saturating arithmetic" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:78:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:84:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:850:20 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/regex-1.3.2/src/literal/imp.rs:85:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:103:15 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:103:52 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:114:5 clippy::too_many_arguments "this function has too many arguments (8/7)" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:117:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:124:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:220:9 clippy::doc_markdown "you should put `thread_caps` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:222:16 clippy::doc_markdown "you should put `at_next` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:223:9 clippy::doc_markdown "you should put `at_next` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:224:5 clippy::too_many_arguments "this function has too many arguments (8/7)" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:234:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:303:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:331:29 clippy::mut_mut "this expression mutably borrows a mutable reference. Consider reborrowing" +target/lintcheck/sources/regex-1.3.2/src/pikevm.rs:88:5 clippy::too_many_arguments "this function has too many arguments (8/7)" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:102:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:120:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:128:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:134:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:141:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:164:41 clippy::inline_always "you have declared `#[inline(always)]` on `deref`. This is usually a bad idea" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:172:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:18:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:236:13 clippy::write_with_newline "using `write!()` with a format string that ends in a single newline" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:300:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:301:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:382:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:409:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:80:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/prog.rs:80:5 clippy::new_without_default "you should consider adding a `Default` implementation for `prog::Program`" +target/lintcheck/sources/regex-1.3.2/src/re_builder.rs:267:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_builder.rs:267:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_builder.rs:4:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/regex-1.3.2/src/re_builder.rs:57:17 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_builder.rs:57:17 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_builder.rs:68:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_builder.rs:68:17 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:1017:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:1039:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:1093:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:1118:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:1133:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:118:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:256:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:483:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:48:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:558:29 clippy::doc_markdown "you should put `shortest_match` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:55:33 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:55:47 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:572:29 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:720:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:817:5 clippy::doc_markdown "you should put `CaptureLocations` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:843:1 clippy::len_without_is_empty "item `re_bytes::CaptureLocations` has a public `len` method but no corresponding `is_empty` method" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:849:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:858:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:869:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:891:1 clippy::len_without_is_empty "item `re_bytes::Captures<'t>` has a public `len` method but no corresponding `is_empty` method" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:911:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:917:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:926:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:955:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:179:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:179:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:251:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:251:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:94:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:94:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_trait.rs:136:29 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:1019:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:1041:9 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:1088:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:1135:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:1160:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:174:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:21:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:313:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:38:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:44:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:51:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:533:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:617:29 clippy::doc_markdown "you should put `shortest_match` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:631:29 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:64:33 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:64:47 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:834:5 clippy::doc_markdown "you should put `CaptureLocations` between ticks in the documentation" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:860:1 clippy::len_without_is_empty "item `re_unicode::CaptureLocations` has a public `len` method but no corresponding `is_empty` method" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:866:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:875:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:886:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:908:1 clippy::len_without_is_empty "item `re_unicode::Captures<'t>` has a public `len` method but no corresponding `is_empty` method" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:928:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:934:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:943:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:972:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/sparse.rs:10:37 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/regex-1.3.2/src/sparse.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:100:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:103:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:106:22 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:107:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:108:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:109:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:111:27 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:121:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:143:24 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:143:9 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:23:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:30:20 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:51:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:58:23 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:58:9 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:63:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:66:22 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:66:54 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:77:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:80:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:83:22 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:84:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:85:19 clippy::cast_lossless "casting `u8` to `u32` may become silently lossy if you later change the type" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:92:23 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:92:9 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/regex-1.3.2/src/utf8.rs:97:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" +target/lintcheck/sources/ripgrep-12.1.1/build.rs:133:19 clippy::option_as_ref_deref "called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `githash.as_deref()` instead" +target/lintcheck/sources/ripgrep-12.1.1/build.rs:18:18 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/ripgrep-12.1.1/build.rs:225:14 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/build.rs:92:19 clippy::option_as_ref_deref "called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `githash.as_deref()` instead" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1408:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1408:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1409:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1409:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:152:32 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:152:32 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:156:39 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:156:39 clippy::doc_markdown "you should put `clap::Arg` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:156:5 clippy::doc_markdown "you should put `RGArg` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:156:5 clippy::doc_markdown "you should put `RGArg` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1668:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1668:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1669:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1669:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1821:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1821:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1822:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1822:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:2999:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:2999:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:3000:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:3000:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:367:54 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:367:54 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:414:59 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:414:59 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:417:57 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:75:9 clippy::doc_markdown "you should put `RIPGREP_BUILD_GIT_HASH` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:75:9 clippy::doc_markdown "you should put `RIPGREP_BUILD_GIT_HASH` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:87:5 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:87:5 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1143:22 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:11:1 clippy::single_component_path_imports "this import is redundant" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1209:74 clippy::if_same_then_else "this `if` has identical blocks" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1282:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1430:22 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1438:21 clippy::doc_markdown "you should put `OsStr` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1520:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1524:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1635:14 clippy::doc_markdown "you should put `values_of_lossy` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1693:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1770:17 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1829:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:287:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:33:1 clippy::single_component_path_imports "this import is redundant" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:34:1 clippy::single_component_path_imports "this import is redundant" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:35:1 clippy::single_component_path_imports "this import is redundant" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:369:5 clippy::upper_case_acronyms "name `JSON` contains a capitalized acronym" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:410:14 clippy::trivially_copy_pass_by_ref "this argument (2 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:475:18 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:512:19 clippy::doc_markdown "you should put `ArgMatches` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:549:16 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:76:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:77:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:923:42 clippy::doc_markdown "you should put `BinaryDetection::quit` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/config.rs:13:1 clippy::single_component_path_imports "this import is redundant" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/config.rs:58:6 clippy::type_complexity "very complex type used. Consider factoring parts into `type` definitions" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/config.rs:79:6 clippy::type_complexity "very complex type used. Consider factoring parts into `type` definitions" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/logger.rs:11:30 clippy::doc_markdown "you should put `max_level` between ticks in the documentation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/logger.rs:15:16 clippy::redundant_static_lifetimes "constants have by default a `'static` lifetime" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/main.rs:114:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/main.rs:189:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/main.rs:55:19 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/main.rs:56:9 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/messages.rs:46:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/messages.rs:51:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/messages.rs:62:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/path_printer.rs:27:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/path_printer.rs:89:9 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:185:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:224:5 clippy::upper_case_acronyms "name `JSON` contains a capitalized acronym" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:292:9 clippy::write_with_newline "using `write!()` with a format string that ends in a single newline" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:311:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:377:12 clippy::nonminimal_bool "this boolean expression can be simplified" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:423:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:447:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:472:24 clippy::map_clone "you are using an explicit closure for cloning elements" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:472:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:480:24 clippy::map_clone "you are using an explicit closure for cloning elements" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:480:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:49:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:509:24 clippy::map_clone "you are using an explicit closure for cloning elements" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:509:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:517:24 clippy::map_clone "you are using an explicit closure for cloning elements" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:517:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:533:36 clippy::cast_lossless "casting `u32` to `f64` may become silently lossy if you later change the type" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:533:5 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/subject.rs:20:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/subject.rs:4:1 clippy::single_component_path_imports "this import is redundant" +target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1592:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1616:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1627:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1638:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1649:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:952:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:986:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/syn-1.0.54/build.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata" +target/lintcheck/sources/syn-1.0.54/src/lib.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata" +target/lintcheck/sources/syn-1.0.54/src/lit.rs:1397:40 clippy::redundant_else "redundant else block" +target/lintcheck/sources/syn-1.0.54/src/lit.rs:1405:28 clippy::redundant_else "redundant else block" +target/lintcheck/sources/syn-1.0.54/src/lit.rs:1485:32 clippy::redundant_else "redundant else block" +target/lintcheck/sources/syn-1.0.54/src/token.rs:974:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `unicode-xid` is missing `package.categories` metadata" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:57:64 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:60:10 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:62:27 clippy::doc_markdown "you should put `ID_Start` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:62:67 clippy::doc_markdown "you should put `NFKx` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:63:21 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:65:61 clippy::doc_markdown "you should put `XID_Continue` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:68:10 clippy::doc_markdown "you should put `XID_Continue` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:70:28 clippy::doc_markdown "you should put `ID_Continue` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:70:72 clippy::doc_markdown "you should put `NFKx` between ticks in the documentation" +target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:71:24 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" +target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:101:34 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:42:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:53:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/count.rs:32:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/count.rs:38:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/count.rs:42:33 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/xsv-0.13.0/src/cmd/count.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/fixlengths.rs:45:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/fixlengths.rs:50:18 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/fixlengths.rs:62:30 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/xsv-0.13.0/src/cmd/fixlengths.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/flatten.rs:10:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/flatten.rs:51:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/fmt.rs:50:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/fmt.rs:55:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/fmt.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:148:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:149:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:15:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:169:13 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:176:17 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:178:24 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:77:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/frequency.rs:93:31 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" +target/lintcheck/sources/xsv-0.13.0/src/cmd/headers.rs:43:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/headers.rs:49:17 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" +target/lintcheck/sources/xsv-0.13.0/src/cmd/headers.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/index.rs:11:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/index.rs:45:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/input.rs:42:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/input.rs:47:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/input.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:17:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:194:29 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:224:22 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:293:14 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:293:20 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:297:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:298:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:299:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:300:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:308:9 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:342:38 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:342:46 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:347:9 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:372:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:375:33 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:392:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:403:29 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:406:57 clippy::implicit_clone "implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:426:13 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:77:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:94:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/partition.rs:105:22 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/partition.rs:106:22 clippy::redundant_slicing "redundant slicing of the whole range" +target/lintcheck/sources/xsv-0.13.0/src/cmd/partition.rs:139:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/partition.rs:15:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/partition.rs:169:9 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/xsv-0.13.0/src/cmd/partition.rs:56:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/partition.rs:77:9 clippy::unused_self "unused `self` argument" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:105:44 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:115:21 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:11:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:51:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:58:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:69:9 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:75:16 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:91:42 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sample.rs:92:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/search.rs:51:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/search.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/select.rs:60:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/select.rs:8:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/slice.rs:57:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/slice.rs:9:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sort.rs:11:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sort.rs:138:47 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sort.rs:139:51 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sort.rs:48:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/sort.rs:91:14 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" +target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:14:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:61:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:94:5 clippy::unnecessary_wraps "this function's return value is unnecessary" +target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:96:14 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:99:13 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:110:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:127:14 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:138:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:139:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:162:25 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:22:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:231:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:262:35 clippy::default_trait_access "calling `cmd::stats::TypedSum::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:263:40 clippy::default_trait_access "calling `cmd::stats::TypedMinMax::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:264:39 clippy::default_trait_access "calling `stats::OnlineStats::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:265:58 clippy::default_trait_access "calling `stats::Unsorted::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:266:41 clippy::default_trait_access "calling `stats::Unsorted::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:268:18 clippy::default_trait_access "calling `cmd::stats::FieldType::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:269:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:270:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:271:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:272:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:273:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:274:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:283:9 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:284:9 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:285:9 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:290:21 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:293:25 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:297:25 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:301:21 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:302:21 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:308:18 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:318:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:322:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:322:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:327:9 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:330:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:338:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:402:16 clippy::redundant_pattern_matching "redundant pattern matching, consider using `is_ok()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:403:16 clippy::redundant_pattern_matching "redundant pattern matching, consider using `is_ok()`" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:407:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:411:16 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:427:56 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:429:56 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:430:60 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:430:60 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:454:5 clippy::doc_markdown "you should put `TypedSum` between ticks in the documentation" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:473:43 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:504:56 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:505:51 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:511:5 clippy::doc_markdown "you should put `TypedMinMax` between ticks in the documentation" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:536:35 clippy::cast_possible_truncation "casting `f64` to `i64` may truncate the value" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:544:33 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:592:22 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:593:22 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:594:23 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:595:21 clippy::default_trait_access "calling `stats::MinMax::default()` is more clear than this expression" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:71:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:86:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/table.rs:10:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/cmd/table.rs:50:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/cmd/table.rs:54:9 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/config.rs:113:43 clippy::or_fun_call "use of `unwrap_or` followed by a function call" +target/lintcheck/sources/xsv-0.13.0/src/config.rs:58:1 clippy::struct_excessive_bools "more than 3 bools in a struct" +target/lintcheck/sources/xsv-0.13.0/src/config.rs:77:28 clippy::explicit_deref_methods "explicit deref method call" +target/lintcheck/sources/xsv-0.13.0/src/config.rs:90:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/index.rs:31:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/main.rs:164:49 clippy::redundant_clone "redundant clone" +target/lintcheck/sources/xsv-0.13.0/src/main.rs:164:50 clippy::implicit_clone "implicitly cloning a `String` by calling `to_owned` on its dereferenced type" +target/lintcheck/sources/xsv-0.13.0/src/main.rs:1:null clippy::cargo_common_metadata "package `xsv` is missing `package.categories` metadata" +target/lintcheck/sources/xsv-0.13.0/src/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `rand_core`: 0.3.1, 0.4.2" +target/lintcheck/sources/xsv-0.13.0/src/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `rand`: 0.3.23, 0.4.6" +target/lintcheck/sources/xsv-0.13.0/src/main.rs:75:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:13:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:154:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:250:33 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:250:43 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:255:39 clippy::range_plus_one "an inclusive range would be more readable" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:280:20 clippy::len_zero "length comparison to zero" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:29:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:360:62 clippy::trivially_copy_pass_by_ref "this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:360:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Option`" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:375:9 clippy::stable_sort_primitive "used `sort` on primitive type `usize`" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:379:18 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:416:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:419:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Option`" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:420:27 clippy::option_option "consider using `Option` instead of `Option>` or a custom enum if you need to distinguish all 3 cases" +target/lintcheck/sources/xsv-0.13.0/src/select.rs:99:17 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/xsv-0.13.0/src/util.rs:150:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/xsv-0.13.0/src/util.rs:37:33 clippy::map_clone "you are using an explicit closure for copying elements" +target/lintcheck/sources/xsv-0.13.0/src/util.rs:90:1 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" @@ -3426,6 +3433,7 @@ clippy::non_ascii_literal 6 clippy::single_component_path_imports 6 clippy::case_sensitive_file_extension_comparisons 7 clippy::explicit_into_iter_loop 7 +clippy::implicit_clone 7 clippy::map_clone 7 clippy::option_map_unit_fn 7 clippy::range_plus_one 7 From b9a7a2a2750ee112f71d95b3f588bc9d51e949a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Feb 2021 23:31:32 +0100 Subject: [PATCH 046/226] lintcheck: add a couple of dtolnays crates to the source list --- clippy_dev/lintcheck_crates.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clippy_dev/lintcheck_crates.toml b/clippy_dev/lintcheck_crates.toml index 60e70ca4eb22b..3e443c593a264 100644 --- a/clippy_dev/lintcheck_crates.toml +++ b/clippy_dev/lintcheck_crates.toml @@ -21,3 +21,10 @@ rand_core = {name = "rand_core", versions = ['0.6.0']} regex = {name = "regex", versions = ['1.3.2']} syn = {name = "syn", versions = ['1.0.54']} unicode-xid = {name = "unicode-xid", versions = ['0.2.1']} +# some more of dtolnays crates +anyhow = {name = "anyhow", versions = ['1.0.38']} +async-trait = {name = "async-trait", versions = ['0.1.42']} +cxx = {name = "cxx", versions = ['1.0.32']} +ryu = {name = "ryu", version = ['1.0.5']} +serde_yaml = {name = "serde_yaml", versions = ['0.8.17']} +thiserror = {name = "thiserror", versions = ['1.0.24']} From 70d952e75123b9c0a935be77d1c58d5c1ed71af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 28 Feb 2021 02:07:01 +0100 Subject: [PATCH 047/226] lintcheck: more fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix a couple of issues when checking if lintcheck needed rerun after clippy binary changed. I was apparently still comparing the times wrongly, but it should be fixed™ now... I actually looked at the date of the sources.toml and not at the date of the log file! Also fix progress report counter not advancing in squential mode --- clippy_dev/src/lintcheck.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 622dad1740b7a..60e677b1e13fe 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -496,7 +496,7 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String, /// check if the latest modification of the logfile is older than the modification date of the /// clippy binary, if this is true, we should clean the lintchec shared target directory and recheck -fn lintcheck_needs_rerun(toml_path: &PathBuf) -> bool { +fn lintcheck_needs_rerun(lintcheck_logs_path: &PathBuf) -> bool { let clippy_modified: std::time::SystemTime = { let mut times = [CLIPPY_DRIVER_PATH, CARGO_CLIPPY_PATH].iter().map(|p| { std::fs::metadata(p) @@ -505,17 +505,17 @@ fn lintcheck_needs_rerun(toml_path: &PathBuf) -> bool { .expect("failed to get modification date") }); // the oldest modification of either of the binaries - std::cmp::min(times.next().unwrap(), times.next().unwrap()) + std::cmp::max(times.next().unwrap(), times.next().unwrap()) }; - let logs_modified: std::time::SystemTime = std::fs::metadata(toml_path) + let logs_modified: std::time::SystemTime = std::fs::metadata(lintcheck_logs_path) .expect("failed to get metadata of file") .modified() .expect("failed to get modification date"); - // if clippys modification time is smaller (older) than the logs mod time, we need to rerun - // lintcheck - clippy_modified < logs_modified + // time is represented in seconds since X + // logs_modified 2 and clippy_modified 5 means clippy binary is older and we need to recheck + logs_modified < clippy_modified } /// lintchecks `main()` function @@ -528,7 +528,7 @@ pub fn run(clap_config: &ArgMatches) { // if the clippy bin is newer than our logs, throw away target dirs to force clippy to // refresh the logs - if lintcheck_needs_rerun(&config.sources_toml_path) { + if lintcheck_needs_rerun(&config.lintcheck_results_path) { let shared_target_dir = "target/lintcheck/shared_target_dir"; match std::fs::metadata(&shared_target_dir) { Ok(metadata) => { @@ -538,8 +538,7 @@ pub fn run(clap_config: &ArgMatches) { .expect("failed to remove target/lintcheck/shared_target_dir"); } }, - Err(_) => { // dir probably does not exist, don't remove anything - }, + Err(_) => { /* dir probably does not exist, don't remove anything */ }, } } @@ -566,6 +565,8 @@ pub fn run(clap_config: &ArgMatches) { let crates = read_crates(&config.sources_toml_path); let old_stats = read_stats_from_file(&config.lintcheck_results_path); + let counter = AtomicUsize::new(1); + let clippy_warnings: Vec = if let Some(only_one_crate) = clap_config.value_of("only") { // if we don't have the specified crate in the .toml, throw an error if !crates.iter().any(|krate| { @@ -595,8 +596,6 @@ pub fn run(clap_config: &ArgMatches) { if config.max_jobs > 1 { // run parallel with rayon - let counter = AtomicUsize::new(0); - // Ask rayon for thread count. Assume that half of that is the number of physical cores // Use one target dir for each core so that we can run N clippys in parallel. // We need to use different target dirs because cargo would lock them for a single build otherwise, @@ -623,7 +622,7 @@ pub fn run(clap_config: &ArgMatches) { crates .into_iter() .map(|krate| krate.download_and_extract()) - .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, num_crates)) + .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, 1, num_crates)) .flatten() .collect() } From 1ebaae8a158d414c23c83298135cdfa12c8b980a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 28 Feb 2021 12:36:56 +0100 Subject: [PATCH 048/226] lintcheck: make download path and source path consts, move source directory from traget/lintcheck/crates to target/lintcheck/sources also update logfile with the dtolnay crates --- clippy_dev/src/lintcheck.rs | 11 ++-- lintcheck-logs/lintcheck_crates_logs.txt | 64 +++++++++++++++++++----- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 60e677b1e13fe..60cccfe2a6398 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -22,6 +22,9 @@ use serde_json::Value; const CLIPPY_DRIVER_PATH: &str = "target/debug/clippy-driver"; const CARGO_CLIPPY_PATH: &str = "target/debug/cargo-clippy"; +const LINTCHECK_DOWNLOADS: &str = "target/lintcheck/downloads"; +const LINTCHECK_SOURCES: &str = "target/lintcheck/sources"; + /// List of sources to check, loaded from a .toml file #[derive(Debug, Serialize, Deserialize)] struct SourceList { @@ -102,8 +105,8 @@ impl CrateSource { fn download_and_extract(&self) -> Crate { match self { CrateSource::CratesIo { name, version, options } => { - let extract_dir = PathBuf::from("target/lintcheck/crates"); - let krate_download_dir = PathBuf::from("target/lintcheck/downloads"); + let extract_dir = PathBuf::from(LINTCHECK_SOURCES); + let krate_download_dir = PathBuf::from(LINTCHECK_DOWNLOADS); // url to download the crate from crates.io let url = format!("https://crates.io/api/v1/crates/{}/{}/download", name, version); @@ -143,7 +146,7 @@ impl CrateSource { options, } => { let repo_path = { - let mut repo_path = PathBuf::from("target/lintcheck/crates"); + let mut repo_path = PathBuf::from(LINTCHECK_SOURCES); // add a -git suffix in case we have the same crate from crates.io and a git repo repo_path.push(format!("{}-git", name)); repo_path @@ -185,7 +188,7 @@ impl CrateSource { use fs_extra::dir; // simply copy the entire directory into our target dir - let copy_dest = PathBuf::from("target/lintcheck/crates/"); + let copy_dest = PathBuf::from(format!("{}/", LINTCHECK_SOURCES)); // the source path of the crate we copied, ${copy_dest}/crate_name let crate_root = copy_dest.join(name); // .../crates/local_crate diff --git a/lintcheck-logs/lintcheck_crates_logs.txt b/lintcheck-logs/lintcheck_crates_logs.txt index b0ba84ed3f7c1..449af904efe5b 100644 --- a/lintcheck-logs/lintcheck_crates_logs.txt +++ b/lintcheck-logs/lintcheck_crates_logs.txt @@ -1,5 +1,26 @@ -clippy 0.1.52 (e3386041a 2021-02-28) +clippy 0.1.52 (70d952e75 2021-02-28) +target/lintcheck/sources/anyhow-1.0.38/build.rs:1:null clippy::cargo_common_metadata "package `anyhow` is missing `package.keywords` metadata" +target/lintcheck/sources/anyhow-1.0.38/src/error.rs:350:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/anyhow-1.0.38/src/lib.rs:1:null clippy::cargo_common_metadata "package `anyhow` is missing `package.keywords` metadata" +target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:130:1 clippy::too_many_lines "this function has too many lines (104/100)" +target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:156:26 clippy::default_trait_access "calling `syn::token::Where::default()` is more clear than this expression" +target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:259:1 clippy::too_many_lines "this function has too many lines (204/100)" +target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:414:35 clippy::shadow_unrelated "`generics` is being shadowed" +target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:464:32 clippy::if_not_else "unnecessary `!=` operation" +target/lintcheck/sources/async-trait-0.1.42/src/lib.rs:102:7 clippy::doc_markdown "you should put `async_trait` between ticks in the documentation" +target/lintcheck/sources/async-trait-0.1.42/src/lib.rs:159:64 clippy::doc_markdown "you should put `async_trait` between ticks in the documentation" +target/lintcheck/sources/async-trait-0.1.42/src/lib.rs:1:null clippy::cargo_common_metadata "package `async-trait` is missing `package.categories` metadata" +target/lintcheck/sources/async-trait-0.1.42/src/lib.rs:1:null clippy::cargo_common_metadata "package `async-trait` is missing `package.keywords` metadata" +target/lintcheck/sources/async-trait-0.1.42/src/lib.rs:240:15 clippy::doc_markdown "you should put `async_trait` between ticks in the documentation" +target/lintcheck/sources/async-trait-0.1.42/src/lifetime.rs:5:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/async-trait-0.1.42/src/receiver.rs:102:34 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/async-trait-0.1.42/src/receiver.rs:107:29 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/async-trait-0.1.42/src/receiver.rs:137:38 clippy::default_trait_access "calling `syn::token::Colon2::default()` is more clear than this expression" +target/lintcheck/sources/async-trait-0.1.42/src/receiver.rs:162:55 clippy::default_trait_access "calling `syn::token::Colon2::default()` is more clear than this expression" +target/lintcheck/sources/async-trait-0.1.42/src/receiver.rs:167:42 clippy::default_trait_access "calling `syn::token::Colon2::default()` is more clear than this expression" +target/lintcheck/sources/async-trait-0.1.42/src/receiver.rs:73:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/async-trait-0.1.42/src/receiver.rs:97:34 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" target/lintcheck/sources/cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:104:34 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" @@ -1427,6 +1448,23 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:52:1 clippy::m target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:56:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:60:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:64:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cxx-1.0.32/src/rust_string.rs:15:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/rust_string.rs:19:24 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/rust_vec.rs:21:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/rust_vec.rs:25:24 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/rust_vec.rs:74:35 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/rust_vec.rs:78:39 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/rust_vec.rs:90:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/rust_vec.rs:94:24 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/shared_ptr.rs:108:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/shared_ptr.rs:165:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cxx-1.0.32/src/shared_ptr.rs:54:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/shared_ptr.rs:62:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/shared_ptr.rs:75:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/unique_ptr.rs:185:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cxx-1.0.32/src/unwind.rs:22:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/cxx-1.0.32/src/weak_ptr.rs:47:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/cxx-1.0.32/src/weak_ptr.rs:80:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" target/lintcheck/sources/iron-0.6.1/src/error.rs:24:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/iron-0.6.1/src/iron.rs:105:13 clippy::redundant_field_names "redundant field names in struct initialization" target/lintcheck/sources/iron-0.6.1/src/iron.rs:119:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -3176,12 +3214,14 @@ target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1638:9 clippy::let_undersco target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1649:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:952:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:986:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" +target/lintcheck/sources/serde_yaml-0.8.17/src/lib.rs:1:null clippy::cargo_common_metadata "package `serde_yaml` is missing `package.categories` metadata" target/lintcheck/sources/syn-1.0.54/build.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata" target/lintcheck/sources/syn-1.0.54/src/lib.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata" target/lintcheck/sources/syn-1.0.54/src/lit.rs:1397:40 clippy::redundant_else "redundant else block" target/lintcheck/sources/syn-1.0.54/src/lit.rs:1405:28 clippy::redundant_else "redundant else block" target/lintcheck/sources/syn-1.0.54/src/lit.rs:1485:32 clippy::redundant_else "redundant else block" target/lintcheck/sources/syn-1.0.54/src/token.rs:974:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/thiserror-1.0.24/src/lib.rs:1:null clippy::cargo_common_metadata "package `thiserror` is missing `package.keywords` metadata" target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `unicode-xid` is missing `package.categories` metadata" target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:57:64 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:60:10 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" @@ -3426,7 +3466,6 @@ clippy::len_without_is_empty 5 clippy::match_like_matches_macro 5 clippy::needless_return 5 clippy::new_without_default 5 -clippy::ptr_as_ptr 5 clippy::collapsible_else_if 6 clippy::manual_strip 6 clippy::non_ascii_literal 6 @@ -3446,42 +3485,43 @@ clippy::match_wildcard_for_single_variants 10 clippy::missing_safety_doc 10 clippy::needless_doctest_main 10 clippy::needless_lifetimes 12 -clippy::cargo_common_metadata 13 -clippy::shadow_unrelated 13 clippy::linkedlist 14 +clippy::shadow_unrelated 14 clippy::single_char_add_str 14 clippy::option_if_let_else 15 clippy::needless_pass_by_value 18 +clippy::cargo_common_metadata 19 clippy::cast_possible_wrap 19 clippy::cast_sign_loss 19 +clippy::ptr_as_ptr 19 clippy::unnecessary_wraps 19 clippy::unused_self 19 clippy::unusual_byte_groupings 19 clippy::map_unwrap_or 20 clippy::struct_excessive_bools 20 clippy::redundant_static_lifetimes 21 -clippy::default_trait_access 22 clippy::cast_lossless 23 -clippy::let_underscore_drop 23 +clippy::default_trait_access 26 +clippy::let_underscore_drop 26 clippy::trivially_copy_pass_by_ref 26 clippy::redundant_else 29 -clippy::too_many_lines 32 -clippy::if_not_else 35 +clippy::too_many_lines 34 +clippy::if_not_else 36 clippy::enum_glob_use 40 clippy::unseparated_literal_suffix 41 clippy::cast_precision_loss 44 clippy::single_match_else 45 -clippy::missing_panics_doc 56 +clippy::missing_panics_doc 57 clippy::inline_always 59 clippy::match_same_arms 60 -clippy::similar_names 78 +clippy::similar_names 81 clippy::cast_possible_truncation 95 clippy::redundant_field_names 111 clippy::redundant_closure_for_method_calls 135 clippy::items_after_statements 139 -clippy::module_name_repetitions 142 +clippy::module_name_repetitions 144 clippy::wildcard_imports 163 -clippy::doc_markdown 178 +clippy::doc_markdown 181 clippy::missing_errors_doc 343 clippy::unreadable_literal 365 clippy::must_use_candidate 565 From 45d6a77ce884f41c2ef5e1160aabbf355403d5cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 28 Feb 2021 13:52:26 +0100 Subject: [PATCH 049/226] lintcheck: add more embark crate sources to the sources toml --- clippy_dev/lintcheck_crates.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clippy_dev/lintcheck_crates.toml b/clippy_dev/lintcheck_crates.toml index 3e443c593a264..f065b2de01e50 100644 --- a/clippy_dev/lintcheck_crates.toml +++ b/clippy_dev/lintcheck_crates.toml @@ -14,7 +14,6 @@ bitflags = {name = "bitflags", versions = ['1.2.1']} libc = {name = "libc", versions = ['0.2.81']} log = {name = "log", versions = ['0.4.11']} proc-macro2 = {name = "proc-macro2", versions = ['1.0.24']} -puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} quote = {name = "quote", versions = ['1.0.7']} rand = {name = "rand", versions = ['0.7.3']} rand_core = {name = "rand_core", versions = ['0.6.0']} @@ -28,3 +27,9 @@ cxx = {name = "cxx", versions = ['1.0.32']} ryu = {name = "ryu", version = ['1.0.5']} serde_yaml = {name = "serde_yaml", versions = ['0.8.17']} thiserror = {name = "thiserror", versions = ['1.0.24']} +# some embark crates there are other interesting crates but +# unfortunately adding them increases lintcheck runtime drastically +cfg-expr = {name = "cfg-expr", versions = ['0.7.1']} +puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} +rpmalloc = {name = "rpmalloc", versions = ['0.2.0']} +tame-oidc = {name = "tame-oidc", versions = ['0.1.0']} From 25f909863b9946c65ae37375f8f95720b728cc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 28 Feb 2021 13:59:47 +0100 Subject: [PATCH 050/226] update lintcheck_crates logs and fix typos --- clippy_dev/lintcheck_crates.toml | 2 +- clippy_dev/src/lintcheck.rs | 4 +- lintcheck-logs/lintcheck_crates_logs.txt | 93 +++++++++++++++++++----- 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/clippy_dev/lintcheck_crates.toml b/clippy_dev/lintcheck_crates.toml index f065b2de01e50..dfee28f1a8712 100644 --- a/clippy_dev/lintcheck_crates.toml +++ b/clippy_dev/lintcheck_crates.toml @@ -27,7 +27,7 @@ cxx = {name = "cxx", versions = ['1.0.32']} ryu = {name = "ryu", version = ['1.0.5']} serde_yaml = {name = "serde_yaml", versions = ['0.8.17']} thiserror = {name = "thiserror", versions = ['1.0.24']} -# some embark crates there are other interesting crates but +# some embark crates, there are other interesting crates but # unfortunately adding them increases lintcheck runtime drastically cfg-expr = {name = "cfg-expr", versions = ['0.7.1']} puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 60cccfe2a6398..1db0445559cd5 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -318,8 +318,8 @@ impl LintcheckConfig { let sources_toml_path = PathBuf::from(sources_toml); - // for the path where we save the lint results, get the filename without extenstion ( so for - // wasd.toml, use "wasd"....) + // for the path where we save the lint results, get the filename without extension (so for + // wasd.toml, use "wasd"...) let filename: PathBuf = sources_toml_path.file_stem().unwrap().into(); let lintcheck_results_path = PathBuf::from(format!("lintcheck-logs/{}_logs.txt", filename.display())); diff --git a/lintcheck-logs/lintcheck_crates_logs.txt b/lintcheck-logs/lintcheck_crates_logs.txt index 449af904efe5b..167024b3a056b 100644 --- a/lintcheck-logs/lintcheck_crates_logs.txt +++ b/lintcheck-logs/lintcheck_crates_logs.txt @@ -1448,6 +1448,36 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:52:1 clippy::m target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:56:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:60:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/workspace.rs:64:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cfg-expr-0.7.1/src/error.rs:107:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cfg-expr-0.7.1/src/error.rs:5:1 clippy::module_name_repetitions "item name ends with its containing module's name" +target/lintcheck/sources/cfg-expr-0.7.1/src/error.rs:74:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cfg-expr-0.7.1/src/error.rs:91:24 clippy::if_not_else "unnecessary boolean `not` operation" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/lexer.rs:102:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/lexer.rs:125:33 clippy::redundant_slicing "redundant slicing of the whole range" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/lexer.rs:4:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/lexer.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/lexer.rs:76:1 clippy::module_name_repetitions "item name starts with its containing module's name" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/lexer.rs:97:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:351:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:464:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:57:13 clippy::enum_glob_use "usage of wildcard import for enum variants" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:586:33 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:599:32 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:116:31 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:124:36 clippy::similar_names "binding's name is too similar to existing binding" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:17:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:17:5 clippy::too_many_lines "this function has too many lines (345/100)" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:22:13 clippy::shadow_unrelated "`original` is being shadowed" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:243:36 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:254:34 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:25:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:390:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:392:17 clippy::if_not_else "unnecessary `!=` operation" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:67:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" +target/lintcheck/sources/cfg-expr-0.7.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `cfg-expr` is missing `package.categories` metadata" +target/lintcheck/sources/cfg-expr-0.7.1/src/targets/builtins.rs:11:5 clippy::wildcard_imports "usage of wildcard import" +target/lintcheck/sources/cfg-expr-0.7.1/src/targets/mod.rs:139:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/cfg-expr-0.7.1/src/targets/mod.rs:153:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/cxx-1.0.32/src/rust_string.rs:15:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" target/lintcheck/sources/cxx-1.0.32/src/rust_string.rs:19:24 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" target/lintcheck/sources/cxx-1.0.32/src/rust_vec.rs:21:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" @@ -3207,6 +3237,12 @@ target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:533:36 clippy::cas target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:533:5 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" target/lintcheck/sources/ripgrep-12.1.1/crates/core/subject.rs:20:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/ripgrep-12.1.1/crates/core/subject.rs:4:1 clippy::single_component_path_imports "this import is redundant" +target/lintcheck/sources/rpmalloc-0.2.0/src/lib.rs:103:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rpmalloc-0.2.0/src/lib.rs:114:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/rpmalloc-0.2.0/src/lib.rs:71:73 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/rpmalloc-0.2.0/src/lib.rs:72:50 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" +target/lintcheck/sources/rpmalloc-0.2.0/src/lib.rs:92:9 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/rpmalloc-0.2.0/src/lib.rs:95:21 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1592:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1616:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" target/lintcheck/sources/serde-1.0.118/src/de/mod.rs:1627:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" @@ -3221,6 +3257,25 @@ target/lintcheck/sources/syn-1.0.54/src/lit.rs:1397:40 clippy::redundant_else "r target/lintcheck/sources/syn-1.0.54/src/lit.rs:1405:28 clippy::redundant_else "redundant else block" target/lintcheck/sources/syn-1.0.54/src/lit.rs:1485:32 clippy::redundant_else "redundant else block" target/lintcheck/sources/syn-1.0.54/src/token.rs:974:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/errors.rs:9:5 clippy::upper_case_acronyms "name `HTTP` contains a capitalized acronym" +target/lintcheck/sources/tame-oidc-0.1.0/src/lib.rs:1:null clippy::cargo_common_metadata "package `tame-oidc` is missing `package.categories` metadata" +target/lintcheck/sources/tame-oidc-0.1.0/src/oidc.rs:111:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/oidc.rs:127:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/oidc.rs:52:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/oidc.rs:60:1 clippy::from_over_into "an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true" +target/lintcheck/sources/tame-oidc-0.1.0/src/oidc.rs:76:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:107:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:107:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:118:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:143:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:159:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:26:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:38:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:57:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:71:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:77:12 clippy::upper_case_acronyms "name `JWK` contains a capitalized acronym" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:90:12 clippy::upper_case_acronyms "name `JWKS` contains a capitalized acronym" +target/lintcheck/sources/tame-oidc-0.1.0/src/provider.rs:95:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/thiserror-1.0.24/src/lib.rs:1:null clippy::cargo_common_metadata "package `thiserror` is missing `package.keywords` metadata" target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `unicode-xid` is missing `package.categories` metadata" target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:57:64 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation" @@ -3416,7 +3471,6 @@ clippy::comparison_chain 1 clippy::expect_fun_call 1 clippy::explicit_deref_methods 1 clippy::from_iter_instead_of_collect 1 -clippy::from_over_into 1 clippy::int_plus_one 1 clippy::manual_flatten 1 clippy::manual_saturating_arithmetic 1 @@ -3426,7 +3480,6 @@ clippy::or_fun_call 1 clippy::precedence 1 clippy::pub_enum_variant_names 1 clippy::redundant_clone 1 -clippy::redundant_slicing 1 clippy::same_item_push 1 clippy::should_implement_trait 1 clippy::stable_sort_primitive 1 @@ -3438,6 +3491,7 @@ clippy::while_let_on_iterator 1 clippy::comparison_to_empty 2 clippy::expl_impl_clone_on_copy 2 clippy::filter_map 2 +clippy::from_over_into 2 clippy::len_zero 2 clippy::manual_non_exhaustive 2 clippy::match_on_vec_items 2 @@ -3445,6 +3499,7 @@ clippy::option_as_ref_deref 2 clippy::option_option 2 clippy::question_mark 2 clippy::redundant_pattern_matching 2 +clippy::redundant_slicing 2 clippy::type_complexity 2 clippy::unnecessary_cast 2 clippy::unused_unit 2 @@ -3458,7 +3513,6 @@ clippy::mut_mut 3 clippy::ptr_arg 3 clippy::zero_ptr 3 clippy::too_many_arguments 4 -clippy::upper_case_acronyms 4 clippy::explicit_iter_loop 5 clippy::field_reassign_with_default 5 clippy::identity_op 5 @@ -3476,6 +3530,7 @@ clippy::implicit_clone 7 clippy::map_clone 7 clippy::option_map_unit_fn 7 clippy::range_plus_one 7 +clippy::upper_case_acronyms 7 clippy::invalid_upcast_comparisons 8 clippy::needless_question_mark 8 clippy::wrong_self_convention 8 @@ -3486,43 +3541,43 @@ clippy::missing_safety_doc 10 clippy::needless_doctest_main 10 clippy::needless_lifetimes 12 clippy::linkedlist 14 -clippy::shadow_unrelated 14 clippy::single_char_add_str 14 clippy::option_if_let_else 15 +clippy::shadow_unrelated 15 clippy::needless_pass_by_value 18 -clippy::cargo_common_metadata 19 clippy::cast_possible_wrap 19 clippy::cast_sign_loss 19 -clippy::ptr_as_ptr 19 clippy::unnecessary_wraps 19 clippy::unused_self 19 clippy::unusual_byte_groupings 19 clippy::map_unwrap_or 20 clippy::struct_excessive_bools 20 +clippy::cargo_common_metadata 21 +clippy::ptr_as_ptr 21 clippy::redundant_static_lifetimes 21 clippy::cast_lossless 23 clippy::default_trait_access 26 clippy::let_underscore_drop 26 clippy::trivially_copy_pass_by_ref 26 clippy::redundant_else 29 -clippy::too_many_lines 34 -clippy::if_not_else 36 -clippy::enum_glob_use 40 +clippy::too_many_lines 35 +clippy::if_not_else 38 clippy::unseparated_literal_suffix 41 clippy::cast_precision_loss 44 -clippy::single_match_else 45 -clippy::missing_panics_doc 57 +clippy::enum_glob_use 44 +clippy::single_match_else 48 clippy::inline_always 59 -clippy::match_same_arms 60 -clippy::similar_names 81 +clippy::missing_panics_doc 59 +clippy::match_same_arms 62 +clippy::similar_names 83 clippy::cast_possible_truncation 95 clippy::redundant_field_names 111 clippy::redundant_closure_for_method_calls 135 -clippy::items_after_statements 139 -clippy::module_name_repetitions 144 -clippy::wildcard_imports 163 -clippy::doc_markdown 181 -clippy::missing_errors_doc 343 +clippy::items_after_statements 143 +clippy::module_name_repetitions 146 +clippy::wildcard_imports 164 +clippy::doc_markdown 184 +clippy::missing_errors_doc 356 clippy::unreadable_literal 365 -clippy::must_use_candidate 565 +clippy::must_use_candidate 571 ICEs: From 7984e60d9e1ee36b943cc72e4e7b33d05e6ee83d Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 26 Feb 2021 21:17:29 -0600 Subject: [PATCH 051/226] Use diagnostic items in into_iter_collections --- clippy_lints/src/methods/mod.rs | 4 ++-- clippy_utils/src/lib.rs | 40 ++++++++++++++++----------------- clippy_utils/src/paths.rs | 2 -- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f101b6476f508..5163074453b5f 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::{self, TraitRef, Ty, TyS}; use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; -use rustc_span::symbol::{sym, SymbolStr}; +use rustc_span::symbol::{sym, Symbol, SymbolStr}; use rustc_typeck::hir_ty_to_ty; use crate::consts::{constant, Constant}; @@ -3619,7 +3619,7 @@ fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_re } } -fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(&'static str, &'static str)> { +fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(Symbol, &'static str)> { has_iter_method(cx, self_ref_ty).map(|ty_name| { let mutbl = match self_ref_ty.kind() { ty::Ref(_, _, mutbl) => mutbl, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 94b7339c7eb6f..42512cadfb18d 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1295,24 +1295,24 @@ pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_>, node: HirId) -> bool } /// Returns true if ty has `iter` or `iter_mut` methods -pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<&'static str> { +pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option { // FIXME: instead of this hard-coded list, we should check if `::iter` // exists and has the desired signature. Unfortunately FnCtxt is not exported // so we can't use its `lookup_method` method. - let into_iter_collections: [&[&str]; 13] = [ - &paths::VEC, - &paths::OPTION, - &paths::RESULT, - &paths::BTREESET, - &paths::BTREEMAP, - &paths::VEC_DEQUE, - &paths::LINKED_LIST, - &paths::BINARY_HEAP, - &paths::HASHSET, - &paths::HASHMAP, - &paths::PATH_BUF, - &paths::PATH, - &paths::RECEIVER, + let into_iter_collections: &[Symbol] = &[ + sym::vec_type, + sym::option_type, + sym::result_type, + sym::BTreeMap, + sym::BTreeSet, + sym::vecdeque_type, + sym::LinkedList, + sym::BinaryHeap, + sym::hashset_type, + sym::hashmap_type, + sym::PathBuf, + sym::Path, + sym::Receiver, ]; let ty_to_check = match probably_ref_ty.kind() { @@ -1321,15 +1321,15 @@ pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option< }; let def_id = match ty_to_check.kind() { - ty::Array(..) => return Some("array"), - ty::Slice(..) => return Some("slice"), + ty::Array(..) => return Some(sym::array), + ty::Slice(..) => return Some(sym::slice), ty::Adt(adt, _) => adt.did, _ => return None, }; - for path in &into_iter_collections { - if match_def_path(cx, def_id, path) { - return Some(*path.last().unwrap()); + for &name in into_iter_collections { + if cx.tcx.is_diagnostic_item(name, def_id) { + return Some(cx.tcx.item_name(def_id)); } } None diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index e617867964753..c2da1f9b7c9f9 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -99,7 +99,6 @@ pub(super) const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"]; pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"]; pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"]; pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"]; -pub const PATH: [&str; 3] = ["std", "path", "Path"]; pub const PATH_BUF: [&str; 3] = ["std", "path", "PathBuf"]; pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"]; pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"]; @@ -116,7 +115,6 @@ pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"]; pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; pub const RC: [&str; 3] = ["alloc", "rc", "Rc"]; pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"]; -pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"]; pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"]; pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"]; pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"]; From ada8c72f3f21013f789f774d4c0219c58264e663 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 1 Mar 2021 11:53:33 -0600 Subject: [PATCH 052/226] Add version = "Two" to rustfmt.toml Ignore UI tests since this change makes rustfmt less friendly with UI test comments. --- clippy_lints/src/await_holding_invalid.rs | 14 ++-- clippy_lints/src/float_literal.rs | 6 +- clippy_lints/src/infinite_iter.rs | 6 +- clippy_lints/src/inherent_to_string.rs | 2 +- clippy_lints/src/loops.rs | 6 +- clippy_lints/src/mutable_debug_assertion.rs | 6 +- clippy_lints/src/needless_continue.rs | 6 +- clippy_lints/src/open_options.rs | 12 ++-- clippy_utils/src/camel_case.rs | 6 +- clippy_utils/src/lib.rs | 12 ++-- clippy_utils/src/ptr.rs | 6 +- rustfmt.toml | 1 + tests/lint_message_convention.rs | 4 +- .../upper_case_acronyms.rs | 5 +- .../upper_case_acronyms.stderr | 4 +- tests/ui/auxiliary/macro_rules.rs | 6 +- tests/ui/blocks_in_if_conditions.fixed | 33 ++++----- tests/ui/blocks_in_if_conditions.rs | 33 ++++----- tests/ui/blocks_in_if_conditions.stderr | 10 +-- .../ui/checked_unwrap/simple_conditionals.rs | 14 ++-- tests/ui/crashes/ice-6256.rs | 1 + tests/ui/crashes/ice-6256.stderr | 6 +- tests/ui/dbg_macro.rs | 6 +- tests/ui/dbg_macro.stderr | 16 ++--- tests/ui/default_trait_access.fixed | 20 +----- tests/ui/default_trait_access.rs | 20 +----- tests/ui/doc_panics.rs | 12 +--- tests/ui/doc_panics.stderr | 12 ++-- tests/ui/float_cmp.rs | 12 +--- tests/ui/float_cmp.stderr | 12 ++-- tests/ui/float_cmp_const.rs | 6 +- tests/ui/float_cmp_const.stderr | 16 ++--- tests/ui/floating_point_abs.fixed | 30 ++------ tests/ui/floating_point_abs.rs | 72 ++++--------------- tests/ui/floating_point_abs.stderr | 70 ++++++------------ tests/ui/if_let_some_result.fixed | 12 +--- tests/ui/if_let_some_result.rs | 12 +--- tests/ui/if_let_some_result.stderr | 6 +- tests/ui/implicit_return.fixed | 6 +- tests/ui/implicit_return.rs | 6 +- tests/ui/implicit_return.stderr | 28 ++++---- tests/ui/needless_lifetimes.rs | 6 +- tests/ui/needless_lifetimes.stderr | 36 +++++----- tests/ui/redundant_clone.fixed | 6 +- tests/ui/redundant_clone.rs | 6 +- tests/ui/redundant_clone.stderr | 28 ++++---- tests/ui/unnecessary_wraps.rs | 36 ++-------- tests/ui/unnecessary_wraps.stderr | 18 ++--- tests/ui/upper_case_acronyms.rs | 5 +- tests/ui/use_self.fixed | 6 +- tests/ui/use_self.rs | 6 +- tests/ui/use_self.stderr | 2 +- 52 files changed, 225 insertions(+), 503 deletions(-) diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index fad3aff96cc82..112c5bb14e359 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -123,13 +123,13 @@ fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorType } if is_refcell_ref(cx, adt.did) { span_lint_and_note( - cx, - AWAIT_HOLDING_REFCELL_REF, - ty_cause.span, - "this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await", - ty_cause.scope_span.or(Some(span)), - "these are all the await points this ref is held through", - ); + cx, + AWAIT_HOLDING_REFCELL_REF, + ty_cause.span, + "this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await", + ty_cause.scope_span.or(Some(span)), + "these are all the await points this ref is held through", + ); } } } diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index be646cbe4d043..8e256f3468419 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -145,11 +145,7 @@ fn count_digits(s: &str) -> usize { .take_while(|c| *c != 'e' && *c != 'E') .fold(0, |count, c| { // leading zeros - if c == '0' && count == 0 { - count - } else { - count + 1 - } + if c == '0' && count == 0 { count } else { count + 1 } }) } diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index 129abd7d89749..7040ac3191f3c 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -89,11 +89,7 @@ impl Finiteness { impl From for Finiteness { #[must_use] fn from(b: bool) -> Self { - if b { - Infinite - } else { - Finite - } + if b { Infinite } else { Finite } } } diff --git a/clippy_lints/src/inherent_to_string.rs b/clippy_lints/src/inherent_to_string.rs index a95321ea7e2af..c1f3e1d9d685c 100644 --- a/clippy_lints/src/inherent_to_string.rs +++ b/clippy_lints/src/inherent_to_string.rs @@ -139,7 +139,7 @@ fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) { self_type.to_string() ), None, - &format!("remove the inherent method from type `{}`", self_type.to_string()) + &format!("remove the inherent method from type `{}`", self_type.to_string()), ); } else { span_lint_and_help( diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 3ff9e18212106..711cd5b3b15cc 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -3158,11 +3158,7 @@ fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, identifier: Ident) seen_other: false, }; visitor.visit_block(block); - if visitor.seen_other { - None - } else { - Some(visitor.uses) - } + if visitor.seen_other { None } else { Some(visitor.uses) } } fn shorten_needless_collect_span(expr: &Expr<'_>) -> Span { diff --git a/clippy_lints/src/mutable_debug_assertion.rs b/clippy_lints/src/mutable_debug_assertion.rs index 76417aa7ed09d..9ac127abe0a4b 100644 --- a/clippy_lints/src/mutable_debug_assertion.rs +++ b/clippy_lints/src/mutable_debug_assertion.rs @@ -73,11 +73,7 @@ impl<'a, 'tcx> MutArgVisitor<'a, 'tcx> { } fn expr_span(&self) -> Option { - if self.found { - self.expr_span - } else { - None - } + if self.found { self.expr_span } else { None } } } diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 603071a5f4ac4..30fe2d6225c8a 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -416,11 +416,7 @@ fn erode_from_back(s: &str) -> String { break; } } - if ret.is_empty() { - s.to_string() - } else { - ret - } + if ret.is_empty() { s.to_string() } else { ret } } fn span_of_first_expr_in_block(block: &ast::Block) -> Option { diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs index 73a99a3a2f870..07ca196990da9 100644 --- a/clippy_lints/src/open_options.rs +++ b/clippy_lints/src/open_options.rs @@ -69,15 +69,11 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec .. } = *span { - if lit { - Argument::True - } else { - Argument::False - } + if lit { Argument::True } else { Argument::False } } else { - return; // The function is called with a literal - // which is not a boolean literal. This is theoretically - // possible, but not very likely. + // The function is called with a literal which is not a boolean literal. + // This is theoretically possible, but not very likely. + return; } }, _ => Argument::Unknown, diff --git a/clippy_utils/src/camel_case.rs b/clippy_utils/src/camel_case.rs index ba1c01ebc9f76..a6636e391374e 100644 --- a/clippy_utils/src/camel_case.rs +++ b/clippy_utils/src/camel_case.rs @@ -25,11 +25,7 @@ pub fn until(s: &str) -> usize { return i; } } - if up { - last_i - } else { - s.len() - } + if up { last_i } else { s.len() } } /// Returns index of the last camel-case component of `s`. diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 2380ea4c7bfae..fbcc6d8dc4f1f 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1563,12 +1563,12 @@ pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool { /// ``` pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { use rustc_trait_selection::traits; - let predicates = - cx.tcx - .predicates_of(did) - .predicates - .iter() - .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); + let predicates = cx + .tcx + .predicates_of(did) + .predicates + .iter() + .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); traits::impossible_predicates( cx.tcx, traits::elaborate_predicates(cx.tcx, predicates) diff --git a/clippy_utils/src/ptr.rs b/clippy_utils/src/ptr.rs index baeff08e02cd8..df6143edbcaf0 100644 --- a/clippy_utils/src/ptr.rs +++ b/clippy_utils/src/ptr.rs @@ -36,11 +36,7 @@ fn extract_clone_suggestions<'tcx>( abort: false, }; visitor.visit_body(body); - if visitor.abort { - None - } else { - Some(visitor.spans) - } + if visitor.abort { None } else { Some(visitor.spans) } } struct PtrCloneVisitor<'a, 'tcx> { diff --git a/rustfmt.toml b/rustfmt.toml index f1241e74b0a3d..4b415a31b272e 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -4,3 +4,4 @@ match_block_trailing_comma = true wrap_comments = true edition = "2018" error_on_line_overflow = true +version = "Two" diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index 8c07c5b242f15..3f754c255b749 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -98,7 +98,9 @@ fn lint_message_convention() { eprintln!("\n\n"); }); - eprintln!("\n\n\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed."); + eprintln!( + "\n\n\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed." + ); eprintln!("Check out the rustc-dev-guide for more information:"); eprintln!("https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure\n\n\n"); diff --git a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs index fdf8905f812f6..735909887acb1 100644 --- a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs +++ b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs @@ -16,7 +16,8 @@ enum Flags { FIN, } -struct GCCLLVMSomething; // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of - // `GccLlvmSomething` +// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of +// `GccLlvmSomething` +struct GCCLLVMSomething; fn main() {} diff --git a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr index 1cc59dc45f2aa..38e30683d5797 100644 --- a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr +++ b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr @@ -61,9 +61,9 @@ LL | FIN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin` error: name `GCCLLVMSomething` contains a capitalized acronym - --> $DIR/upper_case_acronyms.rs:19:8 + --> $DIR/upper_case_acronyms.rs:21:8 | -LL | struct GCCLLVMSomething; // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of +LL | struct GCCLLVMSomething; | ^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GccllvmSomething` error: aborting due to 11 previous errors diff --git a/tests/ui/auxiliary/macro_rules.rs b/tests/ui/auxiliary/macro_rules.rs index d6ecd8568ce78..d4470d3f40708 100644 --- a/tests/ui/auxiliary/macro_rules.rs +++ b/tests/ui/auxiliary/macro_rules.rs @@ -23,11 +23,7 @@ macro_rules! try_err { pub fn try_err_fn() -> Result { let err: i32 = 1; // To avoid warnings during rustfix - if true { - Err(err)? - } else { - Ok(2) - } + if true { Err(err)? } else { Ok(2) } } }; } diff --git a/tests/ui/blocks_in_if_conditions.fixed b/tests/ui/blocks_in_if_conditions.fixed index 14562c4d32c12..e6e40a9948c91 100644 --- a/tests/ui/blocks_in_if_conditions.fixed +++ b/tests/ui/blocks_in_if_conditions.fixed @@ -4,9 +4,7 @@ #![warn(clippy::nonminimal_bool)] macro_rules! blocky { - () => {{ - true - }}; + () => {{ true }}; } macro_rules! blocky_too { @@ -34,20 +32,12 @@ fn condition_has_block() -> i32 { } fn condition_has_block_with_single_expression() -> i32 { - if true { - 6 - } else { - 10 - } + if true { 6 } else { 10 } } fn condition_is_normal() -> i32 { let x = 3; - if x == 3 { - 6 - } else { - 10 - } + if x == 3 { 6 } else { 10 } } fn condition_is_unsafe_block() { @@ -61,14 +51,15 @@ fn condition_is_unsafe_block() { fn block_in_assert() { let opt = Some(42); - assert!(opt - .as_ref() - .map(|val| { - let mut v = val * 2; - v -= 1; - v * 3 - }) - .is_some()); + assert!( + opt.as_ref() + .map(|val| { + let mut v = val * 2; + v -= 1; + v * 3 + }) + .is_some() + ); } fn main() {} diff --git a/tests/ui/blocks_in_if_conditions.rs b/tests/ui/blocks_in_if_conditions.rs index bda87650f6da2..69387ff5782b3 100644 --- a/tests/ui/blocks_in_if_conditions.rs +++ b/tests/ui/blocks_in_if_conditions.rs @@ -4,9 +4,7 @@ #![warn(clippy::nonminimal_bool)] macro_rules! blocky { - () => {{ - true - }}; + () => {{ true }}; } macro_rules! blocky_too { @@ -34,20 +32,12 @@ fn condition_has_block() -> i32 { } fn condition_has_block_with_single_expression() -> i32 { - if { true } { - 6 - } else { - 10 - } + if { true } { 6 } else { 10 } } fn condition_is_normal() -> i32 { let x = 3; - if true && x == 3 { - 6 - } else { - 10 - } + if true && x == 3 { 6 } else { 10 } } fn condition_is_unsafe_block() { @@ -61,14 +51,15 @@ fn condition_is_unsafe_block() { fn block_in_assert() { let opt = Some(42); - assert!(opt - .as_ref() - .map(|val| { - let mut v = val * 2; - v -= 1; - v * 3 - }) - .is_some()); + assert!( + opt.as_ref() + .map(|val| { + let mut v = val * 2; + v -= 1; + v * 3 + }) + .is_some() + ); } fn main() {} diff --git a/tests/ui/blocks_in_if_conditions.stderr b/tests/ui/blocks_in_if_conditions.stderr index 9bdddc8e15248..9328492733fd8 100644 --- a/tests/ui/blocks_in_if_conditions.stderr +++ b/tests/ui/blocks_in_if_conditions.stderr @@ -1,5 +1,5 @@ error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> $DIR/blocks_in_if_conditions.rs:26:5 + --> $DIR/blocks_in_if_conditions.rs:24:5 | LL | / if { LL | | let x = 3; @@ -17,15 +17,15 @@ LL | }; if res { | error: omit braces around single expression condition - --> $DIR/blocks_in_if_conditions.rs:37:8 + --> $DIR/blocks_in_if_conditions.rs:35:8 | -LL | if { true } { +LL | if { true } { 6 } else { 10 } | ^^^^^^^^ help: try: `true` error: this boolean expression can be simplified - --> $DIR/blocks_in_if_conditions.rs:46:8 + --> $DIR/blocks_in_if_conditions.rs:40:8 | -LL | if true && x == 3 { +LL | if true && x == 3 { 6 } else { 10 } | ^^^^^^^^^^^^^^ help: try: `x == 3` | = note: `-D clippy::nonminimal-bool` implied by `-D warnings` diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index 3e7b4b390bad4..369676308348f 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -66,14 +66,16 @@ fn main() { } if x.is_ok() { x = Err(()); - x.unwrap(); // not unnecessary because of mutation of x - // it will always panic but the lint is not smart enough to see this (it only - // checks if conditions). + // not unnecessary because of mutation of x + // it will always panic but the lint is not smart enough to see this (it only + // checks if conditions). + x.unwrap(); } else { x = Ok(()); - x.unwrap_err(); // not unnecessary because of mutation of x - // it will always panic but the lint is not smart enough to see this (it - // only checks if conditions). + // not unnecessary because of mutation of x + // it will always panic but the lint is not smart enough to see this (it + // only checks if conditions). + x.unwrap_err(); } assert!(x.is_ok(), "{:?}", x.unwrap_err()); // ok, it's a common test pattern diff --git a/tests/ui/crashes/ice-6256.rs b/tests/ui/crashes/ice-6256.rs index 5409f36b3f1ed..67308263dadda 100644 --- a/tests/ui/crashes/ice-6256.rs +++ b/tests/ui/crashes/ice-6256.rs @@ -8,6 +8,7 @@ impl dyn TT { fn func(&self) {} } +#[rustfmt::skip] fn main() { let f = |x: &dyn TT| x.func(); //[default]~ ERROR: mismatched types //[nll]~^ ERROR: borrowed data escapes outside of closure diff --git a/tests/ui/crashes/ice-6256.stderr b/tests/ui/crashes/ice-6256.stderr index d1a8bdc3c8d8c..d35d459168f23 100644 --- a/tests/ui/crashes/ice-6256.stderr +++ b/tests/ui/crashes/ice-6256.stderr @@ -1,13 +1,13 @@ error[E0308]: mismatched types - --> $DIR/ice-6256.rs:12:28 + --> $DIR/ice-6256.rs:13:28 | LL | let f = |x: &dyn TT| x.func(); //[default]~ ERROR: mismatched types | ^^^^ lifetime mismatch | = note: expected reference `&(dyn TT + 'static)` found reference `&dyn TT` -note: the anonymous lifetime #1 defined on the body at 12:13... - --> $DIR/ice-6256.rs:12:13 +note: the anonymous lifetime #1 defined on the body at 13:13... + --> $DIR/ice-6256.rs:13:13 | LL | let f = |x: &dyn TT| x.func(); //[default]~ ERROR: mismatched types | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/dbg_macro.rs b/tests/ui/dbg_macro.rs index d2df7fbd3e84c..d74e2611ee1fd 100644 --- a/tests/ui/dbg_macro.rs +++ b/tests/ui/dbg_macro.rs @@ -1,11 +1,7 @@ #![warn(clippy::dbg_macro)] fn foo(n: u32) -> u32 { - if let Some(n) = dbg!(n.checked_sub(4)) { - n - } else { - n - } + if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } } fn factorial(n: u32) -> u32 { diff --git a/tests/ui/dbg_macro.stderr b/tests/ui/dbg_macro.stderr index b8aafe9667846..bdf372af29075 100644 --- a/tests/ui/dbg_macro.stderr +++ b/tests/ui/dbg_macro.stderr @@ -1,17 +1,17 @@ error: `dbg!` macro is intended as a debugging tool --> $DIR/dbg_macro.rs:4:22 | -LL | if let Some(n) = dbg!(n.checked_sub(4)) { +LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } | ^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::dbg-macro` implied by `-D warnings` help: ensure to avoid having uses of it in version control | -LL | if let Some(n) = n.checked_sub(4) { +LL | if let Some(n) = n.checked_sub(4) { n } else { n } | ^^^^^^^^^^^^^^^^ error: `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:12:8 + --> $DIR/dbg_macro.rs:8:8 | LL | if dbg!(n <= 1) { | ^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | if n <= 1 { | ^^^^^^ error: `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:13:9 + --> $DIR/dbg_macro.rs:9:9 | LL | dbg!(1) | ^^^^^^^ @@ -33,7 +33,7 @@ LL | 1 | error: `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:15:9 + --> $DIR/dbg_macro.rs:11:9 | LL | dbg!(n * factorial(n - 1)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | n * factorial(n - 1) | error: `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:20:5 + --> $DIR/dbg_macro.rs:16:5 | LL | dbg!(42); | ^^^^^^^^ @@ -55,7 +55,7 @@ LL | 42; | ^^ error: `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:21:5 + --> $DIR/dbg_macro.rs:17:5 | LL | dbg!(dbg!(dbg!(42))); | ^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | dbg!(dbg!(42)); | ^^^^^^^^^^^^^^ error: `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:22:14 + --> $DIR/dbg_macro.rs:18:14 | LL | foo(3) + dbg!(factorial(4)); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/default_trait_access.fixed b/tests/ui/default_trait_access.fixed index d05567a3f8249..4c80cabc72305 100644 --- a/tests/ui/default_trait_access.fixed +++ b/tests/ui/default_trait_access.fixed @@ -48,25 +48,7 @@ fn main() { println!( "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}], [{:?}]", - s1, - s2, - s3, - s4, - s5, - s6, - s7, - s8, - s9, - s10, - s11, - s12, - s13, - s14, - s15, - s16, - s17, - s18, - s19, + s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, ); } diff --git a/tests/ui/default_trait_access.rs b/tests/ui/default_trait_access.rs index 447e70c0bbbea..a68b6455c0416 100644 --- a/tests/ui/default_trait_access.rs +++ b/tests/ui/default_trait_access.rs @@ -48,25 +48,7 @@ fn main() { println!( "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}], [{:?}]", - s1, - s2, - s3, - s4, - s5, - s6, - s7, - s8, - s9, - s10, - s11, - s12, - s13, - s14, - s15, - s16, - s17, - s18, - s19, + s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, ); } diff --git a/tests/ui/doc_panics.rs b/tests/ui/doc_panics.rs index 3008c2d5b8538..17e72353f8039 100644 --- a/tests/ui/doc_panics.rs +++ b/tests/ui/doc_panics.rs @@ -30,11 +30,7 @@ pub fn inner_body(opt: Option) { /// This needs to be documented pub fn unreachable_and_panic() { - if true { - unreachable!() - } else { - panic!() - } + if true { unreachable!() } else { panic!() } } /// This is documented @@ -84,11 +80,7 @@ pub fn todo_documented() { /// /// We still need to do this part pub fn unreachable_amd_panic_documented() { - if true { - unreachable!() - } else { - panic!() - } + if true { unreachable!() } else { panic!() } } /// This is okay because it is private diff --git a/tests/ui/doc_panics.stderr b/tests/ui/doc_panics.stderr index 287148690d27a..2fa88a2f6ec4b 100644 --- a/tests/ui/doc_panics.stderr +++ b/tests/ui/doc_panics.stderr @@ -67,19 +67,15 @@ error: docs for function which may panic missing `# Panics` section --> $DIR/doc_panics.rs:32:1 | LL | / pub fn unreachable_and_panic() { -LL | | if true { -LL | | unreachable!() -LL | | } else { -LL | | panic!() -LL | | } +LL | | if true { unreachable!() } else { panic!() } LL | | } | |_^ | note: first possible panic found here - --> $DIR/doc_panics.rs:36:9 + --> $DIR/doc_panics.rs:33:39 | -LL | panic!() - | ^^^^^^^^ +LL | if true { unreachable!() } else { panic!() } + | ^^^^^^^^ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index 586784b73e697..ad5d1a09c0345 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -21,19 +21,11 @@ where } fn eq_fl(x: f32, y: f32) -> bool { - if x.is_nan() { - y.is_nan() - } else { - x == y - } // no error, inside "eq" fn + if x.is_nan() { y.is_nan() } else { x == y } // no error, inside "eq" fn } fn fl_eq(x: f32, y: f32) -> bool { - if x.is_nan() { - y.is_nan() - } else { - x == y - } // no error, inside "eq" fn + if x.is_nan() { y.is_nan() } else { x == y } // no error, inside "eq" fn } struct X { diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr index bb4051c466201..cb5b68b2e9585 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui/float_cmp.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:66:5 + --> $DIR/float_cmp.rs:58:5 | LL | ONE as f64 != 2.0; | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin` @@ -8,7 +8,7 @@ LL | ONE as f64 != 2.0; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:71:5 + --> $DIR/float_cmp.rs:63:5 | LL | x == 1.0; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin` @@ -16,7 +16,7 @@ LL | x == 1.0; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:74:5 + --> $DIR/float_cmp.rs:66:5 | LL | twice(x) != twice(ONE as f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin` @@ -24,7 +24,7 @@ LL | twice(x) != twice(ONE as f64); = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:94:5 + --> $DIR/float_cmp.rs:86:5 | LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin` @@ -32,7 +32,7 @@ LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` arrays - --> $DIR/float_cmp.rs:99:5 + --> $DIR/float_cmp.rs:91:5 | LL | a1 == a2; | ^^^^^^^^ @@ -40,7 +40,7 @@ LL | a1 == a2; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:100:5 + --> $DIR/float_cmp.rs:92:5 | LL | a1[0] == a2[0]; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin` diff --git a/tests/ui/float_cmp_const.rs b/tests/ui/float_cmp_const.rs index 263d9a7b92ddb..86ce3bf3bd992 100644 --- a/tests/ui/float_cmp_const.rs +++ b/tests/ui/float_cmp_const.rs @@ -8,11 +8,7 @@ const ONE: f32 = 1.0; const TWO: f32 = 2.0; fn eq_one(x: f32) -> bool { - if x.is_nan() { - false - } else { - x == ONE - } // no error, inside "eq" fn + if x.is_nan() { false } else { x == ONE } // no error, inside "eq" fn } fn main() { diff --git a/tests/ui/float_cmp_const.stderr b/tests/ui/float_cmp_const.stderr index 5d0455363e8e0..d8182cf855b08 100644 --- a/tests/ui/float_cmp_const.stderr +++ b/tests/ui/float_cmp_const.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` constant - --> $DIR/float_cmp_const.rs:20:5 + --> $DIR/float_cmp_const.rs:16:5 | LL | 1f32 == ONE; | ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin` @@ -8,7 +8,7 @@ LL | 1f32 == ONE; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` constant - --> $DIR/float_cmp_const.rs:21:5 + --> $DIR/float_cmp_const.rs:17:5 | LL | TWO == ONE; | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin` @@ -16,7 +16,7 @@ LL | TWO == ONE; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` constant - --> $DIR/float_cmp_const.rs:22:5 + --> $DIR/float_cmp_const.rs:18:5 | LL | TWO != ONE; | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin` @@ -24,7 +24,7 @@ LL | TWO != ONE; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` constant - --> $DIR/float_cmp_const.rs:23:5 + --> $DIR/float_cmp_const.rs:19:5 | LL | ONE + ONE == TWO; | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin` @@ -32,7 +32,7 @@ LL | ONE + ONE == TWO; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` constant - --> $DIR/float_cmp_const.rs:25:5 + --> $DIR/float_cmp_const.rs:21:5 | LL | x as f32 == ONE; | ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin` @@ -40,7 +40,7 @@ LL | x as f32 == ONE; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` constant - --> $DIR/float_cmp_const.rs:28:5 + --> $DIR/float_cmp_const.rs:24:5 | LL | v == ONE; | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin` @@ -48,7 +48,7 @@ LL | v == ONE; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` constant - --> $DIR/float_cmp_const.rs:29:5 + --> $DIR/float_cmp_const.rs:25:5 | LL | v != ONE; | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin` @@ -56,7 +56,7 @@ LL | v != ONE; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` constant arrays - --> $DIR/float_cmp_const.rs:61:5 + --> $DIR/float_cmp_const.rs:57:5 | LL | NON_ZERO_ARRAY == NON_ZERO_ARRAY2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/floating_point_abs.fixed b/tests/ui/floating_point_abs.fixed index b623e4988e7d4..cea727257c430 100644 --- a/tests/ui/floating_point_abs.fixed +++ b/tests/ui/floating_point_abs.fixed @@ -42,43 +42,23 @@ fn fake_nabs3(a: A) -> A { } fn not_fake_abs1(num: f64) -> f64 { - if num > 0.0 { - num - } else { - -num - 1f64 - } + if num > 0.0 { num } else { -num - 1f64 } } fn not_fake_abs2(num: f64) -> f64 { - if num > 0.0 { - num + 1.0 - } else { - -(num + 1.0) - } + if num > 0.0 { num + 1.0 } else { -(num + 1.0) } } fn not_fake_abs3(num1: f64, num2: f64) -> f64 { - if num1 > 0.0 { - num2 - } else { - -num2 - } + if num1 > 0.0 { num2 } else { -num2 } } fn not_fake_abs4(a: A) -> f64 { - if a.a > 0.0 { - a.b - } else { - -a.b - } + if a.a > 0.0 { a.b } else { -a.b } } fn not_fake_abs5(a: A) -> f64 { - if a.a > 0.0 { - a.a - } else { - -a.b - } + if a.a > 0.0 { a.a } else { -a.b } } fn main() { diff --git a/tests/ui/floating_point_abs.rs b/tests/ui/floating_point_abs.rs index cbf9c94e41e6a..ba8a8f18fa231 100644 --- a/tests/ui/floating_point_abs.rs +++ b/tests/ui/floating_point_abs.rs @@ -7,59 +7,31 @@ struct A { } fn fake_abs1(num: f64) -> f64 { - if num >= 0.0 { - num - } else { - -num - } + if num >= 0.0 { num } else { -num } } fn fake_abs2(num: f64) -> f64 { - if 0.0 < num { - num - } else { - -num - } + if 0.0 < num { num } else { -num } } fn fake_abs3(a: A) -> f64 { - if a.a > 0.0 { - a.a - } else { - -a.a - } + if a.a > 0.0 { a.a } else { -a.a } } fn fake_abs4(num: f64) -> f64 { - if 0.0 >= num { - -num - } else { - num - } + if 0.0 >= num { -num } else { num } } fn fake_abs5(a: A) -> f64 { - if a.a < 0.0 { - -a.a - } else { - a.a - } + if a.a < 0.0 { -a.a } else { a.a } } fn fake_nabs1(num: f64) -> f64 { - if num < 0.0 { - num - } else { - -num - } + if num < 0.0 { num } else { -num } } fn fake_nabs2(num: f64) -> f64 { - if 0.0 >= num { - num - } else { - -num - } + if 0.0 >= num { num } else { -num } } fn fake_nabs3(a: A) -> A { @@ -70,43 +42,23 @@ fn fake_nabs3(a: A) -> A { } fn not_fake_abs1(num: f64) -> f64 { - if num > 0.0 { - num - } else { - -num - 1f64 - } + if num > 0.0 { num } else { -num - 1f64 } } fn not_fake_abs2(num: f64) -> f64 { - if num > 0.0 { - num + 1.0 - } else { - -(num + 1.0) - } + if num > 0.0 { num + 1.0 } else { -(num + 1.0) } } fn not_fake_abs3(num1: f64, num2: f64) -> f64 { - if num1 > 0.0 { - num2 - } else { - -num2 - } + if num1 > 0.0 { num2 } else { -num2 } } fn not_fake_abs4(a: A) -> f64 { - if a.a > 0.0 { - a.b - } else { - -a.b - } + if a.a > 0.0 { a.b } else { -a.b } } fn not_fake_abs5(a: A) -> f64 { - if a.a > 0.0 { - a.a - } else { - -a.b - } + if a.a > 0.0 { a.a } else { -a.b } } fn main() { diff --git a/tests/ui/floating_point_abs.stderr b/tests/ui/floating_point_abs.stderr index 74a71f2ca7c57..35af70201fada 100644 --- a/tests/ui/floating_point_abs.stderr +++ b/tests/ui/floating_point_abs.stderr @@ -1,77 +1,49 @@ error: manual implementation of `abs` method --> $DIR/floating_point_abs.rs:10:5 | -LL | / if num >= 0.0 { -LL | | num -LL | | } else { -LL | | -num -LL | | } - | |_____^ help: try: `num.abs()` +LL | if num >= 0.0 { num } else { -num } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()` | = note: `-D clippy::suboptimal-flops` implied by `-D warnings` error: manual implementation of `abs` method - --> $DIR/floating_point_abs.rs:18:5 + --> $DIR/floating_point_abs.rs:14:5 | -LL | / if 0.0 < num { -LL | | num -LL | | } else { -LL | | -num -LL | | } - | |_____^ help: try: `num.abs()` +LL | if 0.0 < num { num } else { -num } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()` error: manual implementation of `abs` method - --> $DIR/floating_point_abs.rs:26:5 + --> $DIR/floating_point_abs.rs:18:5 | -LL | / if a.a > 0.0 { -LL | | a.a -LL | | } else { -LL | | -a.a -LL | | } - | |_____^ help: try: `a.a.abs()` +LL | if a.a > 0.0 { a.a } else { -a.a } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()` error: manual implementation of `abs` method - --> $DIR/floating_point_abs.rs:34:5 + --> $DIR/floating_point_abs.rs:22:5 | -LL | / if 0.0 >= num { -LL | | -num -LL | | } else { -LL | | num -LL | | } - | |_____^ help: try: `num.abs()` +LL | if 0.0 >= num { -num } else { num } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()` error: manual implementation of `abs` method - --> $DIR/floating_point_abs.rs:42:5 + --> $DIR/floating_point_abs.rs:26:5 | -LL | / if a.a < 0.0 { -LL | | -a.a -LL | | } else { -LL | | a.a -LL | | } - | |_____^ help: try: `a.a.abs()` +LL | if a.a < 0.0 { -a.a } else { a.a } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()` error: manual implementation of negation of `abs` method - --> $DIR/floating_point_abs.rs:50:5 + --> $DIR/floating_point_abs.rs:30:5 | -LL | / if num < 0.0 { -LL | | num -LL | | } else { -LL | | -num -LL | | } - | |_____^ help: try: `-num.abs()` +LL | if num < 0.0 { num } else { -num } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()` error: manual implementation of negation of `abs` method - --> $DIR/floating_point_abs.rs:58:5 + --> $DIR/floating_point_abs.rs:34:5 | -LL | / if 0.0 >= num { -LL | | num -LL | | } else { -LL | | -num -LL | | } - | |_____^ help: try: `-num.abs()` +LL | if 0.0 >= num { num } else { -num } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()` error: manual implementation of negation of `abs` method - --> $DIR/floating_point_abs.rs:67:12 + --> $DIR/floating_point_abs.rs:39:12 | LL | a: if a.a >= 0.0 { -a.a } else { a.a }, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-a.a.abs()` diff --git a/tests/ui/if_let_some_result.fixed b/tests/ui/if_let_some_result.fixed index 80505fd997f42..62a25ce2d128c 100644 --- a/tests/ui/if_let_some_result.fixed +++ b/tests/ui/if_let_some_result.fixed @@ -3,19 +3,11 @@ #![warn(clippy::if_let_some_result)] fn str_to_int(x: &str) -> i32 { - if let Ok(y) = x.parse() { - y - } else { - 0 - } + if let Ok(y) = x.parse() { y } else { 0 } } fn str_to_int_ok(x: &str) -> i32 { - if let Ok(y) = x.parse() { - y - } else { - 0 - } + if let Ok(y) = x.parse() { y } else { 0 } } #[rustfmt::skip] diff --git a/tests/ui/if_let_some_result.rs b/tests/ui/if_let_some_result.rs index ecac13574456c..234ff5e9e80e2 100644 --- a/tests/ui/if_let_some_result.rs +++ b/tests/ui/if_let_some_result.rs @@ -3,19 +3,11 @@ #![warn(clippy::if_let_some_result)] fn str_to_int(x: &str) -> i32 { - if let Some(y) = x.parse().ok() { - y - } else { - 0 - } + if let Some(y) = x.parse().ok() { y } else { 0 } } fn str_to_int_ok(x: &str) -> i32 { - if let Ok(y) = x.parse() { - y - } else { - 0 - } + if let Ok(y) = x.parse() { y } else { 0 } } #[rustfmt::skip] diff --git a/tests/ui/if_let_some_result.stderr b/tests/ui/if_let_some_result.stderr index 6afee0f36b9da..0646dd27f35e8 100644 --- a/tests/ui/if_let_some_result.stderr +++ b/tests/ui/if_let_some_result.stderr @@ -1,17 +1,17 @@ error: matching on `Some` with `ok()` is redundant --> $DIR/if_let_some_result.rs:6:5 | -LL | if let Some(y) = x.parse().ok() { +LL | if let Some(y) = x.parse().ok() { y } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::if-let-some-result` implied by `-D warnings` help: consider matching on `Ok(y)` and removing the call to `ok` instead | -LL | if let Ok(y) = x.parse() { +LL | if let Ok(y) = x.parse() { y } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^ error: matching on `Some` with `ok()` is redundant - --> $DIR/if_let_some_result.rs:24:9 + --> $DIR/if_let_some_result.rs:16:9 | LL | if let Some(y) = x . parse() . ok () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/implicit_return.fixed b/tests/ui/implicit_return.fixed index 9066dc3fedfd6..59f7ad9c10624 100644 --- a/tests/ui/implicit_return.fixed +++ b/tests/ui/implicit_return.fixed @@ -14,11 +14,7 @@ fn test_end_of_fn() -> bool { #[allow(clippy::needless_bool)] fn test_if_block() -> bool { - if true { - return true - } else { - return false - } + if true { return true } else { return false } } #[rustfmt::skip] diff --git a/tests/ui/implicit_return.rs b/tests/ui/implicit_return.rs index c0d70ecf502ed..2c1bc04651508 100644 --- a/tests/ui/implicit_return.rs +++ b/tests/ui/implicit_return.rs @@ -14,11 +14,7 @@ fn test_end_of_fn() -> bool { #[allow(clippy::needless_bool)] fn test_if_block() -> bool { - if true { - true - } else { - false - } + if true { true } else { false } } #[rustfmt::skip] diff --git a/tests/ui/implicit_return.stderr b/tests/ui/implicit_return.stderr index fb2ec90276454..3608319e5bd2c 100644 --- a/tests/ui/implicit_return.stderr +++ b/tests/ui/implicit_return.stderr @@ -7,61 +7,61 @@ LL | true = note: `-D clippy::implicit-return` implied by `-D warnings` error: missing `return` statement - --> $DIR/implicit_return.rs:18:9 + --> $DIR/implicit_return.rs:17:15 | -LL | true - | ^^^^ help: add `return` as shown: `return true` +LL | if true { true } else { false } + | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> $DIR/implicit_return.rs:20:9 + --> $DIR/implicit_return.rs:17:29 | -LL | false - | ^^^^^ help: add `return` as shown: `return false` +LL | if true { true } else { false } + | ^^^^^ help: add `return` as shown: `return false` error: missing `return` statement - --> $DIR/implicit_return.rs:27:17 + --> $DIR/implicit_return.rs:23:17 | LL | true => false, | ^^^^^ help: add `return` as shown: `return false` error: missing `return` statement - --> $DIR/implicit_return.rs:28:20 + --> $DIR/implicit_return.rs:24:20 | LL | false => { true }, | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> $DIR/implicit_return.rs:43:9 + --> $DIR/implicit_return.rs:39:9 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> $DIR/implicit_return.rs:51:13 + --> $DIR/implicit_return.rs:47:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> $DIR/implicit_return.rs:60:13 + --> $DIR/implicit_return.rs:56:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> $DIR/implicit_return.rs:78:18 + --> $DIR/implicit_return.rs:74:18 | LL | let _ = || { true }; | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> $DIR/implicit_return.rs:79:16 + --> $DIR/implicit_return.rs:75:16 | LL | let _ = || true; | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> $DIR/implicit_return.rs:87:5 + --> $DIR/implicit_return.rs:83:5 | LL | format!("test {}", "test") | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `return` as shown: `return format!("test {}", "test")` diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs index 44972c8c63964..bda0801e51c7f 100644 --- a/tests/ui/needless_lifetimes.rs +++ b/tests/ui/needless_lifetimes.rs @@ -105,11 +105,7 @@ fn fn_bound_3_cannot_elide() { // No error; multiple input refs. fn fn_bound_4<'a, F: FnOnce() -> &'a ()>(cond: bool, x: &'a (), f: F) -> &'a () { - if cond { - x - } else { - f() - } + if cond { x } else { f() } } struct X { diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr index c8a2e8b81c019..33a6de1618d12 100644 --- a/tests/ui/needless_lifetimes.stderr +++ b/tests/ui/needless_lifetimes.stderr @@ -43,109 +43,109 @@ LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:120:5 + --> $DIR/needless_lifetimes.rs:116:5 | LL | fn self_and_out<'s>(&'s self) -> &'s u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:129:5 + --> $DIR/needless_lifetimes.rs:125:5 | LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:148:1 + --> $DIR/needless_lifetimes.rs:144:1 | LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:178:1 + --> $DIR/needless_lifetimes.rs:174:1 | LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:184:1 + --> $DIR/needless_lifetimes.rs:180:1 | LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:203:1 + --> $DIR/needless_lifetimes.rs:199:1 | LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:211:1 + --> $DIR/needless_lifetimes.rs:207:1 | LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:247:1 + --> $DIR/needless_lifetimes.rs:243:1 | LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:254:9 + --> $DIR/needless_lifetimes.rs:250:9 | LL | fn needless_lt<'a>(x: &'a u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:258:9 + --> $DIR/needless_lifetimes.rs:254:9 | LL | fn needless_lt<'a>(_x: &'a u8) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:271:9 + --> $DIR/needless_lifetimes.rs:267:9 | LL | fn baz<'a>(&'a self) -> impl Foo + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:300:5 + --> $DIR/needless_lifetimes.rs:296:5 | LL | fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:303:5 + --> $DIR/needless_lifetimes.rs:299:5 | LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:312:5 + --> $DIR/needless_lifetimes.rs:308:5 | LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:324:5 + --> $DIR/needless_lifetimes.rs:320:5 | LL | fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:339:5 + --> $DIR/needless_lifetimes.rs:335:5 | LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:352:5 + --> $DIR/needless_lifetimes.rs:348:5 | LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:355:5 + --> $DIR/needless_lifetimes.rs:351:5 | LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed index a5847e37c976e..ec309109ed52b 100644 --- a/tests/ui/redundant_clone.fixed +++ b/tests/ui/redundant_clone.fixed @@ -59,11 +59,7 @@ fn main() { #[derive(Clone)] struct Alpha; fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) { - if b { - (a.clone(), a) - } else { - (Alpha, a) - } + if b { (a.clone(), a) } else { (Alpha, a) } } fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) { diff --git a/tests/ui/redundant_clone.rs b/tests/ui/redundant_clone.rs index dab8d7fb1c727..b57027456e094 100644 --- a/tests/ui/redundant_clone.rs +++ b/tests/ui/redundant_clone.rs @@ -59,11 +59,7 @@ fn main() { #[derive(Clone)] struct Alpha; fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) { - if b { - (a.clone(), a.clone()) - } else { - (Alpha, a) - } + if b { (a.clone(), a.clone()) } else { (Alpha, a) } } fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) { diff --git a/tests/ui/redundant_clone.stderr b/tests/ui/redundant_clone.stderr index 87c219316ce4b..821e7934be8d0 100644 --- a/tests/ui/redundant_clone.stderr +++ b/tests/ui/redundant_clone.stderr @@ -108,61 +108,61 @@ LL | let _t = tup.0.clone(); | ^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:63:22 + --> $DIR/redundant_clone.rs:62:25 | -LL | (a.clone(), a.clone()) - | ^^^^^^^^ help: remove this +LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } + | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:63:21 + --> $DIR/redundant_clone.rs:62:24 | -LL | (a.clone(), a.clone()) - | ^ +LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } + | ^ error: redundant clone - --> $DIR/redundant_clone.rs:123:15 + --> $DIR/redundant_clone.rs:119:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:123:14 + --> $DIR/redundant_clone.rs:119:14 | LL | let _s = s.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:124:15 + --> $DIR/redundant_clone.rs:120:15 | LL | let _t = t.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:124:14 + --> $DIR/redundant_clone.rs:120:14 | LL | let _t = t.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:134:19 + --> $DIR/redundant_clone.rs:130:19 | LL | let _f = f.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:134:18 + --> $DIR/redundant_clone.rs:130:18 | LL | let _f = f.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:146:14 + --> $DIR/redundant_clone.rs:142:14 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^ help: remove this | note: cloned value is neither consumed nor mutated - --> $DIR/redundant_clone.rs:146:13 + --> $DIR/redundant_clone.rs:142:13 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^^ diff --git a/tests/ui/unnecessary_wraps.rs b/tests/ui/unnecessary_wraps.rs index a510263e67da1..54f22e3ee6a4a 100644 --- a/tests/ui/unnecessary_wraps.rs +++ b/tests/ui/unnecessary_wraps.rs @@ -22,29 +22,17 @@ fn func2(a: bool, b: bool) -> Option { if a && b { return Some(10); } - if a { - Some(20) - } else { - Some(30) - } + if a { Some(20) } else { Some(30) } } // public fns should not be linted pub fn func3(a: bool) -> Option { - if a { - Some(1) - } else { - Some(1) - } + if a { Some(1) } else { Some(1) } } // should not be linted fn func4(a: bool) -> Option { - if a { - Some(1) - } else { - None - } + if a { Some(1) } else { None } } // should be linted @@ -64,11 +52,7 @@ fn func7() -> Result { // should not be linted fn func8(a: bool) -> Result { - if a { - Ok(1) - } else { - Err(()) - } + if a { Ok(1) } else { Err(()) } } // should not be linted @@ -143,20 +127,12 @@ fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { // should not be linted fn issue_6640_3() -> Option<()> { - if true { - Some(()) - } else { - None - } + if true { Some(()) } else { None } } // should not be linted fn issue_6640_4() -> Result<(), ()> { - if true { - Ok(()) - } else { - Err(()) - } + if true { Ok(()) } else { Err(()) } } fn main() { diff --git a/tests/ui/unnecessary_wraps.stderr b/tests/ui/unnecessary_wraps.stderr index 9a861c61a4679..0e570397e2a29 100644 --- a/tests/ui/unnecessary_wraps.stderr +++ b/tests/ui/unnecessary_wraps.stderr @@ -32,8 +32,7 @@ LL | / fn func2(a: bool, b: bool) -> Option { LL | | if a && b { LL | | return Some(10); LL | | } -... | -LL | | } +LL | | if a { Some(20) } else { Some(30) } LL | | } | |_^ | @@ -45,14 +44,11 @@ help: ...and then change returning expressions | LL | return 10; LL | } -LL | if a { -LL | 20 -LL | } else { -LL | 30 +LL | if a { 20 } else { 30 } | error: this function's return value is unnecessarily wrapped by `Option` - --> $DIR/unnecessary_wraps.rs:51:1 + --> $DIR/unnecessary_wraps.rs:39:1 | LL | / fn func5() -> Option { LL | | Some(1) @@ -69,7 +65,7 @@ LL | 1 | error: this function's return value is unnecessarily wrapped by `Result` - --> $DIR/unnecessary_wraps.rs:61:1 + --> $DIR/unnecessary_wraps.rs:49:1 | LL | / fn func7() -> Result { LL | | Ok(1) @@ -86,7 +82,7 @@ LL | 1 | error: this function's return value is unnecessarily wrapped by `Option` - --> $DIR/unnecessary_wraps.rs:93:5 + --> $DIR/unnecessary_wraps.rs:77:5 | LL | / fn func12() -> Option { LL | | Some(1) @@ -103,7 +99,7 @@ LL | 1 | error: this function's return value is unnecessary - --> $DIR/unnecessary_wraps.rs:120:1 + --> $DIR/unnecessary_wraps.rs:104:1 | LL | / fn issue_6640_1(a: bool, b: bool) -> Option<()> { LL | | if a && b { @@ -129,7 +125,7 @@ LL | } else { ... error: this function's return value is unnecessary - --> $DIR/unnecessary_wraps.rs:133:1 + --> $DIR/unnecessary_wraps.rs:117:1 | LL | / fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { LL | | if a && b { diff --git a/tests/ui/upper_case_acronyms.rs b/tests/ui/upper_case_acronyms.rs index fdf8905f812f6..735909887acb1 100644 --- a/tests/ui/upper_case_acronyms.rs +++ b/tests/ui/upper_case_acronyms.rs @@ -16,7 +16,8 @@ enum Flags { FIN, } -struct GCCLLVMSomething; // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of - // `GccLlvmSomething` +// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of +// `GccLlvmSomething` +struct GCCLLVMSomething; fn main() {} diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 95e7bc754310f..2b22a2ed2d565 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -329,11 +329,7 @@ mod issue4140 { type To = Self; fn from(value: bool) -> Self { - if value { - 100 - } else { - 0 - } + if value { 100 } else { 0 } } } } diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 75424f341597d..609625abdec0a 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -329,11 +329,7 @@ mod issue4140 { type To = Self; fn from(value: bool) -> Self { - if value { - 100 - } else { - 0 - } + if value { 100 } else { 0 } } } } diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 37dfef7cfe0e5..e1410d2e652c1 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -169,7 +169,7 @@ LL | type To = T::To; | ^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:457:13 + --> $DIR/use_self.rs:453:13 | LL | A::new::(submod::B {}) | ^ help: use the applicable keyword: `Self` From 2c485e36cdd76bc887278820822ffc053c5b3b83 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 1 Mar 2021 17:25:23 -0500 Subject: [PATCH 053/226] Don't move `yield` or inline assembly into closure --- clippy_lints/src/manual_map.rs | 7 +++++- tests/ui/manual_map_option.fixed | 13 +++++++++++ tests/ui/manual_map_option.rs | 13 +++++++++++ tests/ui/manual_map_option.stderr | 38 +++++++++++++++---------------- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/manual_map.rs b/clippy_lints/src/manual_map.rs index 983a10e8eaa22..ac1d51e1993b4 100644 --- a/clippy_lints/src/manual_map.rs +++ b/clippy_lints/src/manual_map.rs @@ -203,7 +203,12 @@ fn can_move_expr_to_closure(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> boo fn visit_expr(&mut self, e: &'tcx Expr<'_>) { match e.kind { - ExprKind::Break(..) | ExprKind::Continue(_) | ExprKind::Ret(_) => { + ExprKind::Break(..) + | ExprKind::Continue(_) + | ExprKind::Ret(_) + | ExprKind::Yield(..) + | ExprKind::InlineAsm(_) + | ExprKind::LlvmInlineAsm(_) => { self.make_closure = false; }, // Accessing a field of a local value can only be done if the type isn't diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed index e6fa10d22e1eb..9222aaf6c789c 100644 --- a/tests/ui/manual_map_option.fixed +++ b/tests/ui/manual_map_option.fixed @@ -1,3 +1,4 @@ +// edition:2018 // run-rustfix #![warn(clippy::manual_map)] @@ -115,4 +116,16 @@ fn main() { Some(0).map(|x| vec![x]); option_env!("").map(String::from); + + // #6819 + async fn f2(x: u32) -> u32 { + x + } + + async fn f3() { + match Some(0) { + Some(x) => Some(f2(x).await), + None => None, + }; + } } diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index 7c2100299a719..1ccb450619c69 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -1,3 +1,4 @@ +// edition:2018 // run-rustfix #![warn(clippy::manual_map)] @@ -173,4 +174,16 @@ fn main() { Some(x) => Some(String::from(x)), None => None, }; + + // #6819 + async fn f2(x: u32) -> u32 { + x + } + + async fn f3() { + match Some(0) { + Some(x) => Some(f2(x).await), + None => None, + }; + } } diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr index 2d13213cf679b..d9f86eecd93f6 100644 --- a/tests/ui/manual_map_option.stderr +++ b/tests/ui/manual_map_option.stderr @@ -1,5 +1,5 @@ error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:13:5 + --> $DIR/manual_map_option.rs:14:5 | LL | / match Some(0) { LL | | Some(_) => Some(2), @@ -10,7 +10,7 @@ LL | | }; = note: `-D clippy::manual-map` implied by `-D warnings` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:18:5 + --> $DIR/manual_map_option.rs:19:5 | LL | / match Some(0) { LL | | Some(x) => Some(x + 1), @@ -19,7 +19,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x + 1)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:23:5 + --> $DIR/manual_map_option.rs:24:5 | LL | / match Some("") { LL | | Some(x) => Some(x.is_empty()), @@ -28,7 +28,7 @@ LL | | }; | |_____^ help: try this: `Some("").map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:28:5 + --> $DIR/manual_map_option.rs:29:5 | LL | / if let Some(x) = Some(0) { LL | | Some(!x) @@ -38,7 +38,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| !x)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:35:5 + --> $DIR/manual_map_option.rs:36:5 | LL | / match Some(0) { LL | | Some(x) => { Some(std::convert::identity(x)) } @@ -47,7 +47,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(std::convert::identity)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:40:5 + --> $DIR/manual_map_option.rs:41:5 | LL | / match Some(&String::new()) { LL | | Some(x) => Some(str::len(x)), @@ -56,7 +56,7 @@ LL | | }; | |_____^ help: try this: `Some(&String::new()).map(|x| str::len(x))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:50:5 + --> $DIR/manual_map_option.rs:51:5 | LL | / match &Some([0, 1]) { LL | | Some(x) => Some(x[0]), @@ -65,7 +65,7 @@ LL | | }; | |_____^ help: try this: `Some([0, 1]).as_ref().map(|x| x[0])` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:55:5 + --> $DIR/manual_map_option.rs:56:5 | LL | / match &Some(0) { LL | | &Some(x) => Some(x * 2), @@ -74,7 +74,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x * 2)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:60:5 + --> $DIR/manual_map_option.rs:61:5 | LL | / match Some(String::new()) { LL | | Some(ref x) => Some(x.is_empty()), @@ -83,7 +83,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:65:5 + --> $DIR/manual_map_option.rs:66:5 | LL | / match &&Some(String::new()) { LL | | Some(x) => Some(x.len()), @@ -92,7 +92,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:70:5 + --> $DIR/manual_map_option.rs:71:5 | LL | / match &&Some(0) { LL | | &&Some(x) => Some(x + x), @@ -101,7 +101,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x + x)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:83:9 + --> $DIR/manual_map_option.rs:84:9 | LL | / match &mut Some(String::new()) { LL | | Some(x) => Some(x.push_str("")), @@ -110,7 +110,7 @@ LL | | }; | |_________^ help: try this: `Some(String::new()).as_mut().map(|x| x.push_str(""))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:89:5 + --> $DIR/manual_map_option.rs:90:5 | LL | / match &mut Some(String::new()) { LL | | Some(ref x) => Some(x.len()), @@ -119,7 +119,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:94:5 + --> $DIR/manual_map_option.rs:95:5 | LL | / match &mut &Some(String::new()) { LL | | Some(x) => Some(x.is_empty()), @@ -128,7 +128,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:99:5 + --> $DIR/manual_map_option.rs:100:5 | LL | / match Some((0, 1, 2)) { LL | | Some((x, y, z)) => Some(x + y + z), @@ -137,7 +137,7 @@ LL | | }; | |_____^ help: try this: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:104:5 + --> $DIR/manual_map_option.rs:105:5 | LL | / match Some([1, 2, 3]) { LL | | Some([first, ..]) => Some(first), @@ -146,7 +146,7 @@ LL | | }; | |_____^ help: try this: `Some([1, 2, 3]).map(|[first, ..]| first)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:109:5 + --> $DIR/manual_map_option.rs:110:5 | LL | / match &Some((String::new(), "test")) { LL | | Some((x, y)) => Some((y, x)), @@ -155,7 +155,7 @@ LL | | }; | |_____^ help: try this: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:167:5 + --> $DIR/manual_map_option.rs:168:5 | LL | / match Some(0) { LL | | Some(x) => Some(vec![x]), @@ -164,7 +164,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| vec![x])` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:172:5 + --> $DIR/manual_map_option.rs:173:5 | LL | / match option_env!("") { LL | | Some(x) => Some(String::from(x)), From f21320fd74490ba98f1ebca60c85626dd4d9e12d Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 1 Mar 2021 22:55:26 -0500 Subject: [PATCH 054/226] Use diagnostic or language items instead of paths --- ...se_sensitive_file_extension_comparisons.rs | 7 +- clippy_lints/src/derive.rs | 4 +- clippy_lints/src/lifetimes.rs | 11 +- clippy_lints/src/map_clone.rs | 4 +- clippy_lints/src/redundant_clone.rs | 2 +- clippy_lints/src/types.rs | 127 ++++++++++-------- clippy_utils/src/lib.rs | 26 +++- clippy_utils/src/paths.rs | 7 - 8 files changed, 106 insertions(+), 82 deletions(-) diff --git a/clippy_lints/src/case_sensitive_file_extension_comparisons.rs b/clippy_lints/src/case_sensitive_file_extension_comparisons.rs index 6969ac949d845..b15fe65352ab1 100644 --- a/clippy_lints/src/case_sensitive_file_extension_comparisons.rs +++ b/clippy_lints/src/case_sensitive_file_extension_comparisons.rs @@ -1,12 +1,11 @@ -use crate::utils::paths::STRING; -use crate::utils::{match_def_path, span_lint_and_help}; +use crate::utils::span_lint_and_help; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_hir::{Expr, ExprKind, PathSegment}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{source_map::Spanned, Span}; +use rustc_span::{source_map::Spanned, symbol::sym, Span}; declare_clippy_lint! { /// **What it does:** @@ -59,7 +58,7 @@ fn check_case_sensitive_file_extension_comparison(ctx: &LateContext<'_>, expr: & return Some(span); }, ty::Adt(&ty::AdtDef { did, .. }, _) => { - if match_def_path(ctx, did, &STRING) { + if ctx.tcx.is_diagnostic_item(sym::string_type, did) { return Some(span); } }, diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index e8510bde9adcd..382a045a3f7cc 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -1,6 +1,6 @@ use crate::utils::paths; use crate::utils::{ - get_trait_def_id, is_allowed, is_automatically_derived, is_copy, match_def_path, match_path, span_lint_and_help, + get_trait_def_id, is_allowed, is_automatically_derived, is_copy, match_def_path, span_lint_and_help, span_lint_and_note, span_lint_and_then, }; use if_chain::if_chain; @@ -293,7 +293,7 @@ fn check_ord_partial_ord<'tcx>( /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>) { - if match_path(&trait_ref.path, &paths::CLONE_TRAIT) { + if cx.tcx.lang_items().clone_trait() == trait_ref.trait_def_id() { if !is_copy(cx, ty) { return; } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 50e6383263dd3..5fed58b821097 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -1,5 +1,4 @@ -use crate::utils::paths; -use crate::utils::{get_trait_def_id, in_macro, span_lint, trait_ref_of_method}; +use crate::utils::{in_macro, span_lint, trait_ref_of_method}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::intravisit::{ walk_fn_decl, walk_generic_param, walk_generics, walk_item, walk_param_bound, walk_poly_trait_ref, walk_ty, @@ -8,8 +7,8 @@ use rustc_hir::intravisit::{ use rustc_hir::FnRetTy::Return; use rustc_hir::{ BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, - ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier, TraitFn, - TraitItem, TraitItemKind, Ty, TyKind, WhereClause, WherePredicate, + ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier, + TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereClause, WherePredicate, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::map::Map; @@ -300,7 +299,7 @@ fn unique_lifetimes(lts: &[RefLt]) -> usize { lts.iter().collect::>().len() } -const CLOSURE_TRAIT_BOUNDS: [&[&str]; 3] = [&paths::FN, &paths::FN_MUT, &paths::FN_ONCE]; +const CLOSURE_TRAIT_BOUNDS: [LangItem; 3] = [LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]; /// A visitor usable for `rustc_front::visit::walk_ty()`. struct RefVisitor<'a, 'tcx> { @@ -361,7 +360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { let trait_ref = &poly_tref.trait_ref; if CLOSURE_TRAIT_BOUNDS .iter() - .any(|trait_path| trait_ref.trait_def_id() == get_trait_def_id(self.cx, trait_path)) + .any(|&item| trait_ref.trait_def_id() == self.cx.tcx.lang_items().items()[item as usize]) { let mut sub_visitor = RefVisitor::new(self.cx); sub_visitor.visit_trait_ref(trait_ref); diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index bd0be88028904..0c358e2e538b1 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -79,7 +79,9 @@ impl<'tcx> LateLintPass<'tcx> for MapClone { }, hir::ExprKind::MethodCall(ref method, _, [obj], _) => if_chain! { if ident_eq(name, obj) && method.ident.name == sym::clone; - if match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT); + if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id); + if let Some(trait_id) = cx.tcx.trait_of_item(fn_id); + if Some(trait_id) == cx.tcx.lang_items().clone_trait(); // no autoderefs if !cx.typeck_results().expr_adjustments(obj).iter() .any(|a| matches!(a.kind, Adjust::Deref(Some(..)))); diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index 06adbb523d706..d74ba10ac506f 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -165,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { if let Some((pred_fn_def_id, pred_arg, pred_arg_ty, res)) = is_call_with_ref_arg(cx, mir, &pred_terminator.kind); if res == cloned; - if match_def_path(cx, pred_fn_def_id, &paths::DEREF_TRAIT_METHOD); + if cx.tcx.is_diagnostic_item(sym::deref_method, pred_fn_def_id); if match_type(cx, pred_arg_ty, &paths::PATH_BUF) || match_type(cx, pred_arg_ty, &paths::OS_STRING); then { diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index f71b1651bfe9b..d1d9ef7d90219 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -11,8 +11,8 @@ use rustc_hir as hir; use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; use rustc_hir::{ BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericBounds, GenericParamKind, HirId, - ImplItem, ImplItemKind, Item, ItemKind, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt, - StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp, + ImplItem, ImplItemKind, Item, ItemKind, LangItem, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node, + QPath, Stmt, StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -23,7 +23,7 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::Span; -use rustc_span::symbol::sym; +use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::LayoutOf; use rustc_target::spec::abi::Abi; use rustc_typeck::hir_ty_to_ty; @@ -32,9 +32,9 @@ use crate::consts::{constant, Constant}; use crate::utils::paths; use crate::utils::sugg::Sugg; use crate::utils::{ - clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant, - is_type_diagnostic_item, last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args, - multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, + clip, comparisons, differing_macro_contexts, get_qpath_generic_tys, higher, in_constant, indent_of, int_bits, + is_hir_ty_cfg_dependant, is_type_diagnostic_item, last_path_segment, match_def_path, match_path, meets_msrv, + method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext, }; @@ -287,37 +287,55 @@ impl<'tcx> LateLintPass<'tcx> for Types { } } -/// Checks if `qpath` has last segment with type parameter matching `path` -fn match_type_parameter(cx: &LateContext<'_>, qpath: &QPath<'_>, path: &[&str]) -> Option { - let last = last_path_segment(qpath); - if_chain! { - if let Some(ref params) = last.args; - if !params.parenthesized; - if let Some(ty) = params.args.iter().find_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty), - _ => None, - }); - if let TyKind::Path(ref qpath) = ty.kind; - if let Some(did) = cx.qpath_res(qpath, ty.hir_id).opt_def_id(); - if match_def_path(cx, did, path); - then { - return Some(ty.span); - } +/// Checks if the first type parameter is a lang item. +fn is_ty_param_lang_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: LangItem) -> Option<&'tcx hir::Ty<'tcx>> { + let ty = get_qpath_generic_tys(qpath).next()?; + + if let TyKind::Path(qpath) = &ty.kind { + cx.qpath_res(qpath, ty.hir_id) + .opt_def_id() + .and_then(|id| (cx.tcx.lang_items().items()[item as usize] == Some(id)).then(|| ty)) + } else { + None } - None } -fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { - if match_type_parameter(cx, qpath, &paths::STRING).is_some() { - return Some("str"); +/// Checks if the first type parameter is a diagnostic item. +fn is_ty_param_diagnostic_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: Symbol) -> Option<&'tcx hir::Ty<'tcx>> { + let ty = get_qpath_generic_tys(qpath).next()?; + + if let TyKind::Path(qpath) = &ty.kind { + cx.qpath_res(qpath, ty.hir_id) + .opt_def_id() + .and_then(|id| cx.tcx.is_diagnostic_item(item, id).then(|| ty)) + } else { + None } - if match_type_parameter(cx, qpath, &paths::OS_STRING).is_some() { - return Some("std::ffi::OsStr"); +} + +/// Checks if the first type parameter is a given item. +fn is_ty_param_path(cx: &LateContext<'_>, qpath: &QPath<'tcx>, path: &[&str]) -> Option<&'tcx hir::Ty<'tcx>> { + let ty = get_qpath_generic_tys(qpath).next()?; + + if let TyKind::Path(qpath) = &ty.kind { + cx.qpath_res(qpath, ty.hir_id) + .opt_def_id() + .and_then(|id| match_def_path(cx, id, path).then(|| ty)) + } else { + None } - if match_type_parameter(cx, qpath, &paths::PATH_BUF).is_some() { - return Some("std::path::Path"); +} + +fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { + if is_ty_param_diagnostic_item(cx, qpath, sym::string_type).is_some() { + Some("str") + } else if is_ty_param_path(cx, qpath, &paths::OS_STRING).is_some() { + Some("std::ffi::OsStr") + } else if is_ty_param_path(cx, qpath, &paths::PATH_BUF).is_some() { + Some("std::path::Path") + } else { + None } - None } fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option { @@ -381,7 +399,7 @@ impl Types { ); return; // don't recurse into the type } - if match_type_parameter(cx, qpath, &paths::VEC).is_some() { + if is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() { span_lint_and_help( cx, BOX_VEC, @@ -393,7 +411,7 @@ impl Types { return; // don't recurse into the type } } else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { - if let Some(span) = match_type_parameter(cx, qpath, &paths::RC) { + if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, @@ -401,21 +419,18 @@ impl Types { hir_ty.span, "usage of `Rc>`", "try", - snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), + snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(), applicability, ); return; // don't recurse into the type } - if match_type_parameter(cx, qpath, &paths::BOX).is_some() { - let box_ty = match &last_path_segment(qpath).args.unwrap().args[0] { - GenericArg::Type(ty) => match &ty.kind { - TyKind::Path(qpath) => qpath, - _ => return, - }, + if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) { + let qpath = match &ty.kind { + TyKind::Path(qpath) => qpath, _ => return, }; - let inner_span = match &last_path_segment(&box_ty).args.unwrap().args[0] { - GenericArg::Type(ty) => ty.span, + let inner_span = match get_qpath_generic_tys(qpath).next() { + Some(ty) => ty.span, _ => return, }; let mut applicability = Applicability::MachineApplicable; @@ -445,16 +460,13 @@ impl Types { ); return; // don't recurse into the type } - if match_type_parameter(cx, qpath, &paths::VEC).is_some() { - let vec_ty = match &last_path_segment(qpath).args.unwrap().args[0] { - GenericArg::Type(ty) => match &ty.kind { - TyKind::Path(qpath) => qpath, - _ => return, - }, + if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { + let qpath = match &ty.kind { + TyKind::Path(qpath) => qpath, _ => return, }; - let inner_span = match &last_path_segment(&vec_ty).args.unwrap().args[0] { - GenericArg::Type(ty) => ty.span, + let inner_span = match get_qpath_generic_tys(qpath).next() { + Some(ty) => ty.span, _ => return, }; let mut applicability = Applicability::MachineApplicable; @@ -498,16 +510,13 @@ impl Types { ); return; // don't recurse into the type } - if match_type_parameter(cx, qpath, &paths::VEC).is_some() { - let vec_ty = match &last_path_segment(qpath).args.unwrap().args[0] { - GenericArg::Type(ty) => match &ty.kind { - TyKind::Path(qpath) => qpath, - _ => return, - }, + if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { + let qpath = match &ty.kind { + TyKind::Path(qpath) => qpath, _ => return, }; - let inner_span = match &last_path_segment(&vec_ty).args.unwrap().args[0] { - GenericArg::Type(ty) => ty.span, + let inner_span = match get_qpath_generic_tys(qpath).next() { + Some(ty) => ty.span, _ => return, }; let mut applicability = Applicability::MachineApplicable; @@ -563,7 +572,7 @@ impl Types { } } } else if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { - if match_type_parameter(cx, qpath, &paths::OPTION).is_some() { + if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { span_lint( cx, OPTION_OPTION, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 2380ea4c7bfae..08e260b7d94ac 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -62,8 +62,9 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::Node; use rustc_hir::{ - def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind, - MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, TyKind, Unsafety, + def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, GenericArgs, HirId, ImplItem, ImplItemKind, Item, + ItemKind, MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, TyKind, + Unsafety, }; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, Level, Lint, LintContext}; @@ -271,6 +272,27 @@ pub fn last_path_segment<'tcx>(path: &QPath<'tcx>) -> &'tcx PathSegment<'tcx> { } } +pub fn get_qpath_generics(path: &QPath<'tcx>) -> Option<&'tcx GenericArgs<'tcx>> { + match path { + QPath::Resolved(_, p) => p.segments.last().and_then(|s| s.args), + QPath::TypeRelative(_, s) => s.args, + QPath::LangItem(..) => None, + } +} + +pub fn get_qpath_generic_tys(path: &QPath<'tcx>) -> impl Iterator> { + get_qpath_generics(path) + .map_or([].as_ref(), |a| a.args) + .iter() + .filter_map(|a| { + if let hir::GenericArg::Type(ty) = a { + Some(ty) + } else { + None + } + }) +} + pub fn single_segment_path<'tcx>(path: &QPath<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { match *path { QPath::Resolved(_, ref path) => path.segments.get(0), diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index e617867964753..14c38459ddeae 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -12,11 +12,9 @@ pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"]; pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"]; pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"]; pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"]; -pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"]; pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"]; pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"]; pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"]; -pub const CLONE_TRAIT: [&str; 3] = ["core", "clone", "Clone"]; pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"]; pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"]; pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"]; @@ -43,9 +41,6 @@ pub const FILE_TYPE: [&str; 3] = ["std", "fs", "FileType"]; pub const FMT_ARGUMENTS_NEW_V1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"]; pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"]; pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"]; -pub const FN: [&str; 3] = ["core", "ops", "Fn"]; -pub const FN_MUT: [&str; 3] = ["core", "ops", "FnMut"]; -pub const FN_ONCE: [&str; 3] = ["core", "ops", "FnOnce"]; pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"]; pub const FROM_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "FromIterator"]; pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"]; @@ -114,7 +109,6 @@ pub const PTR_SLICE_FROM_RAW_PARTS_MUT: [&str; 3] = ["core", "ptr", "slice_from_ pub const PTR_SWAP_NONOVERLAPPING: [&str; 3] = ["core", "ptr", "swap_nonoverlapping"]; pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"]; pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; -pub const RC: [&str; 3] = ["alloc", "rc", "Rc"]; pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"]; pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"]; pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"]; @@ -143,7 +137,6 @@ pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"]; pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"]; pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"]; pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"]; -pub const STRING: [&str; 3] = ["alloc", "string", "String"]; pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"]; pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"]; pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "", "ends_with"]; From 62ac4bd1b2b94cb97f61d7f42fdd4fcd8794d2b0 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 7 Feb 2021 13:35:27 +0100 Subject: [PATCH 055/226] create loops dir; arrange manual_flatten lint and utils --- clippy_lints/src/loops/manual_flatten.rs | 78 +++++++++++++ clippy_lints/src/{loops.rs => loops/mod.rs} | 121 ++------------------ clippy_lints/src/loops/utils.rs | 40 +++++++ 3 files changed, 127 insertions(+), 112 deletions(-) create mode 100644 clippy_lints/src/loops/manual_flatten.rs rename clippy_lints/src/{loops.rs => loops/mod.rs} (95%) create mode 100644 clippy_lints/src/loops/utils.rs diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs new file mode 100644 index 0000000000000..b5881a1b8c47c --- /dev/null +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -0,0 +1,78 @@ +use super::utils::make_iterator_snippet; +use crate::utils::{is_ok_ctor, is_some_ctor, path_to_local_id, span_lint_and_then}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, StmtKind}; +use rustc_lint::LateContext; +use rustc_span::source_map::Span; + +/// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the +/// iterator element is used. +pub(super) fn lint<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + span: Span, +) { + if let ExprKind::Block(ref block, _) = body.kind { + // Ensure the `if let` statement is the only expression or statement in the for-loop + let inner_expr = if block.stmts.len() == 1 && block.expr.is_none() { + let match_stmt = &block.stmts[0]; + if let StmtKind::Semi(inner_expr) = match_stmt.kind { + Some(inner_expr) + } else { + None + } + } else if block.stmts.is_empty() { + block.expr + } else { + None + }; + + if_chain! { + if let Some(inner_expr) = inner_expr; + if let ExprKind::Match( + ref match_expr, ref match_arms, MatchSource::IfLetDesugar{ contains_else_clause: false } + ) = inner_expr.kind; + // Ensure match_expr in `if let` statement is the same as the pat from the for-loop + if let PatKind::Binding(_, pat_hir_id, _, _) = pat.kind; + if path_to_local_id(match_expr, pat_hir_id); + // Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result` + if let PatKind::TupleStruct(QPath::Resolved(None, path), _, _) = match_arms[0].pat.kind; + let some_ctor = is_some_ctor(cx, path.res); + let ok_ctor = is_ok_ctor(cx, path.res); + if some_ctor || ok_ctor; + let if_let_type = if some_ctor { "Some" } else { "Ok" }; + + then { + // Prepare the error message + let msg = format!("unnecessary `if let` since only the `{}` variant of the iterator element is used", if_let_type); + + // Prepare the help message + let mut applicability = Applicability::MaybeIncorrect; + let arg_snippet = make_iterator_snippet(cx, arg, &mut applicability); + + span_lint_and_then( + cx, + super::MANUAL_FLATTEN, + span, + &msg, + |diag| { + let sugg = format!("{}.flatten()", arg_snippet); + diag.span_suggestion( + arg.span, + "try", + sugg, + Applicability::MaybeIncorrect, + ); + diag.span_help( + inner_expr.span, + "...and remove the `if let` statement in the for loop", + ); + } + ); + } + } + } +} diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops/mod.rs similarity index 95% rename from clippy_lints/src/loops.rs rename to clippy_lints/src/loops/mod.rs index 711cd5b3b15cc..18b7e96d42cb4 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,13 +1,16 @@ +mod manual_flatten; +mod utils; + use crate::consts::constant; use crate::utils::sugg::Sugg; use crate::utils::usage::mutated_variables; use crate::utils::visitors::LocalUsedVisitor; use crate::utils::{ contains_name, get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, - indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_ok_ctor, is_refutable, is_some_ctor, - is_type_diagnostic_item, last_path_segment, match_trait_method, match_type, multispan_sugg, path_to_local, - path_to_local_id, paths, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, - span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, SpanlessEq, + indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, + last_path_segment, match_trait_method, match_type, multispan_sugg, path_to_local, path_to_local_id, paths, + single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, + span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, SpanlessEq, }; use if_chain::if_chain; use rustc_ast::ast; @@ -31,6 +34,7 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use std::iter::{once, Iterator}; use std::mem; +use utils::make_iterator_snippet; declare_clippy_lint! { /// **What it does:** Checks for for-loops that manually copy items between @@ -862,7 +866,7 @@ fn check_for_loop<'tcx>( check_for_mut_range_bound(cx, arg, body); check_for_single_element_loop(cx, pat, arg, body, expr); detect_same_item_push(cx, pat, arg, body, expr); - check_manual_flatten(cx, pat, arg, body, span); + manual_flatten::lint(cx, pat, arg, body, span); } // this function assumes the given expression is a `for` loop. @@ -1839,42 +1843,6 @@ fn check_for_loop_explicit_counter<'tcx>( } } -/// If `arg` was the argument to a `for` loop, return the "cleanest" way of writing the -/// actual `Iterator` that the loop uses. -fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String { - let impls_iterator = get_trait_def_id(cx, &paths::ITERATOR).map_or(false, |id| { - implements_trait(cx, cx.typeck_results().expr_ty(arg), id, &[]) - }); - if impls_iterator { - format!( - "{}", - sugg::Sugg::hir_with_applicability(cx, arg, "_", applic_ref).maybe_par() - ) - } else { - // (&x).into_iter() ==> x.iter() - // (&mut x).into_iter() ==> x.iter_mut() - match &arg.kind { - ExprKind::AddrOf(BorrowKind::Ref, mutability, arg_inner) - if has_iter_method(cx, cx.typeck_results().expr_ty(&arg_inner)).is_some() => - { - let meth_name = match mutability { - Mutability::Mut => "iter_mut", - Mutability::Not => "iter", - }; - format!( - "{}.{}()", - sugg::Sugg::hir_with_applicability(cx, &arg_inner, "_", applic_ref).maybe_par(), - meth_name, - ) - } - _ => format!( - "{}.into_iter()", - sugg::Sugg::hir_with_applicability(cx, arg, "_", applic_ref).maybe_par() - ), - } - } -} - /// Checks for the `FOR_KV_MAP` lint. fn check_for_loop_over_map_kv<'tcx>( cx: &LateContext<'tcx>, @@ -1964,77 +1932,6 @@ fn check_for_single_element_loop<'tcx>( } } -/// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the -/// iterator element is used. -fn check_manual_flatten<'tcx>( - cx: &LateContext<'tcx>, - pat: &'tcx Pat<'_>, - arg: &'tcx Expr<'_>, - body: &'tcx Expr<'_>, - span: Span, -) { - if let ExprKind::Block(ref block, _) = body.kind { - // Ensure the `if let` statement is the only expression or statement in the for-loop - let inner_expr = if block.stmts.len() == 1 && block.expr.is_none() { - let match_stmt = &block.stmts[0]; - if let StmtKind::Semi(inner_expr) = match_stmt.kind { - Some(inner_expr) - } else { - None - } - } else if block.stmts.is_empty() { - block.expr - } else { - None - }; - - if_chain! { - if let Some(inner_expr) = inner_expr; - if let ExprKind::Match( - ref match_expr, ref match_arms, MatchSource::IfLetDesugar{ contains_else_clause: false } - ) = inner_expr.kind; - // Ensure match_expr in `if let` statement is the same as the pat from the for-loop - if let PatKind::Binding(_, pat_hir_id, _, _) = pat.kind; - if path_to_local_id(match_expr, pat_hir_id); - // Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result` - if let PatKind::TupleStruct(QPath::Resolved(None, path), _, _) = match_arms[0].pat.kind; - let some_ctor = is_some_ctor(cx, path.res); - let ok_ctor = is_ok_ctor(cx, path.res); - if some_ctor || ok_ctor; - let if_let_type = if some_ctor { "Some" } else { "Ok" }; - - then { - // Prepare the error message - let msg = format!("unnecessary `if let` since only the `{}` variant of the iterator element is used", if_let_type); - - // Prepare the help message - let mut applicability = Applicability::MaybeIncorrect; - let arg_snippet = make_iterator_snippet(cx, arg, &mut applicability); - - span_lint_and_then( - cx, - MANUAL_FLATTEN, - span, - &msg, - |diag| { - let sugg = format!("{}.flatten()", arg_snippet); - diag.span_suggestion( - arg.span, - "try", - sugg, - Applicability::MaybeIncorrect, - ); - diag.span_help( - inner_expr.span, - "...and remove the `if let` statement in the for loop", - ); - } - ); - } - } - } -} - struct MutatePairDelegate<'a, 'tcx> { cx: &'a LateContext<'tcx>, hir_id_low: Option, diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs new file mode 100644 index 0000000000000..b06df2d75f3be --- /dev/null +++ b/clippy_lints/src/loops/utils.rs @@ -0,0 +1,40 @@ +use crate::utils::{get_trait_def_id, has_iter_method, implements_trait, paths, sugg}; +use rustc_errors::Applicability; +use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; +use rustc_lint::LateContext; + +/// If `arg` was the argument to a `for` loop, return the "cleanest" way of writing the +/// actual `Iterator` that the loop uses. +pub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String { + let impls_iterator = get_trait_def_id(cx, &paths::ITERATOR).map_or(false, |id| { + implements_trait(cx, cx.typeck_results().expr_ty(arg), id, &[]) + }); + if impls_iterator { + format!( + "{}", + sugg::Sugg::hir_with_applicability(cx, arg, "_", applic_ref).maybe_par() + ) + } else { + // (&x).into_iter() ==> x.iter() + // (&mut x).into_iter() ==> x.iter_mut() + match &arg.kind { + ExprKind::AddrOf(BorrowKind::Ref, mutability, arg_inner) + if has_iter_method(cx, cx.typeck_results().expr_ty(&arg_inner)).is_some() => + { + let meth_name = match mutability { + Mutability::Mut => "iter_mut", + Mutability::Not => "iter", + }; + format!( + "{}.{}()", + sugg::Sugg::hir_with_applicability(cx, &arg_inner, "_", applic_ref).maybe_par(), + meth_name, + ) + } + _ => format!( + "{}.into_iter()", + sugg::Sugg::hir_with_applicability(cx, arg, "_", applic_ref).maybe_par() + ), + } + } +} From 408368a82c2c394b65524cb995e01ecfc3c1867c Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 8 Feb 2021 20:47:35 +0100 Subject: [PATCH 056/226] Refactor check_for_loop_arg; rename manual_flatten's lint back to check_manual_flatten --- clippy_lints/src/loops/for_loop_arg.rs | 149 +++++++++++++++++++++++ clippy_lints/src/loops/manual_flatten.rs | 2 +- clippy_lints/src/loops/mod.rs | 147 +--------------------- 3 files changed, 154 insertions(+), 144 deletions(-) create mode 100644 clippy_lints/src/loops/for_loop_arg.rs diff --git a/clippy_lints/src/loops/for_loop_arg.rs b/clippy_lints/src/loops/for_loop_arg.rs new file mode 100644 index 0000000000000..b33e7183984da --- /dev/null +++ b/clippy_lints/src/loops/for_loop_arg.rs @@ -0,0 +1,149 @@ +use crate::utils::{ + is_type_diagnostic_item, match_trait_method, match_type, paths, snippet, snippet_with_applicability, span_lint, + span_lint_and_help, span_lint_and_sugg, +}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, Mutability, Pat}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty, TyS}; +use rustc_span::symbol::sym; + +pub(super) fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { + let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used + if let ExprKind::MethodCall(ref method, _, ref args, _) = arg.kind { + // just the receiver, no arguments + if args.len() == 1 { + let method_name = &*method.ident.as_str(); + // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x + if method_name == "iter" || method_name == "iter_mut" { + if is_ref_iterable_type(cx, &args[0]) { + lint_iter_method(cx, args, arg, method_name); + } + } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { + let receiver_ty = cx.typeck_results().expr_ty(&args[0]); + let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); + if TyS::same_type(receiver_ty, receiver_ty_adjusted) { + let mut applicability = Applicability::MachineApplicable; + let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); + span_lint_and_sugg( + cx, + super::EXPLICIT_INTO_ITER_LOOP, + arg.span, + "it is more concise to loop over containers instead of using explicit \ + iteration methods", + "to write this more concisely, try", + object.to_string(), + applicability, + ); + } else { + let ref_receiver_ty = cx.tcx.mk_ref( + cx.tcx.lifetimes.re_erased, + ty::TypeAndMut { + ty: receiver_ty, + mutbl: Mutability::Not, + }, + ); + if TyS::same_type(receiver_ty_adjusted, ref_receiver_ty) { + lint_iter_method(cx, args, arg, method_name) + } + } + } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { + span_lint( + cx, + super::ITER_NEXT_LOOP, + expr.span, + "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ + probably not what you want", + ); + next_loop_linted = true; + } + } + } + if !next_loop_linted { + check_arg_type(cx, pat, arg); + } +} + +/// Checks for `for` loops over `Option`s and `Result`s. +fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { + let ty = cx.typeck_results().expr_ty(arg); + if is_type_diagnostic_item(cx, ty, sym::option_type) { + span_lint_and_help( + cx, + super::FOR_LOOPS_OVER_FALLIBLES, + arg.span, + &format!( + "for loop over `{0}`, which is an `Option`. This is more readably written as an \ + `if let` statement", + snippet(cx, arg.span, "_") + ), + None, + &format!( + "consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`", + snippet(cx, pat.span, "_"), + snippet(cx, arg.span, "_") + ), + ); + } else if is_type_diagnostic_item(cx, ty, sym::result_type) { + span_lint_and_help( + cx, + super::FOR_LOOPS_OVER_FALLIBLES, + arg.span, + &format!( + "for loop over `{0}`, which is a `Result`. This is more readably written as an \ + `if let` statement", + snippet(cx, arg.span, "_") + ), + None, + &format!( + "consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`", + snippet(cx, pat.span, "_"), + snippet(cx, arg.span, "_") + ), + ); + } +} + +fn lint_iter_method(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { + let mut applicability = Applicability::MachineApplicable; + let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); + let muta = if method_name == "iter_mut" { "mut " } else { "" }; + span_lint_and_sugg( + cx, + super::EXPLICIT_ITER_LOOP, + arg.span, + "it is more concise to loop over references to containers instead of using explicit \ + iteration methods", + "to write this more concisely, try", + format!("&{}{}", muta, object), + applicability, + ) +} + +/// Returns `true` if the type of expr is one that provides `IntoIterator` impls +/// for `&T` and `&mut T`, such as `Vec`. +#[rustfmt::skip] +fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { + // no walk_ptrs_ty: calling iter() on a reference can make sense because it + // will allow further borrows afterwards + let ty = cx.typeck_results().expr_ty(e); + is_iterable_array(ty, cx) || + is_type_diagnostic_item(cx, ty, sym::vec_type) || + match_type(cx, ty, &paths::LINKED_LIST) || + is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || + is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || + is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + match_type(cx, ty, &paths::BINARY_HEAP) || + match_type(cx, ty, &paths::BTREEMAP) || + match_type(cx, ty, &paths::BTREESET) +} + +fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { + // IntoIterator is currently only implemented for array sizes <= 32 in rustc + match ty.kind() { + ty::Array(_, n) => n + .try_eval_usize(cx.tcx, cx.param_env) + .map_or(false, |val| (0..=32).contains(&val)), + _ => false, + } +} diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs index b5881a1b8c47c..db90d2c0468fc 100644 --- a/clippy_lints/src/loops/manual_flatten.rs +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -8,7 +8,7 @@ use rustc_span::source_map::Span; /// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the /// iterator element is used. -pub(super) fn lint<'tcx>( +pub(super) fn check_manual_flatten<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 18b7e96d42cb4..63eeb3607b699 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,3 +1,4 @@ +mod for_loop_arg; mod manual_flatten; mod utils; @@ -27,7 +28,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; use rustc_middle::middle::region; -use rustc_middle::ty::{self, Ty, TyS}; +use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -861,12 +862,12 @@ fn check_for_loop<'tcx>( check_for_loop_range(cx, pat, arg, body, expr); check_for_loop_explicit_counter(cx, pat, arg, body, expr); } - check_for_loop_arg(cx, pat, arg, expr); + for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); check_for_loop_over_map_kv(cx, pat, arg, body, expr); check_for_mut_range_bound(cx, arg, body); check_for_single_element_loop(cx, pat, arg, body, expr); detect_same_item_push(cx, pat, arg, body, expr); - manual_flatten::lint(cx, pat, arg, body, span); + manual_flatten::check_manual_flatten(cx, pat, arg, body, span); } // this function assumes the given expression is a `for` loop. @@ -1682,118 +1683,6 @@ fn is_end_eq_array_len<'tcx>( false } -fn lint_iter_method(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { - let mut applicability = Applicability::MachineApplicable; - let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); - let muta = if method_name == "iter_mut" { "mut " } else { "" }; - span_lint_and_sugg( - cx, - EXPLICIT_ITER_LOOP, - arg.span, - "it is more concise to loop over references to containers instead of using explicit \ - iteration methods", - "to write this more concisely, try", - format!("&{}{}", muta, object), - applicability, - ) -} - -fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { - let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used - if let ExprKind::MethodCall(ref method, _, ref args, _) = arg.kind { - // just the receiver, no arguments - if args.len() == 1 { - let method_name = &*method.ident.as_str(); - // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x - if method_name == "iter" || method_name == "iter_mut" { - if is_ref_iterable_type(cx, &args[0]) { - lint_iter_method(cx, args, arg, method_name); - } - } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { - let receiver_ty = cx.typeck_results().expr_ty(&args[0]); - let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); - if TyS::same_type(receiver_ty, receiver_ty_adjusted) { - let mut applicability = Applicability::MachineApplicable; - let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); - span_lint_and_sugg( - cx, - EXPLICIT_INTO_ITER_LOOP, - arg.span, - "it is more concise to loop over containers instead of using explicit \ - iteration methods", - "to write this more concisely, try", - object.to_string(), - applicability, - ); - } else { - let ref_receiver_ty = cx.tcx.mk_ref( - cx.tcx.lifetimes.re_erased, - ty::TypeAndMut { - ty: receiver_ty, - mutbl: Mutability::Not, - }, - ); - if TyS::same_type(receiver_ty_adjusted, ref_receiver_ty) { - lint_iter_method(cx, args, arg, method_name) - } - } - } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { - span_lint( - cx, - ITER_NEXT_LOOP, - expr.span, - "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ - probably not what you want", - ); - next_loop_linted = true; - } - } - } - if !next_loop_linted { - check_arg_type(cx, pat, arg); - } -} - -/// Checks for `for` loops over `Option`s and `Result`s. -fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { - let ty = cx.typeck_results().expr_ty(arg); - if is_type_diagnostic_item(cx, ty, sym::option_type) { - span_lint_and_help( - cx, - FOR_LOOPS_OVER_FALLIBLES, - arg.span, - &format!( - "for loop over `{0}`, which is an `Option`. This is more readably written as an \ - `if let` statement", - snippet(cx, arg.span, "_") - ), - None, - &format!( - "consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`", - snippet(cx, pat.span, "_"), - snippet(cx, arg.span, "_") - ), - ); - } else if is_type_diagnostic_item(cx, ty, sym::result_type) { - span_lint_and_help( - cx, - FOR_LOOPS_OVER_FALLIBLES, - arg.span, - &format!( - "for loop over `{0}`, which is a `Result`. This is more readably written as an \ - `if let` statement", - snippet(cx, arg.span, "_") - ), - None, - &format!( - "consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`", - snippet(cx, pat.span, "_"), - snippet(cx, arg.span, "_") - ), - ); - } -} - // To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be // incremented exactly once in the loop body, and initialized to zero // at the start of the loop. @@ -2270,34 +2159,6 @@ impl<'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor { } } -/// Returns `true` if the type of expr is one that provides `IntoIterator` impls -/// for `&T` and `&mut T`, such as `Vec`. -#[rustfmt::skip] -fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - // no walk_ptrs_ty: calling iter() on a reference can make sense because it - // will allow further borrows afterwards - let ty = cx.typeck_results().expr_ty(e); - is_iterable_array(ty, cx) || - is_type_diagnostic_item(cx, ty, sym::vec_type) || - match_type(cx, ty, &paths::LINKED_LIST) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || - is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || - match_type(cx, ty, &paths::BINARY_HEAP) || - match_type(cx, ty, &paths::BTREEMAP) || - match_type(cx, ty, &paths::BTREESET) -} - -fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { - // IntoIterator is currently only implemented for array sizes <= 32 in rustc - match ty.kind() { - ty::Array(_, n) => n - .try_eval_usize(cx.tcx, cx.param_env) - .map_or(false, |val| (0..=32).contains(&val)), - _ => false, - } -} - /// If a block begins with a statement (possibly a `let` binding) and has an /// expression, return it. fn extract_expr_from_first_stmt<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { From 7b0f588b7706f4ec212e7772084eb7c0e90cfb56 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 8 Feb 2021 21:04:33 +0100 Subject: [PATCH 057/226] Refactor check_for_loop_over_map_kv to its own module --- .../src/loops/for_loop_over_map_kv.rs | 69 +++++++++++++++++++ clippy_lints/src/loops/mod.rs | 67 +----------------- 2 files changed, 71 insertions(+), 65 deletions(-) create mode 100644 clippy_lints/src/loops/for_loop_over_map_kv.rs diff --git a/clippy_lints/src/loops/for_loop_over_map_kv.rs b/clippy_lints/src/loops/for_loop_over_map_kv.rs new file mode 100644 index 0000000000000..c5f0b0909ba64 --- /dev/null +++ b/clippy_lints/src/loops/for_loop_over_map_kv.rs @@ -0,0 +1,69 @@ +use crate::utils::visitors::LocalUsedVisitor; +use crate::utils::{is_type_diagnostic_item, match_type, multispan_sugg, paths, snippet, span_lint_and_then, sugg}; +use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; +use rustc_lint::LateContext; +use rustc_middle::ty; + +/// Checks for the `FOR_KV_MAP` lint. +pub(super) fn check_for_loop_over_map_kv<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, +) { + let pat_span = pat.span; + + if let PatKind::Tuple(ref pat, _) = pat.kind { + if pat.len() == 2 { + let arg_span = arg.span; + let (new_pat_span, kind, ty, mutbl) = match *cx.typeck_results().expr_ty(arg).kind() { + ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) { + (key, _) if pat_is_wild(key, body) => (pat[1].span, "value", ty, mutbl), + (_, value) if pat_is_wild(value, body) => (pat[0].span, "key", ty, Mutability::Not), + _ => return, + }, + _ => return, + }; + let mutbl = match mutbl { + Mutability::Not => "", + Mutability::Mut => "_mut", + }; + let arg = match arg.kind { + ExprKind::AddrOf(BorrowKind::Ref, _, ref expr) => &**expr, + _ => arg, + }; + + if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP) { + span_lint_and_then( + cx, + super::FOR_KV_MAP, + expr.span, + &format!("you seem to want to iterate on a map's {}s", kind), + |diag| { + let map = sugg::Sugg::hir(cx, arg, "map"); + multispan_sugg( + diag, + "use the corresponding method", + vec![ + (pat_span, snippet(cx, new_pat_span, kind).into_owned()), + (arg_span, format!("{}.{}s{}()", map.maybe_par(), kind, mutbl)), + ], + ); + }, + ); + } + } + } +} + +/// Returns `true` if the pattern is a `PatWild` or an ident prefixed with `_`. +fn pat_is_wild<'tcx>(pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { + match *pat { + PatKind::Wild => true, + PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => { + !LocalUsedVisitor::new(id).check_expr(body) + }, + _ => false, + } +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 63eeb3607b699..672f07318595f 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,4 +1,5 @@ mod for_loop_arg; +mod for_loop_over_map_kv; mod manual_flatten; mod utils; @@ -863,7 +864,7 @@ fn check_for_loop<'tcx>( check_for_loop_explicit_counter(cx, pat, arg, body, expr); } for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); - check_for_loop_over_map_kv(cx, pat, arg, body, expr); + for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); check_for_mut_range_bound(cx, arg, body); check_for_single_element_loop(cx, pat, arg, body, expr); detect_same_item_push(cx, pat, arg, body, expr); @@ -1732,59 +1733,6 @@ fn check_for_loop_explicit_counter<'tcx>( } } -/// Checks for the `FOR_KV_MAP` lint. -fn check_for_loop_over_map_kv<'tcx>( - cx: &LateContext<'tcx>, - pat: &'tcx Pat<'_>, - arg: &'tcx Expr<'_>, - body: &'tcx Expr<'_>, - expr: &'tcx Expr<'_>, -) { - let pat_span = pat.span; - - if let PatKind::Tuple(ref pat, _) = pat.kind { - if pat.len() == 2 { - let arg_span = arg.span; - let (new_pat_span, kind, ty, mutbl) = match *cx.typeck_results().expr_ty(arg).kind() { - ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) { - (key, _) if pat_is_wild(cx, key, body) => (pat[1].span, "value", ty, mutbl), - (_, value) if pat_is_wild(cx, value, body) => (pat[0].span, "key", ty, Mutability::Not), - _ => return, - }, - _ => return, - }; - let mutbl = match mutbl { - Mutability::Not => "", - Mutability::Mut => "_mut", - }; - let arg = match arg.kind { - ExprKind::AddrOf(BorrowKind::Ref, _, ref expr) => &**expr, - _ => arg, - }; - - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP) { - span_lint_and_then( - cx, - FOR_KV_MAP, - expr.span, - &format!("you seem to want to iterate on a map's {}s", kind), - |diag| { - let map = sugg::Sugg::hir(cx, arg, "map"); - multispan_sugg( - diag, - "use the corresponding method", - vec![ - (pat_span, snippet(cx, new_pat_span, kind).into_owned()), - (arg_span, format!("{}.{}s{}()", map.maybe_par(), kind, mutbl)), - ], - ); - }, - ); - } - } - } -} - fn check_for_single_element_loop<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, @@ -1927,17 +1875,6 @@ fn check_for_mutation<'tcx>( delegate.mutation_span() } -/// Returns `true` if the pattern is a `PatWild` or an ident prefixed with `_`. -fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { - match *pat { - PatKind::Wild => true, - PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => { - !LocalUsedVisitor::new(cx, id).check_expr(body) - }, - _ => false, - } -} - struct VarVisitor<'a, 'tcx> { /// context reference cx: &'a LateContext<'tcx>, From 6e4663dedf92f871471cc240069d270b65a8160b Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 8 Feb 2021 21:20:23 +0100 Subject: [PATCH 058/226] Refactor check_for_mut_range_bound to its own module --- clippy_lints/src/loops/for_mut_range_bound.rs | 114 ++++++++++++++++++ clippy_lints/src/loops/mod.rs | 111 +---------------- 2 files changed, 116 insertions(+), 109 deletions(-) create mode 100644 clippy_lints/src/loops/for_mut_range_bound.rs diff --git a/clippy_lints/src/loops/for_mut_range_bound.rs b/clippy_lints/src/loops/for_mut_range_bound.rs new file mode 100644 index 0000000000000..d305c55cb9515 --- /dev/null +++ b/clippy_lints/src/loops/for_mut_range_bound.rs @@ -0,0 +1,114 @@ +use crate::utils::{higher, path_to_local, span_lint}; +use if_chain::if_chain; +use rustc_hir::{BindingAnnotation, Expr, HirId, Node, PatKind}; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::source_map::Span; +use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; + +pub(super) fn check_for_mut_range_bound(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) { + if let Some(higher::Range { + start: Some(start), + end: Some(end), + .. + }) = higher::range(arg) + { + let mut_ids = vec![check_for_mutability(cx, start), check_for_mutability(cx, end)]; + if mut_ids[0].is_some() || mut_ids[1].is_some() { + let (span_low, span_high) = check_for_mutation(cx, body, &mut_ids); + mut_warn_with_span(cx, span_low); + mut_warn_with_span(cx, span_high); + } + } +} + +fn mut_warn_with_span(cx: &LateContext<'_>, span: Option) { + if let Some(sp) = span { + span_lint( + cx, + super::MUT_RANGE_BOUND, + sp, + "attempt to mutate range bound within loop; note that the range of the loop is unchanged", + ); + } +} + +fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option { + if_chain! { + if let Some(hir_id) = path_to_local(bound); + if let Node::Binding(pat) = cx.tcx.hir().get(hir_id); + if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind; + then { + return Some(hir_id); + } + } + None +} + +fn check_for_mutation<'tcx>( + cx: &LateContext<'tcx>, + body: &Expr<'_>, + bound_ids: &[Option], +) -> (Option, Option) { + let mut delegate = MutatePairDelegate { + cx, + hir_id_low: bound_ids[0], + hir_id_high: bound_ids[1], + span_low: None, + span_high: None, + }; + cx.tcx.infer_ctxt().enter(|infcx| { + ExprUseVisitor::new( + &mut delegate, + &infcx, + body.hir_id.owner, + cx.param_env, + cx.typeck_results(), + ) + .walk_expr(body); + }); + delegate.mutation_span() +} + +struct MutatePairDelegate<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + hir_id_low: Option, + hir_id_high: Option, + span_low: Option, + span_high: Option, +} + +impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> { + fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: ConsumeMode) {} + + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) { + if let ty::BorrowKind::MutBorrow = bk { + if let PlaceBase::Local(id) = cmt.place.base { + if Some(id) == self.hir_id_low { + self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id)) + } + if Some(id) == self.hir_id_high { + self.span_high = Some(self.cx.tcx.hir().span(diag_expr_id)) + } + } + } + } + + fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + if let PlaceBase::Local(id) = cmt.place.base { + if Some(id) == self.hir_id_low { + self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id)) + } + if Some(id) == self.hir_id_high { + self.span_high = Some(self.cx.tcx.hir().span(diag_expr_id)) + } + } + } +} + +impl MutatePairDelegate<'_, '_> { + fn mutation_span(&self) -> (Option, Option) { + (self.span_low, self.span_high) + } +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 672f07318595f..20f0090ebb487 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,5 +1,6 @@ mod for_loop_arg; mod for_loop_over_map_kv; +mod for_mut_range_bound; mod manual_flatten; mod utils; @@ -24,7 +25,6 @@ use rustc_hir::{ def_id, BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, GenericArg, HirId, InlineAsmOperand, Local, LoopSource, MatchSource, Mutability, Node, Pat, PatKind, QPath, Stmt, StmtKind, }; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; @@ -33,7 +33,6 @@ use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use rustc_span::symbol::{sym, Ident, Symbol}; -use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use std::iter::{once, Iterator}; use std::mem; use utils::make_iterator_snippet; @@ -865,7 +864,7 @@ fn check_for_loop<'tcx>( } for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); - check_for_mut_range_bound(cx, arg, body); + for_mut_range_bound::check_for_mut_range_bound(cx, arg, body); check_for_single_element_loop(cx, pat, arg, body, expr); detect_same_item_push(cx, pat, arg, body, expr); manual_flatten::check_manual_flatten(cx, pat, arg, body, span); @@ -1769,112 +1768,6 @@ fn check_for_single_element_loop<'tcx>( } } -struct MutatePairDelegate<'a, 'tcx> { - cx: &'a LateContext<'tcx>, - hir_id_low: Option, - hir_id_high: Option, - span_low: Option, - span_high: Option, -} - -impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> { - fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: ConsumeMode) {} - - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) { - if let ty::BorrowKind::MutBorrow = bk { - if let PlaceBase::Local(id) = cmt.place.base { - if Some(id) == self.hir_id_low { - self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id)) - } - if Some(id) == self.hir_id_high { - self.span_high = Some(self.cx.tcx.hir().span(diag_expr_id)) - } - } - } - } - - fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { - if let PlaceBase::Local(id) = cmt.place.base { - if Some(id) == self.hir_id_low { - self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id)) - } - if Some(id) == self.hir_id_high { - self.span_high = Some(self.cx.tcx.hir().span(diag_expr_id)) - } - } - } -} - -impl MutatePairDelegate<'_, '_> { - fn mutation_span(&self) -> (Option, Option) { - (self.span_low, self.span_high) - } -} - -fn check_for_mut_range_bound(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) { - if let Some(higher::Range { - start: Some(start), - end: Some(end), - .. - }) = higher::range(arg) - { - let mut_ids = vec![check_for_mutability(cx, start), check_for_mutability(cx, end)]; - if mut_ids[0].is_some() || mut_ids[1].is_some() { - let (span_low, span_high) = check_for_mutation(cx, body, &mut_ids); - mut_warn_with_span(cx, span_low); - mut_warn_with_span(cx, span_high); - } - } -} - -fn mut_warn_with_span(cx: &LateContext<'_>, span: Option) { - if let Some(sp) = span { - span_lint( - cx, - MUT_RANGE_BOUND, - sp, - "attempt to mutate range bound within loop; note that the range of the loop is unchanged", - ); - } -} - -fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option { - if_chain! { - if let Some(hir_id) = path_to_local(bound); - if let Node::Binding(pat) = cx.tcx.hir().get(hir_id); - if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind; - then { - return Some(hir_id); - } - } - None -} - -fn check_for_mutation<'tcx>( - cx: &LateContext<'tcx>, - body: &Expr<'_>, - bound_ids: &[Option], -) -> (Option, Option) { - let mut delegate = MutatePairDelegate { - cx, - hir_id_low: bound_ids[0], - hir_id_high: bound_ids[1], - span_low: None, - span_high: None, - }; - cx.tcx.infer_ctxt().enter(|infcx| { - ExprUseVisitor::new( - &mut delegate, - &infcx, - body.hir_id.owner, - cx.param_env, - cx.typeck_results(), - ) - .walk_expr(body); - }); - delegate.mutation_span() -} - struct VarVisitor<'a, 'tcx> { /// context reference cx: &'a LateContext<'tcx>, From 71c9fdf8b136cf9f879d5ca99615043ef6d09e68 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 8 Feb 2021 21:38:00 +0100 Subject: [PATCH 059/226] Refactor check_for_loop_range into its module --- clippy_lints/src/loops/for_loop_range.rs | 390 +++++++++++++++++++++++ clippy_lints/src/loops/mod.rs | 387 +--------------------- 2 files changed, 396 insertions(+), 381 deletions(-) create mode 100644 clippy_lints/src/loops/for_loop_range.rs diff --git a/clippy_lints/src/loops/for_loop_range.rs b/clippy_lints/src/loops/for_loop_range.rs new file mode 100644 index 0000000000000..43560abb7f2db --- /dev/null +++ b/clippy_lints/src/loops/for_loop_range.rs @@ -0,0 +1,390 @@ +use crate::utils::visitors::LocalUsedVisitor; +use crate::utils::{ + contains_name, has_iter_method, higher, is_integer_const, match_trait_method, multispan_sugg, path_to_local_id, + paths, snippet, span_lint_and_then, sugg, SpanlessEq, +}; +use if_chain::if_chain; +use rustc_ast::ast; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; +use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath}; +use rustc_lint::LateContext; +use rustc_middle::hir::map::Map; +use rustc_middle::middle::region; +use rustc_middle::ty::{self, Ty}; +use rustc_span::symbol::{sym, Symbol}; +use std::iter::Iterator; +use std::mem; + +/// Checks for looping over a range and then indexing a sequence with it. +/// The iteratee must be a range literal. +#[allow(clippy::too_many_lines)] +pub(super) fn check_for_loop_range<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, +) { + if let Some(higher::Range { + start: Some(start), + ref end, + limits, + }) = higher::range(arg) + { + // the var must be a single name + if let PatKind::Binding(_, canonical_id, ident, _) = pat.kind { + let mut visitor = VarVisitor { + cx, + var: canonical_id, + indexed_mut: FxHashSet::default(), + indexed_indirectly: FxHashMap::default(), + indexed_directly: FxHashMap::default(), + referenced: FxHashSet::default(), + nonindex: false, + prefer_mutable: false, + }; + walk_expr(&mut visitor, body); + + // linting condition: we only indexed one variable, and indexed it directly + if visitor.indexed_indirectly.is_empty() && visitor.indexed_directly.len() == 1 { + let (indexed, (indexed_extent, indexed_ty)) = visitor + .indexed_directly + .into_iter() + .next() + .expect("already checked that we have exactly 1 element"); + + // ensure that the indexed variable was declared before the loop, see #601 + if let Some(indexed_extent) = indexed_extent { + let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id); + let parent_def_id = cx.tcx.hir().local_def_id(parent_id); + let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id); + let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id); + if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) { + return; + } + } + + // don't lint if the container that is indexed does not have .iter() method + let has_iter = has_iter_method(cx, indexed_ty); + if has_iter.is_none() { + return; + } + + // don't lint if the container that is indexed into is also used without + // indexing + if visitor.referenced.contains(&indexed) { + return; + } + + let starts_at_zero = is_integer_const(cx, start, 0); + + let skip = if starts_at_zero { + String::new() + } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, start) { + return; + } else { + format!(".skip({})", snippet(cx, start.span, "..")) + }; + + let mut end_is_start_plus_val = false; + + let take = if let Some(end) = *end { + let mut take_expr = end; + + if let ExprKind::Binary(ref op, ref left, ref right) = end.kind { + if let BinOpKind::Add = op.node { + let start_equal_left = SpanlessEq::new(cx).eq_expr(start, left); + let start_equal_right = SpanlessEq::new(cx).eq_expr(start, right); + + if start_equal_left { + take_expr = right; + } else if start_equal_right { + take_expr = left; + } + + end_is_start_plus_val = start_equal_left | start_equal_right; + } + } + + if is_len_call(end, indexed) || is_end_eq_array_len(cx, end, limits, indexed_ty) { + String::new() + } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, take_expr) { + return; + } else { + match limits { + ast::RangeLimits::Closed => { + let take_expr = sugg::Sugg::hir(cx, take_expr, ""); + format!(".take({})", take_expr + sugg::ONE) + }, + ast::RangeLimits::HalfOpen => format!(".take({})", snippet(cx, take_expr.span, "..")), + } + } + } else { + String::new() + }; + + let (ref_mut, method) = if visitor.indexed_mut.contains(&indexed) { + ("mut ", "iter_mut") + } else { + ("", "iter") + }; + + let take_is_empty = take.is_empty(); + let mut method_1 = take; + let mut method_2 = skip; + + if end_is_start_plus_val { + mem::swap(&mut method_1, &mut method_2); + } + + if visitor.nonindex { + span_lint_and_then( + cx, + super::NEEDLESS_RANGE_LOOP, + expr.span, + &format!("the loop variable `{}` is used to index `{}`", ident.name, indexed), + |diag| { + multispan_sugg( + diag, + "consider using an iterator", + vec![ + (pat.span, format!("({}, )", ident.name)), + ( + arg.span, + format!("{}.{}().enumerate(){}{}", indexed, method, method_1, method_2), + ), + ], + ); + }, + ); + } else { + let repl = if starts_at_zero && take_is_empty { + format!("&{}{}", ref_mut, indexed) + } else { + format!("{}.{}(){}{}", indexed, method, method_1, method_2) + }; + + span_lint_and_then( + cx, + super::NEEDLESS_RANGE_LOOP, + expr.span, + &format!("the loop variable `{}` is only used to index `{}`", ident.name, indexed), + |diag| { + multispan_sugg( + diag, + "consider using an iterator", + vec![(pat.span, "".to_string()), (arg.span, repl)], + ); + }, + ); + } + } + } + } +} + +fn is_len_call(expr: &Expr<'_>, var: Symbol) -> bool { + if_chain! { + if let ExprKind::MethodCall(ref method, _, ref len_args, _) = expr.kind; + if len_args.len() == 1; + if method.ident.name == sym!(len); + if let ExprKind::Path(QPath::Resolved(_, ref path)) = len_args[0].kind; + if path.segments.len() == 1; + if path.segments[0].ident.name == var; + then { + return true; + } + } + + false +} + +fn is_end_eq_array_len<'tcx>( + cx: &LateContext<'tcx>, + end: &Expr<'_>, + limits: ast::RangeLimits, + indexed_ty: Ty<'tcx>, +) -> bool { + if_chain! { + if let ExprKind::Lit(ref lit) = end.kind; + if let ast::LitKind::Int(end_int, _) = lit.node; + if let ty::Array(_, arr_len_const) = indexed_ty.kind(); + if let Some(arr_len) = arr_len_const.try_eval_usize(cx.tcx, cx.param_env); + then { + return match limits { + ast::RangeLimits::Closed => end_int + 1 >= arr_len.into(), + ast::RangeLimits::HalfOpen => end_int >= arr_len.into(), + }; + } + } + + false +} + +struct VarVisitor<'a, 'tcx> { + /// context reference + cx: &'a LateContext<'tcx>, + /// var name to look for as index + var: HirId, + /// indexed variables that are used mutably + indexed_mut: FxHashSet, + /// indirectly indexed variables (`v[(i + 4) % N]`), the extend is `None` for global + indexed_indirectly: FxHashMap>, + /// subset of `indexed` of vars that are indexed directly: `v[i]` + /// this will not contain cases like `v[calc_index(i)]` or `v[(i + 4) % N]` + indexed_directly: FxHashMap, Ty<'tcx>)>, + /// Any names that are used outside an index operation. + /// Used to detect things like `&mut vec` used together with `vec[i]` + referenced: FxHashSet, + /// has the loop variable been used in expressions other than the index of + /// an index op? + nonindex: bool, + /// Whether we are inside the `$` in `&mut $` or `$ = foo` or `$.bar`, where bar + /// takes `&mut self` + prefer_mutable: bool, +} + +impl<'a, 'tcx> VarVisitor<'a, 'tcx> { + fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) -> bool { + if_chain! { + // the indexed container is referenced by a name + if let ExprKind::Path(ref seqpath) = seqexpr.kind; + if let QPath::Resolved(None, ref seqvar) = *seqpath; + if seqvar.segments.len() == 1; + then { + let index_used_directly = path_to_local_id(idx, self.var); + let indexed_indirectly = { + let mut used_visitor = LocalUsedVisitor::new(self.var); + walk_expr(&mut used_visitor, idx); + used_visitor.used + }; + + if indexed_indirectly || index_used_directly { + if self.prefer_mutable { + self.indexed_mut.insert(seqvar.segments[0].ident.name); + } + let res = self.cx.qpath_res(seqpath, seqexpr.hir_id); + match res { + Res::Local(hir_id) => { + let parent_id = self.cx.tcx.hir().get_parent_item(expr.hir_id); + let parent_def_id = self.cx.tcx.hir().local_def_id(parent_id); + let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id); + if indexed_indirectly { + self.indexed_indirectly.insert(seqvar.segments[0].ident.name, Some(extent)); + } + if index_used_directly { + self.indexed_directly.insert( + seqvar.segments[0].ident.name, + (Some(extent), self.cx.typeck_results().node_type(seqexpr.hir_id)), + ); + } + return false; // no need to walk further *on the variable* + } + Res::Def(DefKind::Static | DefKind::Const, ..) => { + if indexed_indirectly { + self.indexed_indirectly.insert(seqvar.segments[0].ident.name, None); + } + if index_used_directly { + self.indexed_directly.insert( + seqvar.segments[0].ident.name, + (None, self.cx.typeck_results().node_type(seqexpr.hir_id)), + ); + } + return false; // no need to walk further *on the variable* + } + _ => (), + } + } + } + } + true + } +} + +impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if_chain! { + // a range index op + if let ExprKind::MethodCall(ref meth, _, ref args, _) = expr.kind; + if (meth.ident.name == sym::index && match_trait_method(self.cx, expr, &paths::INDEX)) + || (meth.ident.name == sym::index_mut && match_trait_method(self.cx, expr, &paths::INDEX_MUT)); + if !self.check(&args[1], &args[0], expr); + then { return } + } + + if_chain! { + // an index op + if let ExprKind::Index(ref seqexpr, ref idx) = expr.kind; + if !self.check(idx, seqexpr, expr); + then { return } + } + + if_chain! { + // directly using a variable + if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind; + if let Res::Local(local_id) = path.res; + then { + if local_id == self.var { + self.nonindex = true; + } else { + // not the correct variable, but still a variable + self.referenced.insert(path.segments[0].ident.name); + } + } + } + + let old = self.prefer_mutable; + match expr.kind { + ExprKind::AssignOp(_, ref lhs, ref rhs) | ExprKind::Assign(ref lhs, ref rhs, _) => { + self.prefer_mutable = true; + self.visit_expr(lhs); + self.prefer_mutable = false; + self.visit_expr(rhs); + }, + ExprKind::AddrOf(BorrowKind::Ref, mutbl, ref expr) => { + if mutbl == Mutability::Mut { + self.prefer_mutable = true; + } + self.visit_expr(expr); + }, + ExprKind::Call(ref f, args) => { + self.visit_expr(f); + for expr in args { + let ty = self.cx.typeck_results().expr_ty_adjusted(expr); + self.prefer_mutable = false; + if let ty::Ref(_, _, mutbl) = *ty.kind() { + if mutbl == Mutability::Mut { + self.prefer_mutable = true; + } + } + self.visit_expr(expr); + } + }, + ExprKind::MethodCall(_, _, args, _) => { + let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); + for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) { + self.prefer_mutable = false; + if let ty::Ref(_, _, mutbl) = *ty.kind() { + if mutbl == Mutability::Mut { + self.prefer_mutable = true; + } + } + self.visit_expr(expr); + } + }, + ExprKind::Closure(_, _, body_id, ..) => { + let body = self.cx.tcx.hir().body(body_id); + self.visit_expr(&body.value); + }, + _ => walk_expr(self, expr), + } + self.prefer_mutable = old; + } + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 20f0090ebb487..204f9f9b2551b 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,5 +1,6 @@ mod for_loop_arg; mod for_loop_over_map_kv; +mod for_loop_range; mod for_mut_range_bound; mod manual_flatten; mod utils; @@ -7,13 +8,11 @@ mod utils; use crate::consts::constant; use crate::utils::sugg::Sugg; use crate::utils::usage::mutated_variables; -use crate::utils::visitors::LocalUsedVisitor; use crate::utils::{ - contains_name, get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, - indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, - last_path_segment, match_trait_method, match_type, multispan_sugg, path_to_local, path_to_local_id, paths, - single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, - span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, SpanlessEq, + get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, indent_of, is_in_panic_handler, + is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment, match_trait_method, + match_type, path_to_local, path_to_local_id, paths, single_segment_path, snippet, snippet_with_applicability, + snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, }; use if_chain::if_chain; use rustc_ast::ast; @@ -28,13 +27,11 @@ use rustc_hir::{ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; -use rustc_middle::middle::region; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use rustc_span::symbol::{sym, Ident, Symbol}; use std::iter::{once, Iterator}; -use std::mem; use utils::make_iterator_snippet; declare_clippy_lint! { @@ -859,7 +856,7 @@ fn check_for_loop<'tcx>( ) { let is_manual_memcpy_triggered = detect_manual_memcpy(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { - check_for_loop_range(cx, pat, arg, body, expr); + for_loop_range::check_for_loop_range(cx, pat, arg, body, expr); check_for_loop_explicit_counter(cx, pat, arg, body, expr); } for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); @@ -1477,212 +1474,6 @@ fn detect_same_item_push<'tcx>( } } -/// Checks for looping over a range and then indexing a sequence with it. -/// The iteratee must be a range literal. -#[allow(clippy::too_many_lines)] -fn check_for_loop_range<'tcx>( - cx: &LateContext<'tcx>, - pat: &'tcx Pat<'_>, - arg: &'tcx Expr<'_>, - body: &'tcx Expr<'_>, - expr: &'tcx Expr<'_>, -) { - if let Some(higher::Range { - start: Some(start), - ref end, - limits, - }) = higher::range(arg) - { - // the var must be a single name - if let PatKind::Binding(_, canonical_id, ident, _) = pat.kind { - let mut visitor = VarVisitor { - cx, - var: canonical_id, - indexed_mut: FxHashSet::default(), - indexed_indirectly: FxHashMap::default(), - indexed_directly: FxHashMap::default(), - referenced: FxHashSet::default(), - nonindex: false, - prefer_mutable: false, - }; - walk_expr(&mut visitor, body); - - // linting condition: we only indexed one variable, and indexed it directly - if visitor.indexed_indirectly.is_empty() && visitor.indexed_directly.len() == 1 { - let (indexed, (indexed_extent, indexed_ty)) = visitor - .indexed_directly - .into_iter() - .next() - .expect("already checked that we have exactly 1 element"); - - // ensure that the indexed variable was declared before the loop, see #601 - if let Some(indexed_extent) = indexed_extent { - let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id); - let parent_def_id = cx.tcx.hir().local_def_id(parent_id); - let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id); - let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id); - if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) { - return; - } - } - - // don't lint if the container that is indexed does not have .iter() method - let has_iter = has_iter_method(cx, indexed_ty); - if has_iter.is_none() { - return; - } - - // don't lint if the container that is indexed into is also used without - // indexing - if visitor.referenced.contains(&indexed) { - return; - } - - let starts_at_zero = is_integer_const(cx, start, 0); - - let skip = if starts_at_zero { - String::new() - } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, start) { - return; - } else { - format!(".skip({})", snippet(cx, start.span, "..")) - }; - - let mut end_is_start_plus_val = false; - - let take = if let Some(end) = *end { - let mut take_expr = end; - - if let ExprKind::Binary(ref op, ref left, ref right) = end.kind { - if let BinOpKind::Add = op.node { - let start_equal_left = SpanlessEq::new(cx).eq_expr(start, left); - let start_equal_right = SpanlessEq::new(cx).eq_expr(start, right); - - if start_equal_left { - take_expr = right; - } else if start_equal_right { - take_expr = left; - } - - end_is_start_plus_val = start_equal_left | start_equal_right; - } - } - - if is_len_call(end, indexed) || is_end_eq_array_len(cx, end, limits, indexed_ty) { - String::new() - } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, take_expr) { - return; - } else { - match limits { - ast::RangeLimits::Closed => { - let take_expr = sugg::Sugg::hir(cx, take_expr, ""); - format!(".take({})", take_expr + sugg::ONE) - }, - ast::RangeLimits::HalfOpen => format!(".take({})", snippet(cx, take_expr.span, "..")), - } - } - } else { - String::new() - }; - - let (ref_mut, method) = if visitor.indexed_mut.contains(&indexed) { - ("mut ", "iter_mut") - } else { - ("", "iter") - }; - - let take_is_empty = take.is_empty(); - let mut method_1 = take; - let mut method_2 = skip; - - if end_is_start_plus_val { - mem::swap(&mut method_1, &mut method_2); - } - - if visitor.nonindex { - span_lint_and_then( - cx, - NEEDLESS_RANGE_LOOP, - expr.span, - &format!("the loop variable `{}` is used to index `{}`", ident.name, indexed), - |diag| { - multispan_sugg( - diag, - "consider using an iterator", - vec![ - (pat.span, format!("({}, )", ident.name)), - ( - arg.span, - format!("{}.{}().enumerate(){}{}", indexed, method, method_1, method_2), - ), - ], - ); - }, - ); - } else { - let repl = if starts_at_zero && take_is_empty { - format!("&{}{}", ref_mut, indexed) - } else { - format!("{}.{}(){}{}", indexed, method, method_1, method_2) - }; - - span_lint_and_then( - cx, - NEEDLESS_RANGE_LOOP, - expr.span, - &format!("the loop variable `{}` is only used to index `{}`", ident.name, indexed), - |diag| { - multispan_sugg( - diag, - "consider using an iterator", - vec![(pat.span, "".to_string()), (arg.span, repl)], - ); - }, - ); - } - } - } - } -} - -fn is_len_call(expr: &Expr<'_>, var: Symbol) -> bool { - if_chain! { - if let ExprKind::MethodCall(ref method, _, ref len_args, _) = expr.kind; - if len_args.len() == 1; - if method.ident.name == sym!(len); - if let ExprKind::Path(QPath::Resolved(_, ref path)) = len_args[0].kind; - if path.segments.len() == 1; - if path.segments[0].ident.name == var; - then { - return true; - } - } - - false -} - -fn is_end_eq_array_len<'tcx>( - cx: &LateContext<'tcx>, - end: &Expr<'_>, - limits: ast::RangeLimits, - indexed_ty: Ty<'tcx>, -) -> bool { - if_chain! { - if let ExprKind::Lit(ref lit) = end.kind; - if let ast::LitKind::Int(end_int, _) = lit.node; - if let ty::Array(_, arr_len_const) = indexed_ty.kind(); - if let Some(arr_len) = arr_len_const.try_eval_usize(cx.tcx, cx.param_env); - then { - return match limits { - ast::RangeLimits::Closed => end_int + 1 >= arr_len.into(), - ast::RangeLimits::HalfOpen => end_int >= arr_len.into(), - }; - } - } - - false -} - // To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be // incremented exactly once in the loop body, and initialized to zero // at the start of the loop. @@ -1768,172 +1559,6 @@ fn check_for_single_element_loop<'tcx>( } } -struct VarVisitor<'a, 'tcx> { - /// context reference - cx: &'a LateContext<'tcx>, - /// var name to look for as index - var: HirId, - /// indexed variables that are used mutably - indexed_mut: FxHashSet, - /// indirectly indexed variables (`v[(i + 4) % N]`), the extend is `None` for global - indexed_indirectly: FxHashMap>, - /// subset of `indexed` of vars that are indexed directly: `v[i]` - /// this will not contain cases like `v[calc_index(i)]` or `v[(i + 4) % N]` - indexed_directly: FxHashMap, Ty<'tcx>)>, - /// Any names that are used outside an index operation. - /// Used to detect things like `&mut vec` used together with `vec[i]` - referenced: FxHashSet, - /// has the loop variable been used in expressions other than the index of - /// an index op? - nonindex: bool, - /// Whether we are inside the `$` in `&mut $` or `$ = foo` or `$.bar`, where bar - /// takes `&mut self` - prefer_mutable: bool, -} - -impl<'a, 'tcx> VarVisitor<'a, 'tcx> { - fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) -> bool { - if_chain! { - // the indexed container is referenced by a name - if let ExprKind::Path(ref seqpath) = seqexpr.kind; - if let QPath::Resolved(None, ref seqvar) = *seqpath; - if seqvar.segments.len() == 1; - then { - let index_used_directly = path_to_local_id(idx, self.var); - let indexed_indirectly = { - let mut used_visitor = LocalUsedVisitor::new(self.cx, self.var); - walk_expr(&mut used_visitor, idx); - used_visitor.used - }; - - if indexed_indirectly || index_used_directly { - if self.prefer_mutable { - self.indexed_mut.insert(seqvar.segments[0].ident.name); - } - let res = self.cx.qpath_res(seqpath, seqexpr.hir_id); - match res { - Res::Local(hir_id) => { - let parent_id = self.cx.tcx.hir().get_parent_item(expr.hir_id); - let parent_def_id = self.cx.tcx.hir().local_def_id(parent_id); - let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id); - if indexed_indirectly { - self.indexed_indirectly.insert(seqvar.segments[0].ident.name, Some(extent)); - } - if index_used_directly { - self.indexed_directly.insert( - seqvar.segments[0].ident.name, - (Some(extent), self.cx.typeck_results().node_type(seqexpr.hir_id)), - ); - } - return false; // no need to walk further *on the variable* - } - Res::Def(DefKind::Static | DefKind::Const, ..) => { - if indexed_indirectly { - self.indexed_indirectly.insert(seqvar.segments[0].ident.name, None); - } - if index_used_directly { - self.indexed_directly.insert( - seqvar.segments[0].ident.name, - (None, self.cx.typeck_results().node_type(seqexpr.hir_id)), - ); - } - return false; // no need to walk further *on the variable* - } - _ => (), - } - } - } - } - true - } -} - -impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if_chain! { - // a range index op - if let ExprKind::MethodCall(ref meth, _, ref args, _) = expr.kind; - if (meth.ident.name == sym::index && match_trait_method(self.cx, expr, &paths::INDEX)) - || (meth.ident.name == sym::index_mut && match_trait_method(self.cx, expr, &paths::INDEX_MUT)); - if !self.check(&args[1], &args[0], expr); - then { return } - } - - if_chain! { - // an index op - if let ExprKind::Index(ref seqexpr, ref idx) = expr.kind; - if !self.check(idx, seqexpr, expr); - then { return } - } - - if_chain! { - // directly using a variable - if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind; - if let Res::Local(local_id) = path.res; - then { - if local_id == self.var { - self.nonindex = true; - } else { - // not the correct variable, but still a variable - self.referenced.insert(path.segments[0].ident.name); - } - } - } - - let old = self.prefer_mutable; - match expr.kind { - ExprKind::AssignOp(_, ref lhs, ref rhs) | ExprKind::Assign(ref lhs, ref rhs, _) => { - self.prefer_mutable = true; - self.visit_expr(lhs); - self.prefer_mutable = false; - self.visit_expr(rhs); - }, - ExprKind::AddrOf(BorrowKind::Ref, mutbl, ref expr) => { - if mutbl == Mutability::Mut { - self.prefer_mutable = true; - } - self.visit_expr(expr); - }, - ExprKind::Call(ref f, args) => { - self.visit_expr(f); - for expr in args { - let ty = self.cx.typeck_results().expr_ty_adjusted(expr); - self.prefer_mutable = false; - if let ty::Ref(_, _, mutbl) = *ty.kind() { - if mutbl == Mutability::Mut { - self.prefer_mutable = true; - } - } - self.visit_expr(expr); - } - }, - ExprKind::MethodCall(_, _, args, _) => { - let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); - for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) { - self.prefer_mutable = false; - if let ty::Ref(_, _, mutbl) = *ty.kind() { - if mutbl == Mutability::Mut { - self.prefer_mutable = true; - } - } - self.visit_expr(expr); - } - }, - ExprKind::Closure(_, _, body_id, ..) => { - let body = self.cx.tcx.hir().body(body_id); - self.visit_expr(&body.value); - }, - _ => walk_expr(self, expr), - } - self.prefer_mutable = old; - } - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { let def_id = match path_to_local(expr) { Some(id) => id, From 71026cad541615875fc2570bd3eb51c30ce2151d Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 8 Feb 2021 22:01:05 +0100 Subject: [PATCH 060/226] Refactor check_for_loop_explicit_counter to its own module --- .../src/loops/for_loop_explicit_counter.rs | 56 ++++++++++++++++ clippy_lints/src/loops/mod.rs | 65 +------------------ clippy_lints/src/loops/utils.rs | 12 ++++ 3 files changed, 71 insertions(+), 62 deletions(-) create mode 100644 clippy_lints/src/loops/for_loop_explicit_counter.rs diff --git a/clippy_lints/src/loops/for_loop_explicit_counter.rs b/clippy_lints/src/loops/for_loop_explicit_counter.rs new file mode 100644 index 0000000000000..68fee269eb1d6 --- /dev/null +++ b/clippy_lints/src/loops/for_loop_explicit_counter.rs @@ -0,0 +1,56 @@ +use super::{get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor}; +use crate::utils::{get_enclosing_block, is_integer_const, snippet_with_applicability, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::intravisit::{walk_block, walk_expr}; +use rustc_hir::{Expr, Pat}; +use rustc_lint::LateContext; + +// To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be +// incremented exactly once in the loop body, and initialized to zero +// at the start of the loop. +pub(super) fn check_for_loop_explicit_counter<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, +) { + // Look for variables that are incremented once per loop iteration. + let mut increment_visitor = IncrementVisitor::new(cx); + walk_expr(&mut increment_visitor, body); + + // For each candidate, check the parent block to see if + // it's initialized to zero at the start of the loop. + if let Some(block) = get_enclosing_block(&cx, expr.hir_id) { + for id in increment_visitor.into_results() { + let mut initialize_visitor = InitializeVisitor::new(cx, expr, id); + walk_block(&mut initialize_visitor, block); + + if_chain! { + if let Some((name, initializer)) = initialize_visitor.get_result(); + if is_integer_const(cx, initializer, 0); + then { + let mut applicability = Applicability::MachineApplicable; + + let for_span = get_span_of_entire_for_loop(expr); + + span_lint_and_sugg( + cx, + super::EXPLICIT_COUNTER_LOOP, + for_span.with_hi(arg.span.hi()), + &format!("the variable `{}` is used as a loop counter", name), + "consider using", + format!( + "for ({}, {}) in {}.enumerate()", + name, + snippet_with_applicability(cx, pat.span, "item", &mut applicability), + make_iterator_snippet(cx, arg, &mut applicability), + ), + applicability, + ); + } + } + } + } +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 204f9f9b2551b..f06b3ae4c9ffc 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,4 +1,5 @@ mod for_loop_arg; +mod for_loop_explicit_counter; mod for_loop_over_map_kv; mod for_loop_range; mod for_mut_range_bound; @@ -32,7 +33,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use rustc_span::symbol::{sym, Ident, Symbol}; use std::iter::{once, Iterator}; -use utils::make_iterator_snippet; +use utils::{get_span_of_entire_for_loop, make_iterator_snippet}; declare_clippy_lint! { /// **What it does:** Checks for for-loops that manually copy items between @@ -857,7 +858,7 @@ fn check_for_loop<'tcx>( let is_manual_memcpy_triggered = detect_manual_memcpy(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { for_loop_range::check_for_loop_range(cx, pat, arg, body, expr); - check_for_loop_explicit_counter(cx, pat, arg, body, expr); + for_loop_explicit_counter::check_for_loop_explicit_counter(cx, pat, arg, body, expr); } for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); @@ -867,17 +868,6 @@ fn check_for_loop<'tcx>( manual_flatten::check_manual_flatten(cx, pat, arg, body, span); } -// this function assumes the given expression is a `for` loop. -fn get_span_of_entire_for_loop(expr: &Expr<'_>) -> Span { - // for some reason this is the only way to get the `Span` - // of the entire `for` loop - if let ExprKind::Match(_, arms, _) = &expr.kind { - arms[0].body.span - } else { - unreachable!() - } -} - /// a wrapper of `Sugg`. Besides what `Sugg` do, this removes unnecessary `0`; /// and also, it avoids subtracting a variable from the same one by replacing it with `0`. /// it exists for the convenience of the overloaded operators while normal functions can do the @@ -1474,55 +1464,6 @@ fn detect_same_item_push<'tcx>( } } -// To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be -// incremented exactly once in the loop body, and initialized to zero -// at the start of the loop. -fn check_for_loop_explicit_counter<'tcx>( - cx: &LateContext<'tcx>, - pat: &'tcx Pat<'_>, - arg: &'tcx Expr<'_>, - body: &'tcx Expr<'_>, - expr: &'tcx Expr<'_>, -) { - // Look for variables that are incremented once per loop iteration. - let mut increment_visitor = IncrementVisitor::new(cx); - walk_expr(&mut increment_visitor, body); - - // For each candidate, check the parent block to see if - // it's initialized to zero at the start of the loop. - if let Some(block) = get_enclosing_block(&cx, expr.hir_id) { - for id in increment_visitor.into_results() { - let mut initialize_visitor = InitializeVisitor::new(cx, expr, id); - walk_block(&mut initialize_visitor, block); - - if_chain! { - if let Some((name, initializer)) = initialize_visitor.get_result(); - if is_integer_const(cx, initializer, 0); - then { - let mut applicability = Applicability::MachineApplicable; - - let for_span = get_span_of_entire_for_loop(expr); - - span_lint_and_sugg( - cx, - EXPLICIT_COUNTER_LOOP, - for_span.with_hi(arg.span.hi()), - &format!("the variable `{}` is used as a loop counter", name), - "consider using", - format!( - "for ({}, {}) in {}.enumerate()", - name, - snippet_with_applicability(cx, pat.span, "item", &mut applicability), - make_iterator_snippet(cx, arg, &mut applicability), - ), - applicability, - ); - } - } - } - } -} - fn check_for_single_element_loop<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs index b06df2d75f3be..b9c934d5e549d 100644 --- a/clippy_lints/src/loops/utils.rs +++ b/clippy_lints/src/loops/utils.rs @@ -2,6 +2,18 @@ use crate::utils::{get_trait_def_id, has_iter_method, implements_trait, paths, s use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; use rustc_lint::LateContext; +use rustc_span::source_map::Span; + +// this function assumes the given expression is a `for` loop. +pub(super) fn get_span_of_entire_for_loop(expr: &Expr<'_>) -> Span { + // for some reason this is the only way to get the `Span` + // of the entire `for` loop + if let ExprKind::Match(_, arms, _) = &expr.kind { + arms[0].body.span + } else { + unreachable!() + } +} /// If `arg` was the argument to a `for` loop, return the "cleanest" way of writing the /// actual `Iterator` that the loop uses. From 1e5e541ac57e6757fe8c6c3b316a750730ba7f8c Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 8 Feb 2021 22:12:32 +0100 Subject: [PATCH 061/226] Refactor check_for_single_element_loop to its own module --- .../src/loops/for_single_element_loop.rs | 42 ++++++++++++++++++ clippy_lints/src/loops/mod.rs | 43 ++----------------- 2 files changed, 46 insertions(+), 39 deletions(-) create mode 100644 clippy_lints/src/loops/for_single_element_loop.rs diff --git a/clippy_lints/src/loops/for_single_element_loop.rs b/clippy_lints/src/loops/for_single_element_loop.rs new file mode 100644 index 0000000000000..8ba19a2233a53 --- /dev/null +++ b/clippy_lints/src/loops/for_single_element_loop.rs @@ -0,0 +1,42 @@ +use super::get_span_of_entire_for_loop; +use crate::utils::{indent_of, single_segment_path, snippet, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind}; +use rustc_lint::LateContext; + +pub(super) fn check_for_single_element_loop<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, +) { + if_chain! { + if let ExprKind::AddrOf(BorrowKind::Ref, _, ref arg_expr) = arg.kind; + if let PatKind::Binding(.., target, _) = pat.kind; + if let ExprKind::Array([arg_expression]) = arg_expr.kind; + if let ExprKind::Path(ref list_item) = arg_expression.kind; + if let Some(list_item_name) = single_segment_path(list_item).map(|ps| ps.ident.name); + if let ExprKind::Block(ref block, _) = body.kind; + if !block.stmts.is_empty(); + + then { + let for_span = get_span_of_entire_for_loop(expr); + let mut block_str = snippet(cx, block.span, "..").into_owned(); + block_str.remove(0); + block_str.pop(); + + + span_lint_and_sugg( + cx, + super::SINGLE_ELEMENT_LOOP, + for_span, + "for loop over a single element", + "try", + format!("{{\n{}let {} = &{};{}}}", " ".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0)), target.name, list_item_name, block_str), + Applicability::MachineApplicable + ) + } + } +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index f06b3ae4c9ffc..d434762bc228b 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -3,6 +3,7 @@ mod for_loop_explicit_counter; mod for_loop_over_map_kv; mod for_loop_range; mod for_mut_range_bound; +mod for_single_element_loop; mod manual_flatten; mod utils; @@ -10,9 +11,9 @@ use crate::consts::constant; use crate::utils::sugg::Sugg; use crate::utils::usage::mutated_variables; use crate::utils::{ - get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, indent_of, is_in_panic_handler, + get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment, match_trait_method, - match_type, path_to_local, path_to_local_id, paths, single_segment_path, snippet, snippet_with_applicability, + match_type, path_to_local, path_to_local_id, paths, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, }; use if_chain::if_chain; @@ -863,7 +864,7 @@ fn check_for_loop<'tcx>( for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); for_mut_range_bound::check_for_mut_range_bound(cx, arg, body); - check_for_single_element_loop(cx, pat, arg, body, expr); + for_single_element_loop::check_for_single_element_loop(cx, pat, arg, body, expr); detect_same_item_push(cx, pat, arg, body, expr); manual_flatten::check_manual_flatten(cx, pat, arg, body, span); } @@ -1464,42 +1465,6 @@ fn detect_same_item_push<'tcx>( } } -fn check_for_single_element_loop<'tcx>( - cx: &LateContext<'tcx>, - pat: &'tcx Pat<'_>, - arg: &'tcx Expr<'_>, - body: &'tcx Expr<'_>, - expr: &'tcx Expr<'_>, -) { - if_chain! { - if let ExprKind::AddrOf(BorrowKind::Ref, _, ref arg_expr) = arg.kind; - if let PatKind::Binding(.., target, _) = pat.kind; - if let ExprKind::Array([arg_expression]) = arg_expr.kind; - if let ExprKind::Path(ref list_item) = arg_expression.kind; - if let Some(list_item_name) = single_segment_path(list_item).map(|ps| ps.ident.name); - if let ExprKind::Block(ref block, _) = body.kind; - if !block.stmts.is_empty(); - - then { - let for_span = get_span_of_entire_for_loop(expr); - let mut block_str = snippet(cx, block.span, "..").into_owned(); - block_str.remove(0); - block_str.pop(); - - - span_lint_and_sugg( - cx, - SINGLE_ELEMENT_LOOP, - for_span, - "for loop over a single element", - "try", - format!("{{\n{}let {} = &{};{}}}", " ".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0)), target.name, list_item_name, block_str), - Applicability::MachineApplicable - ) - } - } -} - fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { let def_id = match path_to_local(expr) { Some(id) => id, From 9520cba554e2844c92ede32066138c38de3d327f Mon Sep 17 00:00:00 2001 From: nahuakang Date: Tue, 9 Feb 2021 20:21:22 +0100 Subject: [PATCH 062/226] Add check_infinite_loop to its own module --- clippy_lints/src/loops/infinite_loop.rs | 138 ++++++++++++++++++++++++ clippy_lints/src/loops/mod.rs | 137 +---------------------- 2 files changed, 143 insertions(+), 132 deletions(-) create mode 100644 clippy_lints/src/loops/infinite_loop.rs diff --git a/clippy_lints/src/loops/infinite_loop.rs b/clippy_lints/src/loops/infinite_loop.rs new file mode 100644 index 0000000000000..b89942fb64755 --- /dev/null +++ b/clippy_lints/src/loops/infinite_loop.rs @@ -0,0 +1,138 @@ +use crate::consts::constant; +use crate::utils::span_lint_and_then; +use crate::utils::usage::mutated_variables; +use if_chain::if_chain; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; +use rustc_hir::{def_id, Expr, ExprKind, HirId, QPath}; +use rustc_lint::LateContext; +use rustc_middle::hir::map::Map; +use std::iter::Iterator; + +pub(super) fn check_infinite_loop<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { + if constant(cx, cx.typeck_results(), cond).is_some() { + // A pure constant condition (e.g., `while false`) is not linted. + return; + } + + let mut var_visitor = VarCollectorVisitor { + cx, + ids: FxHashSet::default(), + def_ids: FxHashMap::default(), + skip: false, + }; + var_visitor.visit_expr(cond); + if var_visitor.skip { + return; + } + let used_in_condition = &var_visitor.ids; + let no_cond_variable_mutated = if let Some(used_mutably) = mutated_variables(expr, cx) { + used_in_condition.is_disjoint(&used_mutably) + } else { + return; + }; + let mutable_static_in_cond = var_visitor.def_ids.iter().any(|(_, v)| *v); + + let mut has_break_or_return_visitor = HasBreakOrReturnVisitor { + has_break_or_return: false, + }; + has_break_or_return_visitor.visit_expr(expr); + let has_break_or_return = has_break_or_return_visitor.has_break_or_return; + + if no_cond_variable_mutated && !mutable_static_in_cond { + span_lint_and_then( + cx, + super::WHILE_IMMUTABLE_CONDITION, + cond.span, + "variables in the condition are not mutated in the loop body", + |diag| { + diag.note("this may lead to an infinite or to a never running loop"); + + if has_break_or_return { + diag.note("this loop contains `return`s or `break`s"); + diag.help("rewrite it as `if cond { loop { } }`"); + } + }, + ); + } +} + +struct HasBreakOrReturnVisitor { + has_break_or_return: bool, +} + +impl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if self.has_break_or_return { + return; + } + + match expr.kind { + ExprKind::Ret(_) | ExprKind::Break(_, _) => { + self.has_break_or_return = true; + return; + }, + _ => {}, + } + + walk_expr(self, expr); + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} + +/// Collects the set of variables in an expression +/// Stops analysis if a function call is found +/// Note: In some cases such as `self`, there are no mutable annotation, +/// All variables definition IDs are collected +struct VarCollectorVisitor<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + ids: FxHashSet, + def_ids: FxHashMap, + skip: bool, +} + +impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> { + fn insert_def_id(&mut self, ex: &'tcx Expr<'_>) { + if_chain! { + if let ExprKind::Path(ref qpath) = ex.kind; + if let QPath::Resolved(None, _) = *qpath; + let res = self.cx.qpath_res(qpath, ex.hir_id); + then { + match res { + Res::Local(hir_id) => { + self.ids.insert(hir_id); + }, + Res::Def(DefKind::Static, def_id) => { + let mutable = self.cx.tcx.is_mutable_static(def_id); + self.def_ids.insert(def_id, mutable); + }, + _ => {}, + } + } + } + } +} + +impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, ex: &'tcx Expr<'_>) { + match ex.kind { + ExprKind::Path(_) => self.insert_def_id(ex), + // If there is any function/method call… we just stop analysis + ExprKind::Call(..) | ExprKind::MethodCall(..) => self.skip = true, + + _ => walk_expr(self, ex), + } + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index d434762bc228b..6adfbb6b955ba 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -4,10 +4,10 @@ mod for_loop_over_map_kv; mod for_loop_range; mod for_mut_range_bound; mod for_single_element_loop; +mod infinite_loop; mod manual_flatten; mod utils; -use crate::consts::constant; use crate::utils::sugg::Sugg; use crate::utils::usage::mutated_variables; use crate::utils::{ @@ -18,13 +18,13 @@ use crate::utils::{ }; use if_chain::if_chain; use rustc_ast::ast; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; use rustc_hir::{ - def_id, BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, GenericArg, HirId, InlineAsmOperand, - Local, LoopSource, MatchSource, Mutability, Node, Pat, PatKind, QPath, Stmt, StmtKind, + BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, GenericArg, HirId, InlineAsmOperand, Local, + LoopSource, MatchSource, Mutability, Node, Pat, PatKind, QPath, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -683,7 +683,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { } if let Some((cond, body)) = higher::while_loop(&expr) { - check_infinite_loop(cx, cond, body); + infinite_loop::check_infinite_loop(cx, cond, body); } check_needless_collect(expr, cx); @@ -1895,133 +1895,6 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor { } } -fn check_infinite_loop<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { - if constant(cx, cx.typeck_results(), cond).is_some() { - // A pure constant condition (e.g., `while false`) is not linted. - return; - } - - let mut var_visitor = VarCollectorVisitor { - cx, - ids: FxHashSet::default(), - def_ids: FxHashMap::default(), - skip: false, - }; - var_visitor.visit_expr(cond); - if var_visitor.skip { - return; - } - let used_in_condition = &var_visitor.ids; - let no_cond_variable_mutated = if let Some(used_mutably) = mutated_variables(expr, cx) { - used_in_condition.is_disjoint(&used_mutably) - } else { - return; - }; - let mutable_static_in_cond = var_visitor.def_ids.iter().any(|(_, v)| *v); - - let mut has_break_or_return_visitor = HasBreakOrReturnVisitor { - has_break_or_return: false, - }; - has_break_or_return_visitor.visit_expr(expr); - let has_break_or_return = has_break_or_return_visitor.has_break_or_return; - - if no_cond_variable_mutated && !mutable_static_in_cond { - span_lint_and_then( - cx, - WHILE_IMMUTABLE_CONDITION, - cond.span, - "variables in the condition are not mutated in the loop body", - |diag| { - diag.note("this may lead to an infinite or to a never running loop"); - - if has_break_or_return { - diag.note("this loop contains `return`s or `break`s"); - diag.help("rewrite it as `if cond { loop { } }`"); - } - }, - ); - } -} - -struct HasBreakOrReturnVisitor { - has_break_or_return: bool, -} - -impl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if self.has_break_or_return { - return; - } - - match expr.kind { - ExprKind::Ret(_) | ExprKind::Break(_, _) => { - self.has_break_or_return = true; - return; - }, - _ => {}, - } - - walk_expr(self, expr); - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - -/// Collects the set of variables in an expression -/// Stops analysis if a function call is found -/// Note: In some cases such as `self`, there are no mutable annotation, -/// All variables definition IDs are collected -struct VarCollectorVisitor<'a, 'tcx> { - cx: &'a LateContext<'tcx>, - ids: FxHashSet, - def_ids: FxHashMap, - skip: bool, -} - -impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> { - fn insert_def_id(&mut self, ex: &'tcx Expr<'_>) { - if_chain! { - if let ExprKind::Path(ref qpath) = ex.kind; - if let QPath::Resolved(None, _) = *qpath; - let res = self.cx.qpath_res(qpath, ex.hir_id); - then { - match res { - Res::Local(hir_id) => { - self.ids.insert(hir_id); - }, - Res::Def(DefKind::Static, def_id) => { - let mutable = self.cx.tcx.is_mutable_static(def_id); - self.def_ids.insert(def_id, mutable); - }, - _ => {}, - } - } - } - } -} - -impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, ex: &'tcx Expr<'_>) { - match ex.kind { - ExprKind::Path(_) => self.insert_def_id(ex), - // If there is any function/method call… we just stop analysis - ExprKind::Call(..) | ExprKind::MethodCall(..) => self.skip = true, - - _ => walk_expr(self, ex), - } - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; fn check_needless_collect<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { From 453e6b97ace822f715b6118a60ec9b33e0ae87ec Mon Sep 17 00:00:00 2001 From: nahuakang Date: Tue, 9 Feb 2021 21:26:46 +0100 Subject: [PATCH 063/226] Add check_needless_collect to its own module --- clippy_lints/src/loops/mod.rs | 282 +-------------------- clippy_lints/src/loops/needless_collect.rs | 282 +++++++++++++++++++++ 2 files changed, 289 insertions(+), 275 deletions(-) create mode 100644 clippy_lints/src/loops/needless_collect.rs diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 6adfbb6b955ba..043bbc9d1c589 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -6,6 +6,7 @@ mod for_mut_range_bound; mod for_single_element_loop; mod infinite_loop; mod manual_flatten; +mod needless_collect; mod utils; use crate::utils::sugg::Sugg; @@ -13,8 +14,8 @@ use crate::utils::usage::mutated_variables; use crate::utils::{ get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment, match_trait_method, - match_type, path_to_local, path_to_local_id, paths, snippet, snippet_with_applicability, - snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, + path_to_local, path_to_local_id, paths, snippet, snippet_with_applicability, snippet_with_macro_callsite, + span_lint, span_lint_and_help, span_lint_and_sugg, sugg, }; use if_chain::if_chain; use rustc_ast::ast; @@ -23,8 +24,8 @@ use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; use rustc_hir::{ - BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, GenericArg, HirId, InlineAsmOperand, Local, - LoopSource, MatchSource, Mutability, Node, Pat, PatKind, QPath, Stmt, StmtKind, + BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, HirId, InlineAsmOperand, LoopSource, MatchSource, + Mutability, Node, Pat, PatKind, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -32,7 +33,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; -use rustc_span::symbol::{sym, Ident, Symbol}; +use rustc_span::symbol::{sym, Symbol}; use std::iter::{once, Iterator}; use utils::{get_span_of_entire_for_loop, make_iterator_snippet}; @@ -686,7 +687,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { infinite_loop::check_infinite_loop(cx, cond, body); } - check_needless_collect(expr, cx); + needless_collect::check_needless_collect(expr, cx); } } @@ -1894,272 +1895,3 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor { NestedVisitorMap::None } } - -const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; - -fn check_needless_collect<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { - check_needless_collect_direct_usage(expr, cx); - check_needless_collect_indirect_usage(expr, cx); -} -fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { - if_chain! { - if let ExprKind::MethodCall(ref method, _, ref args, _) = expr.kind; - if let ExprKind::MethodCall(ref chain_method, _, _, _) = args[0].kind; - if chain_method.ident.name == sym!(collect) && match_trait_method(cx, &args[0], &paths::ITERATOR); - if let Some(ref generic_args) = chain_method.args; - if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); - then { - let ty = cx.typeck_results().node_type(ty.hir_id); - if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || - match_type(cx, ty, &paths::BTREEMAP) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { - if method.ident.name == sym!(len) { - let span = shorten_needless_collect_span(expr); - span_lint_and_sugg( - cx, - NEEDLESS_COLLECT, - span, - NEEDLESS_COLLECT_MSG, - "replace with", - "count()".to_string(), - Applicability::MachineApplicable, - ); - } - if method.ident.name == sym!(is_empty) { - let span = shorten_needless_collect_span(expr); - span_lint_and_sugg( - cx, - NEEDLESS_COLLECT, - span, - NEEDLESS_COLLECT_MSG, - "replace with", - "next().is_none()".to_string(), - Applicability::MachineApplicable, - ); - } - if method.ident.name == sym!(contains) { - let contains_arg = snippet(cx, args[1].span, "??"); - let span = shorten_needless_collect_span(expr); - span_lint_and_then( - cx, - NEEDLESS_COLLECT, - span, - NEEDLESS_COLLECT_MSG, - |diag| { - let (arg, pred) = contains_arg - .strip_prefix('&') - .map_or(("&x", &*contains_arg), |s| ("x", s)); - diag.span_suggestion( - span, - "replace with", - format!( - "any(|{}| x == {})", - arg, pred - ), - Applicability::MachineApplicable, - ); - } - ); - } - } - } - } -} - -fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { - if let ExprKind::Block(ref block, _) = expr.kind { - for ref stmt in block.stmts { - if_chain! { - if let StmtKind::Local( - Local { pat: Pat { hir_id: pat_id, kind: PatKind::Binding(_, _, ident, .. ), .. }, - init: Some(ref init_expr), .. } - ) = stmt.kind; - if let ExprKind::MethodCall(ref method_name, _, &[ref iter_source], ..) = init_expr.kind; - if method_name.ident.name == sym!(collect) && match_trait_method(cx, &init_expr, &paths::ITERATOR); - if let Some(ref generic_args) = method_name.args; - if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); - if let ty = cx.typeck_results().node_type(ty.hir_id); - if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || - match_type(cx, ty, &paths::LINKED_LIST); - if let Some(iter_calls) = detect_iter_and_into_iters(block, *ident); - if iter_calls.len() == 1; - then { - let mut used_count_visitor = UsedCountVisitor { - cx, - id: *pat_id, - count: 0, - }; - walk_block(&mut used_count_visitor, block); - if used_count_visitor.count > 1 { - return; - } - - // Suggest replacing iter_call with iter_replacement, and removing stmt - let iter_call = &iter_calls[0]; - span_lint_and_then( - cx, - NEEDLESS_COLLECT, - stmt.span.until(iter_call.span), - NEEDLESS_COLLECT_MSG, - |diag| { - let iter_replacement = format!("{}{}", Sugg::hir(cx, iter_source, ".."), iter_call.get_iter_method(cx)); - diag.multipart_suggestion( - iter_call.get_suggestion_text(), - vec![ - (stmt.span, String::new()), - (iter_call.span, iter_replacement) - ], - Applicability::MachineApplicable,// MaybeIncorrect, - ).emit(); - }, - ); - } - } - } - } -} - -struct IterFunction { - func: IterFunctionKind, - span: Span, -} -impl IterFunction { - fn get_iter_method(&self, cx: &LateContext<'_>) -> String { - match &self.func { - IterFunctionKind::IntoIter => String::new(), - IterFunctionKind::Len => String::from(".count()"), - IterFunctionKind::IsEmpty => String::from(".next().is_none()"), - IterFunctionKind::Contains(span) => { - let s = snippet(cx, *span, ".."); - if let Some(stripped) = s.strip_prefix('&') { - format!(".any(|x| x == {})", stripped) - } else { - format!(".any(|x| x == *{})", s) - } - }, - } - } - fn get_suggestion_text(&self) -> &'static str { - match &self.func { - IterFunctionKind::IntoIter => { - "use the original Iterator instead of collecting it and then producing a new one" - }, - IterFunctionKind::Len => { - "take the original Iterator's count instead of collecting it and finding the length" - }, - IterFunctionKind::IsEmpty => { - "check if the original Iterator has anything instead of collecting it and seeing if it's empty" - }, - IterFunctionKind::Contains(_) => { - "check if the original Iterator contains an element instead of collecting then checking" - }, - } - } -} -enum IterFunctionKind { - IntoIter, - Len, - IsEmpty, - Contains(Span), -} - -struct IterFunctionVisitor { - uses: Vec, - seen_other: bool, - target: Ident, -} -impl<'tcx> Visitor<'tcx> for IterFunctionVisitor { - fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { - // Check function calls on our collection - if_chain! { - if let ExprKind::MethodCall(method_name, _, ref args, _) = &expr.kind; - if let Some(Expr { kind: ExprKind::Path(QPath::Resolved(_, ref path)), .. }) = args.get(0); - if let &[name] = &path.segments; - if name.ident == self.target; - then { - let len = sym!(len); - let is_empty = sym!(is_empty); - let contains = sym!(contains); - match method_name.ident.name { - sym::into_iter => self.uses.push( - IterFunction { func: IterFunctionKind::IntoIter, span: expr.span } - ), - name if name == len => self.uses.push( - IterFunction { func: IterFunctionKind::Len, span: expr.span } - ), - name if name == is_empty => self.uses.push( - IterFunction { func: IterFunctionKind::IsEmpty, span: expr.span } - ), - name if name == contains => self.uses.push( - IterFunction { func: IterFunctionKind::Contains(args[1].span), span: expr.span } - ), - _ => self.seen_other = true, - } - return - } - } - // Check if the collection is used for anything else - if_chain! { - if let Expr { kind: ExprKind::Path(QPath::Resolved(_, ref path)), .. } = expr; - if let &[name] = &path.segments; - if name.ident == self.target; - then { - self.seen_other = true; - } else { - walk_expr(self, expr); - } - } - } - - type Map = Map<'tcx>; - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - -struct UsedCountVisitor<'a, 'tcx> { - cx: &'a LateContext<'tcx>, - id: HirId, - count: usize, -} - -impl<'a, 'tcx> Visitor<'tcx> for UsedCountVisitor<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if path_to_local_id(expr, self.id) { - self.count += 1; - } else { - walk_expr(self, expr); - } - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::OnlyBodies(self.cx.tcx.hir()) - } -} - -/// Detect the occurrences of calls to `iter` or `into_iter` for the -/// given identifier -fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, identifier: Ident) -> Option> { - let mut visitor = IterFunctionVisitor { - uses: Vec::new(), - target: identifier, - seen_other: false, - }; - visitor.visit_block(block); - if visitor.seen_other { None } else { Some(visitor.uses) } -} - -fn shorten_needless_collect_span(expr: &Expr<'_>) -> Span { - if_chain! { - if let ExprKind::MethodCall(.., args, _) = &expr.kind; - if let ExprKind::MethodCall(_, span, ..) = &args[0].kind; - then { - return expr.span.with_lo(span.lo()); - } - } - unreachable!(); -} diff --git a/clippy_lints/src/loops/needless_collect.rs b/clippy_lints/src/loops/needless_collect.rs new file mode 100644 index 0000000000000..cc2e297549276 --- /dev/null +++ b/clippy_lints/src/loops/needless_collect.rs @@ -0,0 +1,282 @@ +use crate::utils::sugg::Sugg; +use crate::utils::{ + is_type_diagnostic_item, match_trait_method, match_type, path_to_local_id, paths, snippet, span_lint_and_sugg, + span_lint_and_then, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::intravisit::{walk_block, walk_expr, NestedVisitorMap, Visitor}; +use rustc_hir::{Block, Expr, ExprKind, GenericArg, HirId, Local, Pat, PatKind, QPath, StmtKind}; +use rustc_lint::LateContext; +use rustc_middle::hir::map::Map; +use rustc_span::source_map::Span; +use rustc_span::symbol::{sym, Ident}; + +const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; + +pub(super) fn check_needless_collect<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { + check_needless_collect_direct_usage(expr, cx); + check_needless_collect_indirect_usage(expr, cx); +} +fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { + if_chain! { + if let ExprKind::MethodCall(ref method, _, ref args, _) = expr.kind; + if let ExprKind::MethodCall(ref chain_method, _, _, _) = args[0].kind; + if chain_method.ident.name == sym!(collect) && match_trait_method(cx, &args[0], &paths::ITERATOR); + if let Some(ref generic_args) = chain_method.args; + if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); + then { + let ty = cx.typeck_results().node_type(ty.hir_id); + if is_type_diagnostic_item(cx, ty, sym::vec_type) || + is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + match_type(cx, ty, &paths::BTREEMAP) || + is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { + if method.ident.name == sym!(len) { + let span = shorten_needless_collect_span(expr); + span_lint_and_sugg( + cx, + super::NEEDLESS_COLLECT, + span, + NEEDLESS_COLLECT_MSG, + "replace with", + "count()".to_string(), + Applicability::MachineApplicable, + ); + } + if method.ident.name == sym!(is_empty) { + let span = shorten_needless_collect_span(expr); + span_lint_and_sugg( + cx, + super::NEEDLESS_COLLECT, + span, + NEEDLESS_COLLECT_MSG, + "replace with", + "next().is_none()".to_string(), + Applicability::MachineApplicable, + ); + } + if method.ident.name == sym!(contains) { + let contains_arg = snippet(cx, args[1].span, "??"); + let span = shorten_needless_collect_span(expr); + span_lint_and_then( + cx, + super::NEEDLESS_COLLECT, + span, + NEEDLESS_COLLECT_MSG, + |diag| { + let (arg, pred) = contains_arg + .strip_prefix('&') + .map_or(("&x", &*contains_arg), |s| ("x", s)); + diag.span_suggestion( + span, + "replace with", + format!( + "any(|{}| x == {})", + arg, pred + ), + Applicability::MachineApplicable, + ); + } + ); + } + } + } + } +} + +fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { + if let ExprKind::Block(ref block, _) = expr.kind { + for ref stmt in block.stmts { + if_chain! { + if let StmtKind::Local( + Local { pat: Pat { hir_id: pat_id, kind: PatKind::Binding(_, _, ident, .. ), .. }, + init: Some(ref init_expr), .. } + ) = stmt.kind; + if let ExprKind::MethodCall(ref method_name, _, &[ref iter_source], ..) = init_expr.kind; + if method_name.ident.name == sym!(collect) && match_trait_method(cx, &init_expr, &paths::ITERATOR); + if let Some(ref generic_args) = method_name.args; + if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); + if let ty = cx.typeck_results().node_type(ty.hir_id); + if is_type_diagnostic_item(cx, ty, sym::vec_type) || + is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + match_type(cx, ty, &paths::LINKED_LIST); + if let Some(iter_calls) = detect_iter_and_into_iters(block, *ident); + if iter_calls.len() == 1; + then { + let mut used_count_visitor = UsedCountVisitor { + cx, + id: *pat_id, + count: 0, + }; + walk_block(&mut used_count_visitor, block); + if used_count_visitor.count > 1 { + return; + } + + // Suggest replacing iter_call with iter_replacement, and removing stmt + let iter_call = &iter_calls[0]; + span_lint_and_then( + cx, + super::NEEDLESS_COLLECT, + stmt.span.until(iter_call.span), + NEEDLESS_COLLECT_MSG, + |diag| { + let iter_replacement = format!("{}{}", Sugg::hir(cx, iter_source, ".."), iter_call.get_iter_method(cx)); + diag.multipart_suggestion( + iter_call.get_suggestion_text(), + vec![ + (stmt.span, String::new()), + (iter_call.span, iter_replacement) + ], + Applicability::MachineApplicable,// MaybeIncorrect, + ).emit(); + }, + ); + } + } + } + } +} + +struct IterFunction { + func: IterFunctionKind, + span: Span, +} +impl IterFunction { + fn get_iter_method(&self, cx: &LateContext<'_>) -> String { + match &self.func { + IterFunctionKind::IntoIter => String::new(), + IterFunctionKind::Len => String::from(".count()"), + IterFunctionKind::IsEmpty => String::from(".next().is_none()"), + IterFunctionKind::Contains(span) => { + let s = snippet(cx, *span, ".."); + if let Some(stripped) = s.strip_prefix('&') { + format!(".any(|x| x == {})", stripped) + } else { + format!(".any(|x| x == *{})", s) + } + }, + } + } + fn get_suggestion_text(&self) -> &'static str { + match &self.func { + IterFunctionKind::IntoIter => { + "use the original Iterator instead of collecting it and then producing a new one" + }, + IterFunctionKind::Len => { + "take the original Iterator's count instead of collecting it and finding the length" + }, + IterFunctionKind::IsEmpty => { + "check if the original Iterator has anything instead of collecting it and seeing if it's empty" + }, + IterFunctionKind::Contains(_) => { + "check if the original Iterator contains an element instead of collecting then checking" + }, + } + } +} +enum IterFunctionKind { + IntoIter, + Len, + IsEmpty, + Contains(Span), +} + +struct IterFunctionVisitor { + uses: Vec, + seen_other: bool, + target: Ident, +} +impl<'tcx> Visitor<'tcx> for IterFunctionVisitor { + fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { + // Check function calls on our collection + if_chain! { + if let ExprKind::MethodCall(method_name, _, ref args, _) = &expr.kind; + if let Some(Expr { kind: ExprKind::Path(QPath::Resolved(_, ref path)), .. }) = args.get(0); + if let &[name] = &path.segments; + if name.ident == self.target; + then { + let len = sym!(len); + let is_empty = sym!(is_empty); + let contains = sym!(contains); + match method_name.ident.name { + sym::into_iter => self.uses.push( + IterFunction { func: IterFunctionKind::IntoIter, span: expr.span } + ), + name if name == len => self.uses.push( + IterFunction { func: IterFunctionKind::Len, span: expr.span } + ), + name if name == is_empty => self.uses.push( + IterFunction { func: IterFunctionKind::IsEmpty, span: expr.span } + ), + name if name == contains => self.uses.push( + IterFunction { func: IterFunctionKind::Contains(args[1].span), span: expr.span } + ), + _ => self.seen_other = true, + } + return + } + } + // Check if the collection is used for anything else + if_chain! { + if let Expr { kind: ExprKind::Path(QPath::Resolved(_, ref path)), .. } = expr; + if let &[name] = &path.segments; + if name.ident == self.target; + then { + self.seen_other = true; + } else { + walk_expr(self, expr); + } + } + } + + type Map = Map<'tcx>; + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} + +struct UsedCountVisitor<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + id: HirId, + count: usize, +} + +impl<'a, 'tcx> Visitor<'tcx> for UsedCountVisitor<'a, 'tcx> { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if path_to_local_id(expr, self.id) { + self.count += 1; + } else { + walk_expr(self, expr); + } + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::OnlyBodies(self.cx.tcx.hir()) + } +} + +/// Detect the occurrences of calls to `iter` or `into_iter` for the +/// given identifier +fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, identifier: Ident) -> Option> { + let mut visitor = IterFunctionVisitor { + uses: Vec::new(), + target: identifier, + seen_other: false, + }; + visitor.visit_block(block); + if visitor.seen_other { None } else { Some(visitor.uses) } +} + +fn shorten_needless_collect_span(expr: &Expr<'_>) -> Span { + if_chain! { + if let ExprKind::MethodCall(.., args, _) = &expr.kind; + if let ExprKind::MethodCall(_, span, ..) = &args[0].kind; + then { + return expr.span.with_lo(span.lo()); + } + } + unreachable!(); +} From 2c1f676bfe831f488cbd8e07d46b7b9be727ca24 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Tue, 9 Feb 2021 21:58:10 +0100 Subject: [PATCH 064/226] Add detect_same_item_push to its own module --- clippy_lints/src/loops/mod.rs | 171 +---------------------- clippy_lints/src/loops/same_item_push.rs | 168 ++++++++++++++++++++++ 2 files changed, 174 insertions(+), 165 deletions(-) create mode 100644 clippy_lints/src/loops/same_item_push.rs diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 043bbc9d1c589..66b71a7202ea6 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -7,6 +7,7 @@ mod for_single_element_loop; mod infinite_loop; mod manual_flatten; mod needless_collect; +mod same_item_push; mod utils; use crate::utils::sugg::Sugg; @@ -14,18 +15,17 @@ use crate::utils::usage::mutated_variables; use crate::utils::{ get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment, match_trait_method, - path_to_local, path_to_local_id, paths, snippet, snippet_with_applicability, snippet_with_macro_callsite, - span_lint, span_lint_and_help, span_lint_and_sugg, sugg, + path_to_local, path_to_local_id, paths, snippet, snippet_with_applicability, span_lint, span_lint_and_help, + span_lint_and_sugg, sugg, }; use if_chain::if_chain; use rustc_ast::ast; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; -use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; use rustc_hir::{ - BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, HirId, InlineAsmOperand, LoopSource, MatchSource, - Mutability, Node, Pat, PatKind, Stmt, StmtKind, + BinOpKind, Block, BorrowKind, Expr, ExprKind, HirId, InlineAsmOperand, LoopSource, MatchSource, Mutability, Node, + Pat, PatKind, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -866,7 +866,7 @@ fn check_for_loop<'tcx>( for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); for_mut_range_bound::check_for_mut_range_bound(cx, arg, body); for_single_element_loop::check_for_single_element_loop(cx, pat, arg, body, expr); - detect_same_item_push(cx, pat, arg, body, expr); + same_item_push::detect_same_item_push(cx, pat, arg, body, expr); manual_flatten::check_manual_flatten(cx, pat, arg, body, span); } @@ -1307,165 +1307,6 @@ fn detect_manual_memcpy<'tcx>( false } -// Scans the body of the for loop and determines whether lint should be given -struct SameItemPushVisitor<'a, 'tcx> { - should_lint: bool, - // this field holds the last vec push operation visited, which should be the only push seen - vec_push: Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)>, - cx: &'a LateContext<'tcx>, -} - -impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - match &expr.kind { - // Non-determinism may occur ... don't give a lint - ExprKind::Loop(..) | ExprKind::Match(..) => self.should_lint = false, - ExprKind::Block(block, _) => self.visit_block(block), - _ => {}, - } - } - - fn visit_block(&mut self, b: &'tcx Block<'_>) { - for stmt in b.stmts.iter() { - self.visit_stmt(stmt); - } - } - - fn visit_stmt(&mut self, s: &'tcx Stmt<'_>) { - let vec_push_option = get_vec_push(self.cx, s); - if vec_push_option.is_none() { - // Current statement is not a push so visit inside - match &s.kind { - StmtKind::Expr(expr) | StmtKind::Semi(expr) => self.visit_expr(&expr), - _ => {}, - } - } else { - // Current statement is a push ...check whether another - // push had been previously done - if self.vec_push.is_none() { - self.vec_push = vec_push_option; - } else { - // There are multiple pushes ... don't lint - self.should_lint = false; - } - } - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - -// Given some statement, determine if that statement is a push on a Vec. If it is, return -// the Vec being pushed into and the item being pushed -fn get_vec_push<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { - if_chain! { - // Extract method being called - if let StmtKind::Semi(semi_stmt) = &stmt.kind; - if let ExprKind::MethodCall(path, _, args, _) = &semi_stmt.kind; - // Figure out the parameters for the method call - if let Some(self_expr) = args.get(0); - if let Some(pushed_item) = args.get(1); - // Check that the method being called is push() on a Vec - if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::vec_type); - if path.ident.name.as_str() == "push"; - then { - return Some((self_expr, pushed_item)) - } - } - None -} - -/// Detects for loop pushing the same item into a Vec -fn detect_same_item_push<'tcx>( - cx: &LateContext<'tcx>, - pat: &'tcx Pat<'_>, - _: &'tcx Expr<'_>, - body: &'tcx Expr<'_>, - _: &'tcx Expr<'_>, -) { - fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>) { - let vec_str = snippet_with_macro_callsite(cx, vec.span, ""); - let item_str = snippet_with_macro_callsite(cx, pushed_item.span, ""); - - span_lint_and_help( - cx, - SAME_ITEM_PUSH, - vec.span, - "it looks like the same item is being pushed into this Vec", - None, - &format!( - "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})", - item_str, vec_str, item_str - ), - ) - } - - if !matches!(pat.kind, PatKind::Wild) { - return; - } - - // Determine whether it is safe to lint the body - let mut same_item_push_visitor = SameItemPushVisitor { - should_lint: true, - vec_push: None, - cx, - }; - walk_expr(&mut same_item_push_visitor, body); - if same_item_push_visitor.should_lint { - if let Some((vec, pushed_item)) = same_item_push_visitor.vec_push { - let vec_ty = cx.typeck_results().expr_ty(vec); - let ty = vec_ty.walk().nth(1).unwrap().expect_ty(); - if cx - .tcx - .lang_items() - .clone_trait() - .map_or(false, |id| implements_trait(cx, ty, id, &[])) - { - // Make sure that the push does not involve possibly mutating values - match pushed_item.kind { - ExprKind::Path(ref qpath) => { - match cx.qpath_res(qpath, pushed_item.hir_id) { - // immutable bindings that are initialized with literal or constant - Res::Local(hir_id) => { - if_chain! { - let node = cx.tcx.hir().get(hir_id); - if let Node::Binding(pat) = node; - if let PatKind::Binding(bind_ann, ..) = pat.kind; - if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable); - let parent_node = cx.tcx.hir().get_parent_node(hir_id); - if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node); - if let Some(init) = parent_let_expr.init; - then { - match init.kind { - // immutable bindings that are initialized with literal - ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item), - // immutable bindings that are initialized with constant - ExprKind::Path(ref path) => { - if let Res::Def(DefKind::Const, ..) = cx.qpath_res(path, init.hir_id) { - emit_lint(cx, vec, pushed_item); - } - } - _ => {}, - } - } - } - }, - // constant - Res::Def(DefKind::Const, ..) => emit_lint(cx, vec, pushed_item), - _ => {}, - } - }, - ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item), - _ => {}, - } - } - } - } -} - fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { let def_id = match path_to_local(expr) { Some(id) => id, diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs new file mode 100644 index 0000000000000..62efb58a38f7d --- /dev/null +++ b/clippy_lints/src/loops/same_item_push.rs @@ -0,0 +1,168 @@ +use crate::utils::{implements_trait, is_type_diagnostic_item, snippet_with_macro_callsite, span_lint_and_help}; +use if_chain::if_chain; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; +use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, Node, Pat, PatKind, Stmt, StmtKind}; +use rustc_lint::LateContext; +use rustc_middle::hir::map::Map; +use rustc_span::symbol::sym; +use std::iter::Iterator; + +/// Detects for loop pushing the same item into a Vec +pub(super) fn detect_same_item_push<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + _: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + _: &'tcx Expr<'_>, +) { + fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>) { + let vec_str = snippet_with_macro_callsite(cx, vec.span, ""); + let item_str = snippet_with_macro_callsite(cx, pushed_item.span, ""); + + span_lint_and_help( + cx, + super::SAME_ITEM_PUSH, + vec.span, + "it looks like the same item is being pushed into this Vec", + None, + &format!( + "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})", + item_str, vec_str, item_str + ), + ) + } + + if !matches!(pat.kind, PatKind::Wild) { + return; + } + + // Determine whether it is safe to lint the body + let mut same_item_push_visitor = SameItemPushVisitor { + should_lint: true, + vec_push: None, + cx, + }; + walk_expr(&mut same_item_push_visitor, body); + if same_item_push_visitor.should_lint { + if let Some((vec, pushed_item)) = same_item_push_visitor.vec_push { + let vec_ty = cx.typeck_results().expr_ty(vec); + let ty = vec_ty.walk().nth(1).unwrap().expect_ty(); + if cx + .tcx + .lang_items() + .clone_trait() + .map_or(false, |id| implements_trait(cx, ty, id, &[])) + { + // Make sure that the push does not involve possibly mutating values + match pushed_item.kind { + ExprKind::Path(ref qpath) => { + match cx.qpath_res(qpath, pushed_item.hir_id) { + // immutable bindings that are initialized with literal or constant + Res::Local(hir_id) => { + if_chain! { + let node = cx.tcx.hir().get(hir_id); + if let Node::Binding(pat) = node; + if let PatKind::Binding(bind_ann, ..) = pat.kind; + if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable); + let parent_node = cx.tcx.hir().get_parent_node(hir_id); + if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node); + if let Some(init) = parent_let_expr.init; + then { + match init.kind { + // immutable bindings that are initialized with literal + ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item), + // immutable bindings that are initialized with constant + ExprKind::Path(ref path) => { + if let Res::Def(DefKind::Const, ..) = cx.qpath_res(path, init.hir_id) { + emit_lint(cx, vec, pushed_item); + } + } + _ => {}, + } + } + } + }, + // constant + Res::Def(DefKind::Const, ..) => emit_lint(cx, vec, pushed_item), + _ => {}, + } + }, + ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item), + _ => {}, + } + } + } + } +} + +// Scans the body of the for loop and determines whether lint should be given +struct SameItemPushVisitor<'a, 'tcx> { + should_lint: bool, + // this field holds the last vec push operation visited, which should be the only push seen + vec_push: Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)>, + cx: &'a LateContext<'tcx>, +} + +impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + match &expr.kind { + // Non-determinism may occur ... don't give a lint + ExprKind::Loop(..) | ExprKind::Match(..) => self.should_lint = false, + ExprKind::Block(block, _) => self.visit_block(block), + _ => {}, + } + } + + fn visit_block(&mut self, b: &'tcx Block<'_>) { + for stmt in b.stmts.iter() { + self.visit_stmt(stmt); + } + } + + fn visit_stmt(&mut self, s: &'tcx Stmt<'_>) { + let vec_push_option = get_vec_push(self.cx, s); + if vec_push_option.is_none() { + // Current statement is not a push so visit inside + match &s.kind { + StmtKind::Expr(expr) | StmtKind::Semi(expr) => self.visit_expr(&expr), + _ => {}, + } + } else { + // Current statement is a push ...check whether another + // push had been previously done + if self.vec_push.is_none() { + self.vec_push = vec_push_option; + } else { + // There are multiple pushes ... don't lint + self.should_lint = false; + } + } + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} + +// Given some statement, determine if that statement is a push on a Vec. If it is, return +// the Vec being pushed into and the item being pushed +fn get_vec_push<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { + if_chain! { + // Extract method being called + if let StmtKind::Semi(semi_stmt) = &stmt.kind; + if let ExprKind::MethodCall(path, _, args, _) = &semi_stmt.kind; + // Figure out the parameters for the method call + if let Some(self_expr) = args.get(0); + if let Some(pushed_item) = args.get(1); + // Check that the method being called is push() on a Vec + if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::vec_type); + if path.ident.name.as_str() == "push"; + then { + return Some((self_expr, pushed_item)) + } + } + None +} From 5b870e1b36e781d842c7c84290707f2aaf5dc8cf Mon Sep 17 00:00:00 2001 From: nahuakang Date: Tue, 9 Feb 2021 23:27:03 +0100 Subject: [PATCH 065/226] Move detect_manual_memcpy to its module; split up utils structs --- clippy_lints/src/loops/manual_memcpy.rs | 381 +++++++++++++ clippy_lints/src/loops/mod.rs | 684 +----------------------- clippy_lints/src/loops/utils.rs | 302 ++++++++++- 3 files changed, 694 insertions(+), 673 deletions(-) create mode 100644 clippy_lints/src/loops/manual_memcpy.rs diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs new file mode 100644 index 0000000000000..85b3dfaece736 --- /dev/null +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -0,0 +1,381 @@ +use super::{get_span_of_entire_for_loop, IncrementVisitor, InitializeVisitor, MinifyingSugg}; +use crate::utils::sugg::Sugg; +use crate::utils::{ + get_enclosing_block, higher, is_type_diagnostic_item, path_to_local, snippet, span_lint_and_sugg, sugg, +}; +use if_chain::if_chain; +use rustc_ast::ast; +use rustc_errors::Applicability; +use rustc_hir::intravisit::walk_block; +use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Pat, PatKind, StmtKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; +use rustc_span::symbol::sym; +use std::iter::Iterator; + +/// Checks for for loops that sequentially copy items from one slice-like +/// object to another. +pub(super) fn detect_manual_memcpy<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, +) -> bool { + if let Some(higher::Range { + start: Some(start), + end: Some(end), + limits, + }) = higher::range(arg) + { + // the var must be a single name + if let PatKind::Binding(_, canonical_id, _, _) = pat.kind { + let mut starts = vec![Start { + id: canonical_id, + kind: StartKind::Range, + }]; + + // This is one of few ways to return different iterators + // derived from: https://stackoverflow.com/questions/29760668/conditionally-iterate-over-one-of-several-possible-iterators/52064434#52064434 + let mut iter_a = None; + let mut iter_b = None; + + if let ExprKind::Block(block, _) = body.kind { + if let Some(loop_counters) = get_loop_counters(cx, block, expr) { + starts.extend(loop_counters); + } + iter_a = Some(get_assignments(block, &starts)); + } else { + iter_b = Some(get_assignment(body)); + } + + let assignments = iter_a.into_iter().flatten().chain(iter_b.into_iter()); + + let big_sugg = assignments + // The only statements in the for loops can be indexed assignments from + // indexed retrievals (except increments of loop counters). + .map(|o| { + o.and_then(|(lhs, rhs)| { + let rhs = fetch_cloned_expr(rhs); + if_chain! { + if let ExprKind::Index(base_left, idx_left) = lhs.kind; + if let ExprKind::Index(base_right, idx_right) = rhs.kind; + if is_slice_like(cx, cx.typeck_results().expr_ty(base_left)) + && is_slice_like(cx, cx.typeck_results().expr_ty(base_right)); + if let Some((start_left, offset_left)) = get_details_from_idx(cx, &idx_left, &starts); + if let Some((start_right, offset_right)) = get_details_from_idx(cx, &idx_right, &starts); + + // Source and destination must be different + if path_to_local(base_left) != path_to_local(base_right); + then { + Some((IndexExpr { base: base_left, idx: start_left, idx_offset: offset_left }, + IndexExpr { base: base_right, idx: start_right, idx_offset: offset_right })) + } else { + None + } + } + }) + }) + .map(|o| o.map(|(dst, src)| build_manual_memcpy_suggestion(cx, start, end, limits, &dst, &src))) + .collect::>>() + .filter(|v| !v.is_empty()) + .map(|v| v.join("\n ")); + + if let Some(big_sugg) = big_sugg { + span_lint_and_sugg( + cx, + super::MANUAL_MEMCPY, + get_span_of_entire_for_loop(expr), + "it looks like you're manually copying between slices", + "try replacing the loop by", + big_sugg, + Applicability::Unspecified, + ); + return true; + } + } + } + false +} + +fn build_manual_memcpy_suggestion<'tcx>( + cx: &LateContext<'tcx>, + start: &Expr<'_>, + end: &Expr<'_>, + limits: ast::RangeLimits, + dst: &IndexExpr<'_>, + src: &IndexExpr<'_>, +) -> String { + fn print_offset(offset: MinifyingSugg<'static>) -> MinifyingSugg<'static> { + if offset.as_str() == "0" { + sugg::EMPTY.into() + } else { + offset + } + } + + let print_limit = |end: &Expr<'_>, end_str: &str, base: &Expr<'_>, sugg: MinifyingSugg<'static>| { + if_chain! { + if let ExprKind::MethodCall(method, _, len_args, _) = end.kind; + if method.ident.name == sym!(len); + if len_args.len() == 1; + if let Some(arg) = len_args.get(0); + if path_to_local(arg) == path_to_local(base); + then { + if sugg.as_str() == end_str { + sugg::EMPTY.into() + } else { + sugg + } + } else { + match limits { + ast::RangeLimits::Closed => { + sugg + &sugg::ONE.into() + }, + ast::RangeLimits::HalfOpen => sugg, + } + } + } + }; + + let start_str = Sugg::hir(cx, start, "").into(); + let end_str: MinifyingSugg<'_> = Sugg::hir(cx, end, "").into(); + + let print_offset_and_limit = |idx_expr: &IndexExpr<'_>| match idx_expr.idx { + StartKind::Range => ( + print_offset(apply_offset(&start_str, &idx_expr.idx_offset)).into_sugg(), + print_limit( + end, + end_str.as_str(), + idx_expr.base, + apply_offset(&end_str, &idx_expr.idx_offset), + ) + .into_sugg(), + ), + StartKind::Counter { initializer } => { + let counter_start = Sugg::hir(cx, initializer, "").into(); + ( + print_offset(apply_offset(&counter_start, &idx_expr.idx_offset)).into_sugg(), + print_limit( + end, + end_str.as_str(), + idx_expr.base, + apply_offset(&end_str, &idx_expr.idx_offset) + &counter_start - &start_str, + ) + .into_sugg(), + ) + }, + }; + + let (dst_offset, dst_limit) = print_offset_and_limit(&dst); + let (src_offset, src_limit) = print_offset_and_limit(&src); + + let dst_base_str = snippet(cx, dst.base.span, "???"); + let src_base_str = snippet(cx, src.base.span, "???"); + + let dst = if dst_offset == sugg::EMPTY && dst_limit == sugg::EMPTY { + dst_base_str + } else { + format!( + "{}[{}..{}]", + dst_base_str, + dst_offset.maybe_par(), + dst_limit.maybe_par() + ) + .into() + }; + + format!( + "{}.clone_from_slice(&{}[{}..{}]);", + dst, + src_base_str, + src_offset.maybe_par(), + src_limit.maybe_par() + ) +} + +/// a wrapper around `MinifyingSugg`, which carries a operator like currying +/// so that the suggested code become more efficient (e.g. `foo + -bar` `foo - bar`). +struct Offset { + value: MinifyingSugg<'static>, + sign: OffsetSign, +} + +#[derive(Clone, Copy)] +enum OffsetSign { + Positive, + Negative, +} + +impl Offset { + fn negative(value: Sugg<'static>) -> Self { + Self { + value: value.into(), + sign: OffsetSign::Negative, + } + } + + fn positive(value: Sugg<'static>) -> Self { + Self { + value: value.into(), + sign: OffsetSign::Positive, + } + } + + fn empty() -> Self { + Self::positive(sugg::ZERO) + } +} + +fn apply_offset(lhs: &MinifyingSugg<'static>, rhs: &Offset) -> MinifyingSugg<'static> { + match rhs.sign { + OffsetSign::Positive => lhs + &rhs.value, + OffsetSign::Negative => lhs - &rhs.value, + } +} + +#[derive(Debug, Clone, Copy)] +enum StartKind<'hir> { + Range, + Counter { initializer: &'hir Expr<'hir> }, +} + +struct IndexExpr<'hir> { + base: &'hir Expr<'hir>, + idx: StartKind<'hir>, + idx_offset: Offset, +} + +struct Start<'hir> { + id: HirId, + kind: StartKind<'hir>, +} + +fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'_>) -> bool { + let is_slice = match ty.kind() { + ty::Ref(_, subty, _) => is_slice_like(cx, subty), + ty::Slice(..) | ty::Array(..) => true, + _ => false, + }; + + is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) +} + +fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { + if_chain! { + if let ExprKind::MethodCall(method, _, args, _) = expr.kind; + if method.ident.name == sym::clone; + if args.len() == 1; + if let Some(arg) = args.get(0); + then { arg } else { expr } + } +} + +fn get_details_from_idx<'tcx>( + cx: &LateContext<'tcx>, + idx: &Expr<'_>, + starts: &[Start<'tcx>], +) -> Option<(StartKind<'tcx>, Offset)> { + fn get_start<'tcx>(e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option> { + let id = path_to_local(e)?; + starts.iter().find(|start| start.id == id).map(|start| start.kind) + } + + fn get_offset<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option> { + match &e.kind { + ExprKind::Lit(l) => match l.node { + ast::LitKind::Int(x, _ty) => Some(Sugg::NonParen(x.to_string().into())), + _ => None, + }, + ExprKind::Path(..) if get_start(e, starts).is_none() => Some(Sugg::hir(cx, e, "???")), + _ => None, + } + } + + match idx.kind { + ExprKind::Binary(op, lhs, rhs) => match op.node { + BinOpKind::Add => { + let offset_opt = get_start(lhs, starts) + .and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, o))) + .or_else(|| get_start(rhs, starts).and_then(|s| get_offset(cx, lhs, starts).map(|o| (s, o)))); + + offset_opt.map(|(s, o)| (s, Offset::positive(o))) + }, + BinOpKind::Sub => { + get_start(lhs, starts).and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, Offset::negative(o)))) + }, + _ => None, + }, + ExprKind::Path(..) => get_start(idx, starts).map(|s| (s, Offset::empty())), + _ => None, + } +} + +fn get_assignment<'tcx>(e: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { + if let ExprKind::Assign(lhs, rhs, _) = e.kind { + Some((lhs, rhs)) + } else { + None + } +} + +/// Get assignments from the given block. +/// The returned iterator yields `None` if no assignment expressions are there, +/// filtering out the increments of the given whitelisted loop counters; +/// because its job is to make sure there's nothing other than assignments and the increments. +fn get_assignments<'a, 'tcx>( + Block { stmts, expr, .. }: &'tcx Block<'tcx>, + loop_counters: &'a [Start<'tcx>], +) -> impl Iterator, &'tcx Expr<'tcx>)>> + 'a { + // As the `filter` and `map` below do different things, I think putting together + // just increases complexity. (cc #3188 and #4193) + stmts + .iter() + .filter_map(move |stmt| match stmt.kind { + StmtKind::Local(..) | StmtKind::Item(..) => None, + StmtKind::Expr(e) | StmtKind::Semi(e) => Some(e), + }) + .chain((*expr).into_iter()) + .filter(move |e| { + if let ExprKind::AssignOp(_, place, _) = e.kind { + path_to_local(place).map_or(false, |id| { + !loop_counters + .iter() + // skip the first item which should be `StartKind::Range` + // this makes it possible to use the slice with `StartKind::Range` in the same iterator loop. + .skip(1) + .any(|counter| counter.id == id) + }) + } else { + true + } + }) + .map(get_assignment) +} + +fn get_loop_counters<'a, 'tcx>( + cx: &'a LateContext<'tcx>, + body: &'tcx Block<'tcx>, + expr: &'tcx Expr<'_>, +) -> Option> + 'a> { + // Look for variables that are incremented once per loop iteration. + let mut increment_visitor = IncrementVisitor::new(cx); + walk_block(&mut increment_visitor, body); + + // For each candidate, check the parent block to see if + // it's initialized to zero at the start of the loop. + get_enclosing_block(&cx, expr.hir_id).and_then(|block| { + increment_visitor + .into_results() + .filter_map(move |var_id| { + let mut initialize_visitor = InitializeVisitor::new(cx, expr, var_id); + walk_block(&mut initialize_visitor, block); + + initialize_visitor.get_result().map(|(_, initializer)| Start { + id: var_id, + kind: StartKind::Counter { initializer }, + }) + }) + .into() + }) +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 66b71a7202ea6..c6055e34eb2ef 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -6,6 +6,7 @@ mod for_mut_range_bound; mod for_single_element_loop; mod infinite_loop; mod manual_flatten; +mod manual_memcpy; mod needless_collect; mod same_item_push; mod utils; @@ -13,29 +14,26 @@ mod utils; use crate::utils::sugg::Sugg; use crate::utils::usage::mutated_variables; use crate::utils::{ - get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, is_in_panic_handler, - is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment, match_trait_method, - path_to_local, path_to_local_id, paths, snippet, snippet_with_applicability, span_lint, span_lint_and_help, - span_lint_and_sugg, sugg, + get_enclosing_block, get_trait_def_id, higher, implements_trait, is_in_panic_handler, is_no_std_crate, + is_refutable, last_path_segment, match_trait_method, path_to_local, path_to_local_id, paths, + snippet_with_applicability, span_lint, span_lint_and_help, span_lint_and_sugg, sugg, }; use if_chain::if_chain; -use rustc_ast::ast; -use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; -use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; +use rustc_hir::intravisit::{walk_block, walk_expr, NestedVisitorMap, Visitor}; use rustc_hir::{ - BinOpKind, Block, BorrowKind, Expr, ExprKind, HirId, InlineAsmOperand, LoopSource, MatchSource, Mutability, Node, - Pat, PatKind, Stmt, StmtKind, + Block, Expr, ExprKind, HirId, InlineAsmOperand, LoopSource, MatchSource, Node, Pat, PatKind, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::sym; use std::iter::{once, Iterator}; -use utils::{get_span_of_entire_for_loop, make_iterator_snippet}; +use utils::{ + get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor, LoopNestVisitor, Nesting, +}; declare_clippy_lint! { /// **What it does:** Checks for for-loops that manually copy items between @@ -857,7 +855,7 @@ fn check_for_loop<'tcx>( expr: &'tcx Expr<'_>, span: Span, ) { - let is_manual_memcpy_triggered = detect_manual_memcpy(cx, pat, arg, body, expr); + let is_manual_memcpy_triggered = manual_memcpy::detect_manual_memcpy(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { for_loop_range::check_for_loop_range(cx, pat, arg, body, expr); for_loop_explicit_counter::check_for_loop_explicit_counter(cx, pat, arg, body, expr); @@ -940,373 +938,6 @@ impl std::ops::Sub<&MinifyingSugg<'static>> for MinifyingSugg<'static> { } } -/// a wrapper around `MinifyingSugg`, which carries a operator like currying -/// so that the suggested code become more efficient (e.g. `foo + -bar` `foo - bar`). -struct Offset { - value: MinifyingSugg<'static>, - sign: OffsetSign, -} - -#[derive(Clone, Copy)] -enum OffsetSign { - Positive, - Negative, -} - -impl Offset { - fn negative(value: Sugg<'static>) -> Self { - Self { - value: value.into(), - sign: OffsetSign::Negative, - } - } - - fn positive(value: Sugg<'static>) -> Self { - Self { - value: value.into(), - sign: OffsetSign::Positive, - } - } - - fn empty() -> Self { - Self::positive(sugg::ZERO) - } -} - -fn apply_offset(lhs: &MinifyingSugg<'static>, rhs: &Offset) -> MinifyingSugg<'static> { - match rhs.sign { - OffsetSign::Positive => lhs + &rhs.value, - OffsetSign::Negative => lhs - &rhs.value, - } -} - -#[derive(Debug, Clone, Copy)] -enum StartKind<'hir> { - Range, - Counter { initializer: &'hir Expr<'hir> }, -} - -struct IndexExpr<'hir> { - base: &'hir Expr<'hir>, - idx: StartKind<'hir>, - idx_offset: Offset, -} - -struct Start<'hir> { - id: HirId, - kind: StartKind<'hir>, -} - -fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'_>) -> bool { - let is_slice = match ty.kind() { - ty::Ref(_, subty, _) => is_slice_like(cx, subty), - ty::Slice(..) | ty::Array(..) => true, - _ => false, - }; - - is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) -} - -fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { - if_chain! { - if let ExprKind::MethodCall(method, _, args, _) = expr.kind; - if method.ident.name == sym::clone; - if args.len() == 1; - if let Some(arg) = args.get(0); - then { arg } else { expr } - } -} - -fn get_details_from_idx<'tcx>( - cx: &LateContext<'tcx>, - idx: &Expr<'_>, - starts: &[Start<'tcx>], -) -> Option<(StartKind<'tcx>, Offset)> { - fn get_start<'tcx>(e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option> { - let id = path_to_local(e)?; - starts.iter().find(|start| start.id == id).map(|start| start.kind) - } - - fn get_offset<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option> { - match &e.kind { - ExprKind::Lit(l) => match l.node { - ast::LitKind::Int(x, _ty) => Some(Sugg::NonParen(x.to_string().into())), - _ => None, - }, - ExprKind::Path(..) if get_start(e, starts).is_none() => Some(Sugg::hir(cx, e, "???")), - _ => None, - } - } - - match idx.kind { - ExprKind::Binary(op, lhs, rhs) => match op.node { - BinOpKind::Add => { - let offset_opt = get_start(lhs, starts) - .and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, o))) - .or_else(|| get_start(rhs, starts).and_then(|s| get_offset(cx, lhs, starts).map(|o| (s, o)))); - - offset_opt.map(|(s, o)| (s, Offset::positive(o))) - }, - BinOpKind::Sub => { - get_start(lhs, starts).and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, Offset::negative(o)))) - }, - _ => None, - }, - ExprKind::Path(..) => get_start(idx, starts).map(|s| (s, Offset::empty())), - _ => None, - } -} - -fn get_assignment<'tcx>(e: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { - if let ExprKind::Assign(lhs, rhs, _) = e.kind { - Some((lhs, rhs)) - } else { - None - } -} - -/// Get assignments from the given block. -/// The returned iterator yields `None` if no assignment expressions are there, -/// filtering out the increments of the given whitelisted loop counters; -/// because its job is to make sure there's nothing other than assignments and the increments. -fn get_assignments<'a, 'tcx>( - Block { stmts, expr, .. }: &'tcx Block<'tcx>, - loop_counters: &'a [Start<'tcx>], -) -> impl Iterator, &'tcx Expr<'tcx>)>> + 'a { - // As the `filter` and `map` below do different things, I think putting together - // just increases complexity. (cc #3188 and #4193) - stmts - .iter() - .filter_map(move |stmt| match stmt.kind { - StmtKind::Local(..) | StmtKind::Item(..) => None, - StmtKind::Expr(e) | StmtKind::Semi(e) => Some(e), - }) - .chain((*expr).into_iter()) - .filter(move |e| { - if let ExprKind::AssignOp(_, place, _) = e.kind { - path_to_local(place).map_or(false, |id| { - !loop_counters - .iter() - // skip the first item which should be `StartKind::Range` - // this makes it possible to use the slice with `StartKind::Range` in the same iterator loop. - .skip(1) - .any(|counter| counter.id == id) - }) - } else { - true - } - }) - .map(get_assignment) -} - -fn get_loop_counters<'a, 'tcx>( - cx: &'a LateContext<'tcx>, - body: &'tcx Block<'tcx>, - expr: &'tcx Expr<'_>, -) -> Option> + 'a> { - // Look for variables that are incremented once per loop iteration. - let mut increment_visitor = IncrementVisitor::new(cx); - walk_block(&mut increment_visitor, body); - - // For each candidate, check the parent block to see if - // it's initialized to zero at the start of the loop. - get_enclosing_block(&cx, expr.hir_id).and_then(|block| { - increment_visitor - .into_results() - .filter_map(move |var_id| { - let mut initialize_visitor = InitializeVisitor::new(cx, expr, var_id); - walk_block(&mut initialize_visitor, block); - - initialize_visitor.get_result().map(|(_, initializer)| Start { - id: var_id, - kind: StartKind::Counter { initializer }, - }) - }) - .into() - }) -} - -fn build_manual_memcpy_suggestion<'tcx>( - cx: &LateContext<'tcx>, - start: &Expr<'_>, - end: &Expr<'_>, - limits: ast::RangeLimits, - dst: &IndexExpr<'_>, - src: &IndexExpr<'_>, -) -> String { - fn print_offset(offset: MinifyingSugg<'static>) -> MinifyingSugg<'static> { - if offset.as_str() == "0" { - sugg::EMPTY.into() - } else { - offset - } - } - - let print_limit = |end: &Expr<'_>, end_str: &str, base: &Expr<'_>, sugg: MinifyingSugg<'static>| { - if_chain! { - if let ExprKind::MethodCall(method, _, len_args, _) = end.kind; - if method.ident.name == sym!(len); - if len_args.len() == 1; - if let Some(arg) = len_args.get(0); - if path_to_local(arg) == path_to_local(base); - then { - if sugg.as_str() == end_str { - sugg::EMPTY.into() - } else { - sugg - } - } else { - match limits { - ast::RangeLimits::Closed => { - sugg + &sugg::ONE.into() - }, - ast::RangeLimits::HalfOpen => sugg, - } - } - } - }; - - let start_str = Sugg::hir(cx, start, "").into(); - let end_str: MinifyingSugg<'_> = Sugg::hir(cx, end, "").into(); - - let print_offset_and_limit = |idx_expr: &IndexExpr<'_>| match idx_expr.idx { - StartKind::Range => ( - print_offset(apply_offset(&start_str, &idx_expr.idx_offset)).into_sugg(), - print_limit( - end, - end_str.as_str(), - idx_expr.base, - apply_offset(&end_str, &idx_expr.idx_offset), - ) - .into_sugg(), - ), - StartKind::Counter { initializer } => { - let counter_start = Sugg::hir(cx, initializer, "").into(); - ( - print_offset(apply_offset(&counter_start, &idx_expr.idx_offset)).into_sugg(), - print_limit( - end, - end_str.as_str(), - idx_expr.base, - apply_offset(&end_str, &idx_expr.idx_offset) + &counter_start - &start_str, - ) - .into_sugg(), - ) - }, - }; - - let (dst_offset, dst_limit) = print_offset_and_limit(&dst); - let (src_offset, src_limit) = print_offset_and_limit(&src); - - let dst_base_str = snippet(cx, dst.base.span, "???"); - let src_base_str = snippet(cx, src.base.span, "???"); - - let dst = if dst_offset == sugg::EMPTY && dst_limit == sugg::EMPTY { - dst_base_str - } else { - format!( - "{}[{}..{}]", - dst_base_str, - dst_offset.maybe_par(), - dst_limit.maybe_par() - ) - .into() - }; - - format!( - "{}.clone_from_slice(&{}[{}..{}]);", - dst, - src_base_str, - src_offset.maybe_par(), - src_limit.maybe_par() - ) -} - -/// Checks for for loops that sequentially copy items from one slice-like -/// object to another. -fn detect_manual_memcpy<'tcx>( - cx: &LateContext<'tcx>, - pat: &'tcx Pat<'_>, - arg: &'tcx Expr<'_>, - body: &'tcx Expr<'_>, - expr: &'tcx Expr<'_>, -) -> bool { - if let Some(higher::Range { - start: Some(start), - end: Some(end), - limits, - }) = higher::range(arg) - { - // the var must be a single name - if let PatKind::Binding(_, canonical_id, _, _) = pat.kind { - let mut starts = vec![Start { - id: canonical_id, - kind: StartKind::Range, - }]; - - // This is one of few ways to return different iterators - // derived from: https://stackoverflow.com/questions/29760668/conditionally-iterate-over-one-of-several-possible-iterators/52064434#52064434 - let mut iter_a = None; - let mut iter_b = None; - - if let ExprKind::Block(block, _) = body.kind { - if let Some(loop_counters) = get_loop_counters(cx, block, expr) { - starts.extend(loop_counters); - } - iter_a = Some(get_assignments(block, &starts)); - } else { - iter_b = Some(get_assignment(body)); - } - - let assignments = iter_a.into_iter().flatten().chain(iter_b.into_iter()); - - let big_sugg = assignments - // The only statements in the for loops can be indexed assignments from - // indexed retrievals (except increments of loop counters). - .map(|o| { - o.and_then(|(lhs, rhs)| { - let rhs = fetch_cloned_expr(rhs); - if_chain! { - if let ExprKind::Index(base_left, idx_left) = lhs.kind; - if let ExprKind::Index(base_right, idx_right) = rhs.kind; - if is_slice_like(cx, cx.typeck_results().expr_ty(base_left)) - && is_slice_like(cx, cx.typeck_results().expr_ty(base_right)); - if let Some((start_left, offset_left)) = get_details_from_idx(cx, &idx_left, &starts); - if let Some((start_right, offset_right)) = get_details_from_idx(cx, &idx_right, &starts); - - // Source and destination must be different - if path_to_local(base_left) != path_to_local(base_right); - then { - Some((IndexExpr { base: base_left, idx: start_left, idx_offset: offset_left }, - IndexExpr { base: base_right, idx: start_right, idx_offset: offset_right })) - } else { - None - } - } - }) - }) - .map(|o| o.map(|(dst, src)| build_manual_memcpy_suggestion(cx, start, end, limits, &dst, &src))) - .collect::>>() - .filter(|v| !v.is_empty()) - .map(|v| v.join("\n ")); - - if let Some(big_sugg) = big_sugg { - span_lint_and_sugg( - cx, - MANUAL_MEMCPY, - get_span_of_entire_for_loop(expr), - "it looks like you're manually copying between slices", - "try replacing the loop by", - big_sugg, - Applicability::Unspecified, - ); - return true; - } - } - } - false -} - fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { let def_id = match path_to_local(expr) { Some(id) => id, @@ -1398,233 +1029,6 @@ fn is_simple_break_expr(expr: &Expr<'_>) -> bool { } } -#[derive(Debug, PartialEq)] -enum IncrementVisitorVarState { - Initial, // Not examined yet - IncrOnce, // Incremented exactly once, may be a loop counter - DontWarn, -} - -/// Scan a for loop for variables that are incremented exactly once and not used after that. -struct IncrementVisitor<'a, 'tcx> { - cx: &'a LateContext<'tcx>, // context reference - states: FxHashMap, // incremented variables - depth: u32, // depth of conditional expressions - done: bool, -} - -impl<'a, 'tcx> IncrementVisitor<'a, 'tcx> { - fn new(cx: &'a LateContext<'tcx>) -> Self { - Self { - cx, - states: FxHashMap::default(), - depth: 0, - done: false, - } - } - - fn into_results(self) -> impl Iterator { - self.states.into_iter().filter_map(|(id, state)| { - if state == IncrementVisitorVarState::IncrOnce { - Some(id) - } else { - None - } - }) - } -} - -impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if self.done { - return; - } - - // If node is a variable - if let Some(def_id) = path_to_local(expr) { - if let Some(parent) = get_parent_expr(self.cx, expr) { - let state = self.states.entry(def_id).or_insert(IncrementVisitorVarState::Initial); - if *state == IncrementVisitorVarState::IncrOnce { - *state = IncrementVisitorVarState::DontWarn; - return; - } - - match parent.kind { - ExprKind::AssignOp(op, ref lhs, ref rhs) => { - if lhs.hir_id == expr.hir_id { - *state = if op.node == BinOpKind::Add - && is_integer_const(self.cx, rhs, 1) - && *state == IncrementVisitorVarState::Initial - && self.depth == 0 - { - IncrementVisitorVarState::IncrOnce - } else { - // Assigned some other value or assigned multiple times - IncrementVisitorVarState::DontWarn - }; - } - }, - ExprKind::Assign(ref lhs, _, _) if lhs.hir_id == expr.hir_id => { - *state = IncrementVisitorVarState::DontWarn - }, - ExprKind::AddrOf(BorrowKind::Ref, mutability, _) if mutability == Mutability::Mut => { - *state = IncrementVisitorVarState::DontWarn - }, - _ => (), - } - } - - walk_expr(self, expr); - } else if is_loop(expr) || is_conditional(expr) { - self.depth += 1; - walk_expr(self, expr); - self.depth -= 1; - } else if let ExprKind::Continue(_) = expr.kind { - self.done = true; - } else { - walk_expr(self, expr); - } - } - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - -enum InitializeVisitorState<'hir> { - Initial, // Not examined yet - Declared(Symbol), // Declared but not (yet) initialized - Initialized { - name: Symbol, - initializer: &'hir Expr<'hir>, - }, - DontWarn, -} - -/// Checks whether a variable is initialized at the start of a loop and not modified -/// and used after the loop. -struct InitializeVisitor<'a, 'tcx> { - cx: &'a LateContext<'tcx>, // context reference - end_expr: &'tcx Expr<'tcx>, // the for loop. Stop scanning here. - var_id: HirId, - state: InitializeVisitorState<'tcx>, - depth: u32, // depth of conditional expressions - past_loop: bool, -} - -impl<'a, 'tcx> InitializeVisitor<'a, 'tcx> { - fn new(cx: &'a LateContext<'tcx>, end_expr: &'tcx Expr<'tcx>, var_id: HirId) -> Self { - Self { - cx, - end_expr, - var_id, - state: InitializeVisitorState::Initial, - depth: 0, - past_loop: false, - } - } - - fn get_result(&self) -> Option<(Symbol, &'tcx Expr<'tcx>)> { - if let InitializeVisitorState::Initialized { name, initializer } = self.state { - Some((name, initializer)) - } else { - None - } - } -} - -impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) { - // Look for declarations of the variable - if_chain! { - if let StmtKind::Local(ref local) = stmt.kind; - if local.pat.hir_id == self.var_id; - if let PatKind::Binding(.., ident, _) = local.pat.kind; - then { - self.state = local.init.map_or(InitializeVisitorState::Declared(ident.name), |init| { - InitializeVisitorState::Initialized { - initializer: init, - name: ident.name, - } - }) - } - } - walk_stmt(self, stmt); - } - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if matches!(self.state, InitializeVisitorState::DontWarn) { - return; - } - if expr.hir_id == self.end_expr.hir_id { - self.past_loop = true; - return; - } - // No need to visit expressions before the variable is - // declared - if matches!(self.state, InitializeVisitorState::Initial) { - return; - } - - // If node is the desired variable, see how it's used - if path_to_local_id(expr, self.var_id) { - if self.past_loop { - self.state = InitializeVisitorState::DontWarn; - return; - } - - if let Some(parent) = get_parent_expr(self.cx, expr) { - match parent.kind { - ExprKind::AssignOp(_, ref lhs, _) if lhs.hir_id == expr.hir_id => { - self.state = InitializeVisitorState::DontWarn; - }, - ExprKind::Assign(ref lhs, ref rhs, _) if lhs.hir_id == expr.hir_id => { - self.state = if_chain! { - if self.depth == 0; - if let InitializeVisitorState::Declared(name) - | InitializeVisitorState::Initialized { name, ..} = self.state; - then { - InitializeVisitorState::Initialized { initializer: rhs, name } - } else { - InitializeVisitorState::DontWarn - } - } - }, - ExprKind::AddrOf(BorrowKind::Ref, mutability, _) if mutability == Mutability::Mut => { - self.state = InitializeVisitorState::DontWarn - }, - _ => (), - } - } - - walk_expr(self, expr); - } else if !self.past_loop && is_loop(expr) { - self.state = InitializeVisitorState::DontWarn; - } else if is_conditional(expr) { - self.depth += 1; - walk_expr(self, expr); - self.depth -= 1; - } else { - walk_expr(self, expr); - } - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::OnlyBodies(self.cx.tcx.hir()) - } -} - -fn is_loop(expr: &Expr<'_>) -> bool { - matches!(expr.kind, ExprKind::Loop(..)) -} - -fn is_conditional(expr: &Expr<'_>) -> bool { - matches!(expr.kind, ExprKind::If(..) | ExprKind::Match(..)) -} - fn is_nested(cx: &LateContext<'_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { if_chain! { if let Some(loop_block) = get_enclosing_block(cx, match_expr.hir_id); @@ -1659,10 +1063,10 @@ fn is_loop_nested(cx: &LateContext<'_>, loop_expr: &Expr<'_>, iter_expr: &Expr<' let mut block_visitor = LoopNestVisitor { hir_id: id, iterator: iter_id, - nesting: Unknown, + nesting: Nesting::Unknown, }; walk_block(&mut block_visitor, block); - if block_visitor.nesting == RuledOut { + if block_visitor.nesting == Nesting::RuledOut { return false; } }, @@ -1674,65 +1078,3 @@ fn is_loop_nested(cx: &LateContext<'_>, loop_expr: &Expr<'_>, iter_expr: &Expr<' id = parent; } } - -#[derive(PartialEq, Eq)] -enum Nesting { - Unknown, // no nesting detected yet - RuledOut, // the iterator is initialized or assigned within scope - LookFurther, // no nesting detected, no further walk required -} - -use self::Nesting::{LookFurther, RuledOut, Unknown}; - -struct LoopNestVisitor { - hir_id: HirId, - iterator: HirId, - nesting: Nesting, -} - -impl<'tcx> Visitor<'tcx> for LoopNestVisitor { - type Map = Map<'tcx>; - - fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) { - if stmt.hir_id == self.hir_id { - self.nesting = LookFurther; - } else if self.nesting == Unknown { - walk_stmt(self, stmt); - } - } - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if self.nesting != Unknown { - return; - } - if expr.hir_id == self.hir_id { - self.nesting = LookFurther; - return; - } - match expr.kind { - ExprKind::Assign(ref path, _, _) | ExprKind::AssignOp(_, ref path, _) => { - if path_to_local_id(path, self.iterator) { - self.nesting = RuledOut; - } - }, - _ => walk_expr(self, expr), - } - } - - fn visit_pat(&mut self, pat: &'tcx Pat<'_>) { - if self.nesting != Unknown { - return; - } - if let PatKind::Binding(_, id, ..) = pat.kind { - if id == self.iterator { - self.nesting = RuledOut; - return; - } - } - walk_pat(self, pat) - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs index b9c934d5e549d..9e38e17719aad 100644 --- a/clippy_lints/src/loops/utils.rs +++ b/clippy_lints/src/loops/utils.rs @@ -1,8 +1,306 @@ -use crate::utils::{get_trait_def_id, has_iter_method, implements_trait, paths, sugg}; +use crate::utils::{ + get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, is_integer_const, path_to_local, + path_to_local_id, paths, sugg, +}; +use if_chain::if_chain; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; -use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; +use rustc_hir::intravisit::{walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; +use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Stmt, StmtKind}; use rustc_lint::LateContext; +use rustc_middle::hir::map::Map; use rustc_span::source_map::Span; +use rustc_span::symbol::Symbol; +use std::iter::Iterator; + +#[derive(Debug, PartialEq)] +enum IncrementVisitorVarState { + Initial, // Not examined yet + IncrOnce, // Incremented exactly once, may be a loop counter + DontWarn, +} + +/// Scan a for loop for variables that are incremented exactly once and not used after that. +pub(super) struct IncrementVisitor<'a, 'tcx> { + cx: &'a LateContext<'tcx>, // context reference + states: FxHashMap, // incremented variables + depth: u32, // depth of conditional expressions + done: bool, +} + +impl<'a, 'tcx> IncrementVisitor<'a, 'tcx> { + pub(super) fn new(cx: &'a LateContext<'tcx>) -> Self { + Self { + cx, + states: FxHashMap::default(), + depth: 0, + done: false, + } + } + + pub(super) fn into_results(self) -> impl Iterator { + self.states.into_iter().filter_map(|(id, state)| { + if state == IncrementVisitorVarState::IncrOnce { + Some(id) + } else { + None + } + }) + } +} + +impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if self.done { + return; + } + + // If node is a variable + if let Some(def_id) = path_to_local(expr) { + if let Some(parent) = get_parent_expr(self.cx, expr) { + let state = self.states.entry(def_id).or_insert(IncrementVisitorVarState::Initial); + if *state == IncrementVisitorVarState::IncrOnce { + *state = IncrementVisitorVarState::DontWarn; + return; + } + + match parent.kind { + ExprKind::AssignOp(op, ref lhs, ref rhs) => { + if lhs.hir_id == expr.hir_id { + *state = if op.node == BinOpKind::Add + && is_integer_const(self.cx, rhs, 1) + && *state == IncrementVisitorVarState::Initial + && self.depth == 0 + { + IncrementVisitorVarState::IncrOnce + } else { + // Assigned some other value or assigned multiple times + IncrementVisitorVarState::DontWarn + }; + } + }, + ExprKind::Assign(ref lhs, _, _) if lhs.hir_id == expr.hir_id => { + *state = IncrementVisitorVarState::DontWarn + }, + ExprKind::AddrOf(BorrowKind::Ref, mutability, _) if mutability == Mutability::Mut => { + *state = IncrementVisitorVarState::DontWarn + }, + _ => (), + } + } + + walk_expr(self, expr); + } else if is_loop(expr) || is_conditional(expr) { + self.depth += 1; + walk_expr(self, expr); + self.depth -= 1; + } else if let ExprKind::Continue(_) = expr.kind { + self.done = true; + } else { + walk_expr(self, expr); + } + } + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} + +enum InitializeVisitorState<'hir> { + Initial, // Not examined yet + Declared(Symbol), // Declared but not (yet) initialized + Initialized { + name: Symbol, + initializer: &'hir Expr<'hir>, + }, + DontWarn, +} + +/// Checks whether a variable is initialized at the start of a loop and not modified +/// and used after the loop. +pub(super) struct InitializeVisitor<'a, 'tcx> { + cx: &'a LateContext<'tcx>, // context reference + end_expr: &'tcx Expr<'tcx>, // the for loop. Stop scanning here. + var_id: HirId, + state: InitializeVisitorState<'tcx>, + depth: u32, // depth of conditional expressions + past_loop: bool, +} + +impl<'a, 'tcx> InitializeVisitor<'a, 'tcx> { + pub(super) fn new(cx: &'a LateContext<'tcx>, end_expr: &'tcx Expr<'tcx>, var_id: HirId) -> Self { + Self { + cx, + end_expr, + var_id, + state: InitializeVisitorState::Initial, + depth: 0, + past_loop: false, + } + } + + pub(super) fn get_result(&self) -> Option<(Symbol, &'tcx Expr<'tcx>)> { + if let InitializeVisitorState::Initialized { name, initializer } = self.state { + Some((name, initializer)) + } else { + None + } + } +} + +impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { + type Map = Map<'tcx>; + + fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) { + // Look for declarations of the variable + if_chain! { + if let StmtKind::Local(ref local) = stmt.kind; + if local.pat.hir_id == self.var_id; + if let PatKind::Binding(.., ident, _) = local.pat.kind; + then { + self.state = local.init.map_or(InitializeVisitorState::Declared(ident.name), |init| { + InitializeVisitorState::Initialized { + initializer: init, + name: ident.name, + } + }) + } + } + walk_stmt(self, stmt); + } + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if matches!(self.state, InitializeVisitorState::DontWarn) { + return; + } + if expr.hir_id == self.end_expr.hir_id { + self.past_loop = true; + return; + } + // No need to visit expressions before the variable is + // declared + if matches!(self.state, InitializeVisitorState::Initial) { + return; + } + + // If node is the desired variable, see how it's used + if path_to_local_id(expr, self.var_id) { + if self.past_loop { + self.state = InitializeVisitorState::DontWarn; + return; + } + + if let Some(parent) = get_parent_expr(self.cx, expr) { + match parent.kind { + ExprKind::AssignOp(_, ref lhs, _) if lhs.hir_id == expr.hir_id => { + self.state = InitializeVisitorState::DontWarn; + }, + ExprKind::Assign(ref lhs, ref rhs, _) if lhs.hir_id == expr.hir_id => { + self.state = if_chain! { + if self.depth == 0; + if let InitializeVisitorState::Declared(name) + | InitializeVisitorState::Initialized { name, ..} = self.state; + then { + InitializeVisitorState::Initialized { initializer: rhs, name } + } else { + InitializeVisitorState::DontWarn + } + } + }, + ExprKind::AddrOf(BorrowKind::Ref, mutability, _) if mutability == Mutability::Mut => { + self.state = InitializeVisitorState::DontWarn + }, + _ => (), + } + } + + walk_expr(self, expr); + } else if !self.past_loop && is_loop(expr) { + self.state = InitializeVisitorState::DontWarn; + } else if is_conditional(expr) { + self.depth += 1; + walk_expr(self, expr); + self.depth -= 1; + } else { + walk_expr(self, expr); + } + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::OnlyBodies(self.cx.tcx.hir()) + } +} + +fn is_loop(expr: &Expr<'_>) -> bool { + matches!(expr.kind, ExprKind::Loop(..)) +} + +fn is_conditional(expr: &Expr<'_>) -> bool { + matches!(expr.kind, ExprKind::If(..) | ExprKind::Match(..)) +} + +#[derive(PartialEq, Eq)] +pub(super) enum Nesting { + Unknown, // no nesting detected yet + RuledOut, // the iterator is initialized or assigned within scope + LookFurther, // no nesting detected, no further walk required +} + +use self::Nesting::{LookFurther, RuledOut, Unknown}; + +pub(super) struct LoopNestVisitor { + pub(super) hir_id: HirId, + pub(super) iterator: HirId, + pub(super) nesting: Nesting, +} + +impl<'tcx> Visitor<'tcx> for LoopNestVisitor { + type Map = Map<'tcx>; + + fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) { + if stmt.hir_id == self.hir_id { + self.nesting = LookFurther; + } else if self.nesting == Unknown { + walk_stmt(self, stmt); + } + } + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if self.nesting != Unknown { + return; + } + if expr.hir_id == self.hir_id { + self.nesting = LookFurther; + return; + } + match expr.kind { + ExprKind::Assign(ref path, _, _) | ExprKind::AssignOp(_, ref path, _) => { + if path_to_local_id(path, self.iterator) { + self.nesting = RuledOut; + } + }, + _ => walk_expr(self, expr), + } + } + + fn visit_pat(&mut self, pat: &'tcx Pat<'_>) { + if self.nesting != Unknown { + return; + } + if let PatKind::Binding(_, id, ..) = pat.kind { + if id == self.iterator { + self.nesting = RuledOut; + return; + } + } + walk_pat(self, pat) + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} // this function assumes the given expression is a `for` loop. pub(super) fn get_span_of_entire_for_loop(expr: &Expr<'_>) -> Span { From 455d0476b11c1a1a2ae8005e781c6ea9b2f4d2ac Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 21 Feb 2021 15:58:05 +0100 Subject: [PATCH 066/226] Refactor never loop to its own module --- clippy_lints/src/loops/mod.rs | 173 +-------------------------- clippy_lints/src/loops/never_loop.rs | 172 ++++++++++++++++++++++++++ 2 files changed, 176 insertions(+), 169 deletions(-) create mode 100644 clippy_lints/src/loops/never_loop.rs diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index c6055e34eb2ef..9a4cbf27c497d 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -8,6 +8,7 @@ mod infinite_loop; mod manual_flatten; mod manual_memcpy; mod needless_collect; +mod never_loop; mod same_item_push; mod utils; @@ -16,21 +17,18 @@ use crate::utils::usage::mutated_variables; use crate::utils::{ get_enclosing_block, get_trait_def_id, higher, implements_trait, is_in_panic_handler, is_no_std_crate, is_refutable, last_path_segment, match_trait_method, path_to_local, path_to_local_id, paths, - snippet_with_applicability, span_lint, span_lint_and_help, span_lint_and_sugg, sugg, + snippet_with_applicability, span_lint_and_help, span_lint_and_sugg, sugg, }; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_block, walk_expr, NestedVisitorMap, Visitor}; -use rustc_hir::{ - Block, Expr, ExprKind, HirId, InlineAsmOperand, LoopSource, MatchSource, Node, Pat, PatKind, Stmt, StmtKind, -}; +use rustc_hir::{Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, PatKind, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use rustc_span::symbol::sym; -use std::iter::{once, Iterator}; use utils::{ get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor, LoopNestVisitor, Nesting, }; @@ -567,12 +565,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { } // check for never_loop - if let ExprKind::Loop(ref block, _, _, _) = expr.kind { - match never_loop_block(block, expr.hir_id) { - NeverLoopResult::AlwaysBreak => span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops"), - NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Otherwise => (), - } - } + never_loop::check_never_loop(cx, expr); // check for `loop { if let {} else break }` that could be `while let` // (also matches an explicit "match" instead of "if let") @@ -689,164 +682,6 @@ impl<'tcx> LateLintPass<'tcx> for Loops { } } -enum NeverLoopResult { - // A break/return always get triggered but not necessarily for the main loop. - AlwaysBreak, - // A continue may occur for the main loop. - MayContinueMainLoop, - Otherwise, -} - -#[must_use] -fn absorb_break(arg: &NeverLoopResult) -> NeverLoopResult { - match *arg { - NeverLoopResult::AlwaysBreak | NeverLoopResult::Otherwise => NeverLoopResult::Otherwise, - NeverLoopResult::MayContinueMainLoop => NeverLoopResult::MayContinueMainLoop, - } -} - -// Combine two results for parts that are called in order. -#[must_use] -fn combine_seq(first: NeverLoopResult, second: NeverLoopResult) -> NeverLoopResult { - match first { - NeverLoopResult::AlwaysBreak | NeverLoopResult::MayContinueMainLoop => first, - NeverLoopResult::Otherwise => second, - } -} - -// Combine two results where both parts are called but not necessarily in order. -#[must_use] -fn combine_both(left: NeverLoopResult, right: NeverLoopResult) -> NeverLoopResult { - match (left, right) { - (NeverLoopResult::MayContinueMainLoop, _) | (_, NeverLoopResult::MayContinueMainLoop) => { - NeverLoopResult::MayContinueMainLoop - }, - (NeverLoopResult::AlwaysBreak, _) | (_, NeverLoopResult::AlwaysBreak) => NeverLoopResult::AlwaysBreak, - (NeverLoopResult::Otherwise, NeverLoopResult::Otherwise) => NeverLoopResult::Otherwise, - } -} - -// Combine two results where only one of the part may have been executed. -#[must_use] -fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult { - match (b1, b2) { - (NeverLoopResult::AlwaysBreak, NeverLoopResult::AlwaysBreak) => NeverLoopResult::AlwaysBreak, - (NeverLoopResult::MayContinueMainLoop, _) | (_, NeverLoopResult::MayContinueMainLoop) => { - NeverLoopResult::MayContinueMainLoop - }, - (NeverLoopResult::Otherwise, _) | (_, NeverLoopResult::Otherwise) => NeverLoopResult::Otherwise, - } -} - -fn never_loop_block(block: &Block<'_>, main_loop_id: HirId) -> NeverLoopResult { - let stmts = block.stmts.iter().map(stmt_to_expr); - let expr = once(block.expr.as_deref()); - let mut iter = stmts.chain(expr).flatten(); - never_loop_expr_seq(&mut iter, main_loop_id) -} - -fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<&'tcx Expr<'tcx>> { - match stmt.kind { - StmtKind::Semi(ref e, ..) | StmtKind::Expr(ref e, ..) => Some(e), - StmtKind::Local(ref local) => local.init.as_deref(), - _ => None, - } -} - -fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { - match expr.kind { - ExprKind::Box(ref e) - | ExprKind::Unary(_, ref e) - | ExprKind::Cast(ref e, _) - | ExprKind::Type(ref e, _) - | ExprKind::Field(ref e, _) - | ExprKind::AddrOf(_, _, ref e) - | ExprKind::Struct(_, _, Some(ref e)) - | ExprKind::Repeat(ref e, _) - | ExprKind::DropTemps(ref e) => never_loop_expr(e, main_loop_id), - ExprKind::Array(ref es) | ExprKind::MethodCall(_, _, ref es, _) | ExprKind::Tup(ref es) => { - never_loop_expr_all(&mut es.iter(), main_loop_id) - }, - ExprKind::Call(ref e, ref es) => never_loop_expr_all(&mut once(&**e).chain(es.iter()), main_loop_id), - ExprKind::Binary(_, ref e1, ref e2) - | ExprKind::Assign(ref e1, ref e2, _) - | ExprKind::AssignOp(_, ref e1, ref e2) - | ExprKind::Index(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id), - ExprKind::Loop(ref b, _, _, _) => { - // Break can come from the inner loop so remove them. - absorb_break(&never_loop_block(b, main_loop_id)) - }, - ExprKind::If(ref e, ref e2, ref e3) => { - let e1 = never_loop_expr(e, main_loop_id); - let e2 = never_loop_expr(e2, main_loop_id); - let e3 = e3 - .as_ref() - .map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id)); - combine_seq(e1, combine_branches(e2, e3)) - }, - ExprKind::Match(ref e, ref arms, _) => { - let e = never_loop_expr(e, main_loop_id); - if arms.is_empty() { - e - } else { - let arms = never_loop_expr_branch(&mut arms.iter().map(|a| &*a.body), main_loop_id); - combine_seq(e, arms) - } - }, - ExprKind::Block(ref b, _) => never_loop_block(b, main_loop_id), - ExprKind::Continue(d) => { - let id = d - .target_id - .expect("target ID can only be missing in the presence of compilation errors"); - if id == main_loop_id { - NeverLoopResult::MayContinueMainLoop - } else { - NeverLoopResult::AlwaysBreak - } - }, - ExprKind::Break(_, ref e) | ExprKind::Ret(ref e) => e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| { - combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak) - }), - ExprKind::InlineAsm(ref asm) => asm - .operands - .iter() - .map(|(o, _)| match o { - InlineAsmOperand::In { expr, .. } - | InlineAsmOperand::InOut { expr, .. } - | InlineAsmOperand::Const { expr } - | InlineAsmOperand::Sym { expr } => never_loop_expr(expr, main_loop_id), - InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter(), main_loop_id), - InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { - never_loop_expr_all(&mut once(in_expr).chain(out_expr.iter()), main_loop_id) - }, - }) - .fold(NeverLoopResult::Otherwise, combine_both), - ExprKind::Struct(_, _, None) - | ExprKind::Yield(_, _) - | ExprKind::Closure(_, _, _, _, _) - | ExprKind::LlvmInlineAsm(_) - | ExprKind::Path(_) - | ExprKind::ConstBlock(_) - | ExprKind::Lit(_) - | ExprKind::Err => NeverLoopResult::Otherwise, - } -} - -fn never_loop_expr_seq<'a, T: Iterator>>(es: &mut T, main_loop_id: HirId) -> NeverLoopResult { - es.map(|e| never_loop_expr(e, main_loop_id)) - .fold(NeverLoopResult::Otherwise, combine_seq) -} - -fn never_loop_expr_all<'a, T: Iterator>>(es: &mut T, main_loop_id: HirId) -> NeverLoopResult { - es.map(|e| never_loop_expr(e, main_loop_id)) - .fold(NeverLoopResult::Otherwise, combine_both) -} - -fn never_loop_expr_branch<'a, T: Iterator>>(e: &mut T, main_loop_id: HirId) -> NeverLoopResult { - e.map(|e| never_loop_expr(e, main_loop_id)) - .fold(NeverLoopResult::AlwaysBreak, combine_branches) -} - fn check_for_loop<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs new file mode 100644 index 0000000000000..d51ff81103fd4 --- /dev/null +++ b/clippy_lints/src/loops/never_loop.rs @@ -0,0 +1,172 @@ +use super::NEVER_LOOP; +use crate::utils::span_lint; +use rustc_hir::{Block, Expr, ExprKind, HirId, InlineAsmOperand, Stmt, StmtKind}; +use rustc_lint::LateContext; +use std::iter::{once, Iterator}; + +pub(super) fn check_never_loop(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Loop(ref block, _, _, _) = expr.kind { + match never_loop_block(block, expr.hir_id) { + NeverLoopResult::AlwaysBreak => span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops"), + NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Otherwise => (), + } + } +} + +enum NeverLoopResult { + // A break/return always get triggered but not necessarily for the main loop. + AlwaysBreak, + // A continue may occur for the main loop. + MayContinueMainLoop, + Otherwise, +} + +#[must_use] +fn absorb_break(arg: &NeverLoopResult) -> NeverLoopResult { + match *arg { + NeverLoopResult::AlwaysBreak | NeverLoopResult::Otherwise => NeverLoopResult::Otherwise, + NeverLoopResult::MayContinueMainLoop => NeverLoopResult::MayContinueMainLoop, + } +} + +// Combine two results for parts that are called in order. +#[must_use] +fn combine_seq(first: NeverLoopResult, second: NeverLoopResult) -> NeverLoopResult { + match first { + NeverLoopResult::AlwaysBreak | NeverLoopResult::MayContinueMainLoop => first, + NeverLoopResult::Otherwise => second, + } +} + +// Combine two results where both parts are called but not necessarily in order. +#[must_use] +fn combine_both(left: NeverLoopResult, right: NeverLoopResult) -> NeverLoopResult { + match (left, right) { + (NeverLoopResult::MayContinueMainLoop, _) | (_, NeverLoopResult::MayContinueMainLoop) => { + NeverLoopResult::MayContinueMainLoop + }, + (NeverLoopResult::AlwaysBreak, _) | (_, NeverLoopResult::AlwaysBreak) => NeverLoopResult::AlwaysBreak, + (NeverLoopResult::Otherwise, NeverLoopResult::Otherwise) => NeverLoopResult::Otherwise, + } +} + +// Combine two results where only one of the part may have been executed. +#[must_use] +fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult { + match (b1, b2) { + (NeverLoopResult::AlwaysBreak, NeverLoopResult::AlwaysBreak) => NeverLoopResult::AlwaysBreak, + (NeverLoopResult::MayContinueMainLoop, _) | (_, NeverLoopResult::MayContinueMainLoop) => { + NeverLoopResult::MayContinueMainLoop + }, + (NeverLoopResult::Otherwise, _) | (_, NeverLoopResult::Otherwise) => NeverLoopResult::Otherwise, + } +} + +fn never_loop_block(block: &Block<'_>, main_loop_id: HirId) -> NeverLoopResult { + let stmts = block.stmts.iter().map(stmt_to_expr); + let expr = once(block.expr.as_deref()); + let mut iter = stmts.chain(expr).flatten(); + never_loop_expr_seq(&mut iter, main_loop_id) +} + +fn never_loop_expr_seq<'a, T: Iterator>>(es: &mut T, main_loop_id: HirId) -> NeverLoopResult { + es.map(|e| never_loop_expr(e, main_loop_id)) + .fold(NeverLoopResult::Otherwise, combine_seq) +} + +fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<&'tcx Expr<'tcx>> { + match stmt.kind { + StmtKind::Semi(ref e, ..) | StmtKind::Expr(ref e, ..) => Some(e), + StmtKind::Local(ref local) => local.init.as_deref(), + _ => None, + } +} + +fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { + match expr.kind { + ExprKind::Box(ref e) + | ExprKind::Unary(_, ref e) + | ExprKind::Cast(ref e, _) + | ExprKind::Type(ref e, _) + | ExprKind::Field(ref e, _) + | ExprKind::AddrOf(_, _, ref e) + | ExprKind::Struct(_, _, Some(ref e)) + | ExprKind::Repeat(ref e, _) + | ExprKind::DropTemps(ref e) => never_loop_expr(e, main_loop_id), + ExprKind::Array(ref es) | ExprKind::MethodCall(_, _, ref es, _) | ExprKind::Tup(ref es) => { + never_loop_expr_all(&mut es.iter(), main_loop_id) + }, + ExprKind::Call(ref e, ref es) => never_loop_expr_all(&mut once(&**e).chain(es.iter()), main_loop_id), + ExprKind::Binary(_, ref e1, ref e2) + | ExprKind::Assign(ref e1, ref e2, _) + | ExprKind::AssignOp(_, ref e1, ref e2) + | ExprKind::Index(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id), + ExprKind::Loop(ref b, _, _, _) => { + // Break can come from the inner loop so remove them. + absorb_break(&never_loop_block(b, main_loop_id)) + }, + ExprKind::If(ref e, ref e2, ref e3) => { + let e1 = never_loop_expr(e, main_loop_id); + let e2 = never_loop_expr(e2, main_loop_id); + let e3 = e3 + .as_ref() + .map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id)); + combine_seq(e1, combine_branches(e2, e3)) + }, + ExprKind::Match(ref e, ref arms, _) => { + let e = never_loop_expr(e, main_loop_id); + if arms.is_empty() { + e + } else { + let arms = never_loop_expr_branch(&mut arms.iter().map(|a| &*a.body), main_loop_id); + combine_seq(e, arms) + } + }, + ExprKind::Block(ref b, _) => never_loop_block(b, main_loop_id), + ExprKind::Continue(d) => { + let id = d + .target_id + .expect("target ID can only be missing in the presence of compilation errors"); + if id == main_loop_id { + NeverLoopResult::MayContinueMainLoop + } else { + NeverLoopResult::AlwaysBreak + } + }, + ExprKind::Break(_, ref e) | ExprKind::Ret(ref e) => e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| { + combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak) + }), + ExprKind::InlineAsm(ref asm) => asm + .operands + .iter() + .map(|(o, _)| match o { + InlineAsmOperand::In { expr, .. } + | InlineAsmOperand::InOut { expr, .. } + | InlineAsmOperand::Const { expr } + | InlineAsmOperand::Sym { expr } => never_loop_expr(expr, main_loop_id), + InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter(), main_loop_id), + InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { + never_loop_expr_all(&mut once(in_expr).chain(out_expr.iter()), main_loop_id) + }, + }) + .fold(NeverLoopResult::Otherwise, combine_both), + ExprKind::Struct(_, _, None) + | ExprKind::Yield(_, _) + | ExprKind::Closure(_, _, _, _, _) + | ExprKind::LlvmInlineAsm(_) + | ExprKind::Path(_) + | ExprKind::ConstBlock(_) + | ExprKind::Lit(_) + | ExprKind::Err => NeverLoopResult::Otherwise, + } +} + +fn never_loop_expr_all<'a, T: Iterator>>(es: &mut T, main_loop_id: HirId) -> NeverLoopResult { + es.map(|e| never_loop_expr(e, main_loop_id)) + .fold(NeverLoopResult::Otherwise, combine_both) +} + +fn never_loop_expr_branch<'a, T: Iterator>>(e: &mut T, main_loop_id: HirId) -> NeverLoopResult { + e.map(|e| never_loop_expr(e, main_loop_id)) + .fold(NeverLoopResult::AlwaysBreak, combine_branches) +} From d0b657c0b7335ccb4a594af100ab49d8bd660e97 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 21 Feb 2021 16:37:09 +0100 Subject: [PATCH 067/226] Refactor while let on iterator lint to its module; rename for loop explicit counter to explicit counter loop --- ...it_counter.rs => explicit_counter_loop.rs} | 0 clippy_lints/src/loops/mod.rs | 174 +----------------- .../src/loops/while_let_on_iterator.rs | 171 +++++++++++++++++ 3 files changed, 179 insertions(+), 166 deletions(-) rename clippy_lints/src/loops/{for_loop_explicit_counter.rs => explicit_counter_loop.rs} (100%) create mode 100644 clippy_lints/src/loops/while_let_on_iterator.rs diff --git a/clippy_lints/src/loops/for_loop_explicit_counter.rs b/clippy_lints/src/loops/explicit_counter_loop.rs similarity index 100% rename from clippy_lints/src/loops/for_loop_explicit_counter.rs rename to clippy_lints/src/loops/explicit_counter_loop.rs diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 9a4cbf27c497d..cadf92412562b 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,5 +1,5 @@ +mod explicit_counter_loop; mod for_loop_arg; -mod for_loop_explicit_counter; mod for_loop_over_map_kv; mod for_loop_range; mod for_mut_range_bound; @@ -11,27 +11,20 @@ mod needless_collect; mod never_loop; mod same_item_push; mod utils; +mod while_let_on_iterator; use crate::utils::sugg::Sugg; -use crate::utils::usage::mutated_variables; use crate::utils::{ - get_enclosing_block, get_trait_def_id, higher, implements_trait, is_in_panic_handler, is_no_std_crate, - is_refutable, last_path_segment, match_trait_method, path_to_local, path_to_local_id, paths, - snippet_with_applicability, span_lint_and_help, span_lint_and_sugg, sugg, + higher, is_in_panic_handler, is_no_std_crate, snippet_with_applicability, span_lint_and_help, span_lint_and_sugg, + sugg, }; -use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::intravisit::{walk_block, walk_expr, NestedVisitorMap, Visitor}; -use rustc_hir::{Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, PatKind, StmtKind}; +use rustc_hir::{Block, Expr, ExprKind, LoopSource, MatchSource, Pat, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; -use rustc_span::symbol::sym; -use utils::{ - get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor, LoopNestVisitor, Nesting, -}; +use utils::{get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor}; declare_clippy_lint! { /// **What it does:** Checks for for-loops that manually copy items between @@ -625,54 +618,8 @@ impl<'tcx> LateLintPass<'tcx> for Loops { } } } - if let ExprKind::Match(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.kind { - let pat = &arms[0].pat.kind; - if let ( - &PatKind::TupleStruct(ref qpath, ref pat_args, _), - &ExprKind::MethodCall(ref method_path, _, ref method_args, _), - ) = (pat, &match_expr.kind) - { - let iter_expr = &method_args[0]; - - // Don't lint when the iterator is recreated on every iteration - if_chain! { - if let ExprKind::MethodCall(..) | ExprKind::Call(..) = iter_expr.kind; - if let Some(iter_def_id) = get_trait_def_id(cx, &paths::ITERATOR); - if implements_trait(cx, cx.typeck_results().expr_ty(iter_expr), iter_def_id, &[]); - then { - return; - } - } - let lhs_constructor = last_path_segment(qpath); - if method_path.ident.name == sym::next - && match_trait_method(cx, match_expr, &paths::ITERATOR) - && lhs_constructor.ident.name == sym::Some - && (pat_args.is_empty() - || !is_refutable(cx, &pat_args[0]) - && !is_used_inside(cx, iter_expr, &arms[0].body) - && !is_iterator_used_after_while_let(cx, iter_expr) - && !is_nested(cx, expr, &method_args[0])) - { - let mut applicability = Applicability::MachineApplicable; - let iterator = snippet_with_applicability(cx, method_args[0].span, "_", &mut applicability); - let loop_var = if pat_args.is_empty() { - "_".to_string() - } else { - snippet_with_applicability(cx, pat_args[0].span, "_", &mut applicability).into_owned() - }; - span_lint_and_sugg( - cx, - WHILE_LET_ON_ITERATOR, - expr.span.with_hi(match_expr.span.hi()), - "this loop could be written as a `for` loop", - "try", - format!("for {} in {}", loop_var, iterator), - applicability, - ); - } - } - } + while_let_on_iterator::check_while_let_on_iterator(cx, expr); if let Some((cond, body)) = higher::while_loop(&expr) { infinite_loop::check_infinite_loop(cx, cond, body); @@ -693,7 +640,7 @@ fn check_for_loop<'tcx>( let is_manual_memcpy_triggered = manual_memcpy::detect_manual_memcpy(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { for_loop_range::check_for_loop_range(cx, pat, arg, body, expr); - for_loop_explicit_counter::check_for_loop_explicit_counter(cx, pat, arg, body, expr); + explicit_counter_loop::check_for_loop_explicit_counter(cx, pat, arg, body, expr); } for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); @@ -773,61 +720,6 @@ impl std::ops::Sub<&MinifyingSugg<'static>> for MinifyingSugg<'static> { } } -fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { - let def_id = match path_to_local(expr) { - Some(id) => id, - None => return false, - }; - if let Some(used_mutably) = mutated_variables(container, cx) { - if used_mutably.contains(&def_id) { - return true; - } - } - false -} - -fn is_iterator_used_after_while_let<'tcx>(cx: &LateContext<'tcx>, iter_expr: &'tcx Expr<'_>) -> bool { - let def_id = match path_to_local(iter_expr) { - Some(id) => id, - None => return false, - }; - let mut visitor = VarUsedAfterLoopVisitor { - def_id, - iter_expr_id: iter_expr.hir_id, - past_while_let: false, - var_used_after_while_let: false, - }; - if let Some(enclosing_block) = get_enclosing_block(cx, def_id) { - walk_block(&mut visitor, enclosing_block); - } - visitor.var_used_after_while_let -} - -struct VarUsedAfterLoopVisitor { - def_id: HirId, - iter_expr_id: HirId, - past_while_let: bool, - var_used_after_while_let: bool, -} - -impl<'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor { - type Map = Map<'tcx>; - - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if self.past_while_let { - if path_to_local_id(expr, self.def_id) { - self.var_used_after_while_let = true; - } - } else if self.iter_expr_id == expr.hir_id { - self.past_while_let = true; - } - walk_expr(self, expr); - } - fn nested_visit_map(&mut self) -> NestedVisitorMap { - NestedVisitorMap::None - } -} - /// If a block begins with a statement (possibly a `let` binding) and has an /// expression, return it. fn extract_expr_from_first_stmt<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { @@ -863,53 +755,3 @@ fn is_simple_break_expr(expr: &Expr<'_>) -> bool { _ => false, } } - -fn is_nested(cx: &LateContext<'_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { - if_chain! { - if let Some(loop_block) = get_enclosing_block(cx, match_expr.hir_id); - let parent_node = cx.tcx.hir().get_parent_node(loop_block.hir_id); - if let Some(Node::Expr(loop_expr)) = cx.tcx.hir().find(parent_node); - then { - return is_loop_nested(cx, loop_expr, iter_expr) - } - } - false -} - -fn is_loop_nested(cx: &LateContext<'_>, loop_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { - let mut id = loop_expr.hir_id; - let iter_id = if let Some(id) = path_to_local(iter_expr) { - id - } else { - return true; - }; - loop { - let parent = cx.tcx.hir().get_parent_node(id); - if parent == id { - return false; - } - match cx.tcx.hir().find(parent) { - Some(Node::Expr(expr)) => { - if let ExprKind::Loop(..) = expr.kind { - return true; - }; - }, - Some(Node::Block(block)) => { - let mut block_visitor = LoopNestVisitor { - hir_id: id, - iterator: iter_id, - nesting: Nesting::Unknown, - }; - walk_block(&mut block_visitor, block); - if block_visitor.nesting == Nesting::RuledOut { - return false; - } - }, - Some(Node::Stmt(_)) => (), - _ => { - return false; - }, - } - id = parent; - } -} diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs new file mode 100644 index 0000000000000..090c8ceba9744 --- /dev/null +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -0,0 +1,171 @@ +use super::utils::{LoopNestVisitor, Nesting}; +use super::WHILE_LET_ON_ITERATOR; +use crate::utils::usage::mutated_variables; +use crate::utils::{ + get_enclosing_block, get_trait_def_id, implements_trait, is_refutable, last_path_segment, match_trait_method, + path_to_local, path_to_local_id, paths, snippet_with_applicability, span_lint_and_sugg, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::intravisit::{walk_block, walk_expr, NestedVisitorMap, Visitor}; +use rustc_hir::{Expr, ExprKind, HirId, MatchSource, Node, PatKind}; +use rustc_lint::LateContext; +use rustc_middle::hir::map::Map; + +use rustc_span::symbol::sym; + +pub(super) fn check_while_let_on_iterator(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Match(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.kind { + let pat = &arms[0].pat.kind; + if let ( + &PatKind::TupleStruct(ref qpath, ref pat_args, _), + &ExprKind::MethodCall(ref method_path, _, ref method_args, _), + ) = (pat, &match_expr.kind) + { + let iter_expr = &method_args[0]; + + // Don't lint when the iterator is recreated on every iteration + if_chain! { + if let ExprKind::MethodCall(..) | ExprKind::Call(..) = iter_expr.kind; + if let Some(iter_def_id) = get_trait_def_id(cx, &paths::ITERATOR); + if implements_trait(cx, cx.typeck_results().expr_ty(iter_expr), iter_def_id, &[]); + then { + return; + } + } + + let lhs_constructor = last_path_segment(qpath); + if method_path.ident.name == sym::next + && match_trait_method(cx, match_expr, &paths::ITERATOR) + && lhs_constructor.ident.name == sym::Some + && (pat_args.is_empty() + || !is_refutable(cx, &pat_args[0]) + && !is_used_inside(cx, iter_expr, &arms[0].body) + && !is_iterator_used_after_while_let(cx, iter_expr) + && !is_nested(cx, expr, &method_args[0])) + { + let mut applicability = Applicability::MachineApplicable; + let iterator = snippet_with_applicability(cx, method_args[0].span, "_", &mut applicability); + let loop_var = if pat_args.is_empty() { + "_".to_string() + } else { + snippet_with_applicability(cx, pat_args[0].span, "_", &mut applicability).into_owned() + }; + span_lint_and_sugg( + cx, + WHILE_LET_ON_ITERATOR, + expr.span.with_hi(match_expr.span.hi()), + "this loop could be written as a `for` loop", + "try", + format!("for {} in {}", loop_var, iterator), + applicability, + ); + } + } + } +} + +fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { + let def_id = match path_to_local(expr) { + Some(id) => id, + None => return false, + }; + if let Some(used_mutably) = mutated_variables(container, cx) { + if used_mutably.contains(&def_id) { + return true; + } + } + false +} + +fn is_iterator_used_after_while_let<'tcx>(cx: &LateContext<'tcx>, iter_expr: &'tcx Expr<'_>) -> bool { + let def_id = match path_to_local(iter_expr) { + Some(id) => id, + None => return false, + }; + let mut visitor = VarUsedAfterLoopVisitor { + def_id, + iter_expr_id: iter_expr.hir_id, + past_while_let: false, + var_used_after_while_let: false, + }; + if let Some(enclosing_block) = get_enclosing_block(cx, def_id) { + walk_block(&mut visitor, enclosing_block); + } + visitor.var_used_after_while_let +} + +fn is_nested(cx: &LateContext<'_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { + if_chain! { + if let Some(loop_block) = get_enclosing_block(cx, match_expr.hir_id); + let parent_node = cx.tcx.hir().get_parent_node(loop_block.hir_id); + if let Some(Node::Expr(loop_expr)) = cx.tcx.hir().find(parent_node); + then { + return is_loop_nested(cx, loop_expr, iter_expr) + } + } + false +} + +fn is_loop_nested(cx: &LateContext<'_>, loop_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { + let mut id = loop_expr.hir_id; + let iter_id = if let Some(id) = path_to_local(iter_expr) { + id + } else { + return true; + }; + loop { + let parent = cx.tcx.hir().get_parent_node(id); + if parent == id { + return false; + } + match cx.tcx.hir().find(parent) { + Some(Node::Expr(expr)) => { + if let ExprKind::Loop(..) = expr.kind { + return true; + }; + }, + Some(Node::Block(block)) => { + let mut block_visitor = LoopNestVisitor { + hir_id: id, + iterator: iter_id, + nesting: Nesting::Unknown, + }; + walk_block(&mut block_visitor, block); + if block_visitor.nesting == Nesting::RuledOut { + return false; + } + }, + Some(Node::Stmt(_)) => (), + _ => { + return false; + }, + } + id = parent; + } +} + +struct VarUsedAfterLoopVisitor { + def_id: HirId, + iter_expr_id: HirId, + past_while_let: bool, + var_used_after_while_let: bool, +} + +impl<'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor { + type Map = Map<'tcx>; + + fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { + if self.past_while_let { + if path_to_local_id(expr, self.def_id) { + self.var_used_after_while_let = true; + } + } else if self.iter_expr_id == expr.hir_id { + self.past_while_let = true; + } + walk_expr(self, expr); + } + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } +} From 287a4f8ab176a95cff2b82f6414d37e33809110a Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 21 Feb 2021 16:48:16 +0100 Subject: [PATCH 068/226] Refactor empty loop to its own module --- clippy_lints/src/loops/empty_loop.rs | 17 +++++++++++++++++ clippy_lints/src/loops/mod.rs | 16 +++------------- 2 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 clippy_lints/src/loops/empty_loop.rs diff --git a/clippy_lints/src/loops/empty_loop.rs b/clippy_lints/src/loops/empty_loop.rs new file mode 100644 index 0000000000000..fdc99e190e381 --- /dev/null +++ b/clippy_lints/src/loops/empty_loop.rs @@ -0,0 +1,17 @@ +use super::EMPTY_LOOP; +use crate::utils::{is_in_panic_handler, is_no_std_crate, span_lint_and_help}; + +use rustc_hir::{Block, Expr}; +use rustc_lint::LateContext; + +pub(super) fn check_empty_loop(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) { + if loop_block.stmts.is_empty() && loop_block.expr.is_none() && !is_in_panic_handler(cx, expr) { + let msg = "empty `loop {}` wastes CPU cycles"; + let help = if is_no_std_crate(cx.tcx.hir().krate()) { + "you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body" + } else { + "you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body" + }; + span_lint_and_help(cx, EMPTY_LOOP, expr.span, msg, None, help); + } +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index cadf92412562b..d205f0536792e 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,3 +1,4 @@ +mod empty_loop; mod explicit_counter_loop; mod for_loop_arg; mod for_loop_over_map_kv; @@ -14,10 +15,7 @@ mod utils; mod while_let_on_iterator; use crate::utils::sugg::Sugg; -use crate::utils::{ - higher, is_in_panic_handler, is_no_std_crate, snippet_with_applicability, span_lint_and_help, span_lint_and_sugg, - sugg, -}; +use crate::utils::{higher, snippet_with_applicability, span_lint_and_sugg, sugg}; use rustc_errors::Applicability; use rustc_hir::{Block, Expr, ExprKind, LoopSource, MatchSource, Pat, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -565,15 +563,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { // (even if the "match" or "if let" is used for declaration) if let ExprKind::Loop(ref block, _, LoopSource::Loop, _) = expr.kind { // also check for empty `loop {}` statements, skipping those in #[panic_handler] - if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) { - let msg = "empty `loop {}` wastes CPU cycles"; - let help = if is_no_std_crate(cx.tcx.hir().krate()) { - "you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body" - } else { - "you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body" - }; - span_lint_and_help(cx, EMPTY_LOOP, expr.span, msg, None, help); - } + empty_loop::check_empty_loop(cx, expr, block); // extract the expression from the first statement (if any) in a block let inner_stmt_expr = extract_expr_from_first_stmt(block); From 7158c944a4f033f6feb57fbcdbf3453333d892b7 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 21 Feb 2021 17:01:49 +0100 Subject: [PATCH 069/226] Refactor while let loop to its own module --- clippy_lints/src/loops/mod.rs | 89 ++---------------------- clippy_lints/src/loops/while_let_loop.rs | 87 +++++++++++++++++++++++ 2 files changed, 92 insertions(+), 84 deletions(-) create mode 100644 clippy_lints/src/loops/while_let_loop.rs diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index d205f0536792e..9076e48584a7a 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -12,14 +12,13 @@ mod needless_collect; mod never_loop; mod same_item_push; mod utils; +mod while_let_loop; mod while_let_on_iterator; use crate::utils::sugg::Sugg; -use crate::utils::{higher, snippet_with_applicability, span_lint_and_sugg, sugg}; -use rustc_errors::Applicability; -use rustc_hir::{Block, Expr, ExprKind, LoopSource, MatchSource, Pat, StmtKind}; -use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::lint::in_external_macro; +use crate::utils::{higher, sugg}; +use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; +use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use utils::{get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor}; @@ -564,49 +563,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { if let ExprKind::Loop(ref block, _, LoopSource::Loop, _) = expr.kind { // also check for empty `loop {}` statements, skipping those in #[panic_handler] empty_loop::check_empty_loop(cx, expr, block); - - // extract the expression from the first statement (if any) in a block - let inner_stmt_expr = extract_expr_from_first_stmt(block); - // or extract the first expression (if any) from the block - if let Some(inner) = inner_stmt_expr.or_else(|| extract_first_expr(block)) { - if let ExprKind::Match(ref matchexpr, ref arms, ref source) = inner.kind { - // ensure "if let" compatible match structure - match *source { - MatchSource::Normal | MatchSource::IfLetDesugar { .. } => { - if arms.len() == 2 - && arms[0].guard.is_none() - && arms[1].guard.is_none() - && is_simple_break_expr(&arms[1].body) - { - if in_external_macro(cx.sess(), expr.span) { - return; - } - - // NOTE: we used to build a body here instead of using - // ellipsis, this was removed because: - // 1) it was ugly with big bodies; - // 2) it was not indented properly; - // 3) it wasn’t very smart (see #675). - let mut applicability = Applicability::HasPlaceholders; - span_lint_and_sugg( - cx, - WHILE_LET_LOOP, - expr.span, - "this loop could be written as a `while let` loop", - "try", - format!( - "while let {} = {} {{ .. }}", - snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability), - snippet_with_applicability(cx, matchexpr.span, "..", &mut applicability), - ), - applicability, - ); - } - }, - _ => (), - } - } - } + while_let_loop::check_while_let_loop(cx, expr, block); } while_let_on_iterator::check_while_let_on_iterator(cx, expr); @@ -709,39 +666,3 @@ impl std::ops::Sub<&MinifyingSugg<'static>> for MinifyingSugg<'static> { } } } - -/// If a block begins with a statement (possibly a `let` binding) and has an -/// expression, return it. -fn extract_expr_from_first_stmt<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { - if block.stmts.is_empty() { - return None; - } - if let StmtKind::Local(ref local) = block.stmts[0].kind { - local.init //.map(|expr| expr) - } else { - None - } -} - -/// If a block begins with an expression (with or without semicolon), return it. -fn extract_first_expr<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { - match block.expr { - Some(ref expr) if block.stmts.is_empty() => Some(expr), - None if !block.stmts.is_empty() => match block.stmts[0].kind { - StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => Some(expr), - StmtKind::Local(..) | StmtKind::Item(..) => None, - }, - _ => None, - } -} - -/// Returns `true` if expr contains a single break expr without destination label -/// and -/// passed expression. The expression may be within a block. -fn is_simple_break_expr(expr: &Expr<'_>) -> bool { - match expr.kind { - ExprKind::Break(dest, ref passed_expr) if dest.label.is_none() && passed_expr.is_none() => true, - ExprKind::Block(ref b, _) => extract_first_expr(b).map_or(false, |subexpr| is_simple_break_expr(subexpr)), - _ => false, - } -} diff --git a/clippy_lints/src/loops/while_let_loop.rs b/clippy_lints/src/loops/while_let_loop.rs new file mode 100644 index 0000000000000..0c95798696457 --- /dev/null +++ b/clippy_lints/src/loops/while_let_loop.rs @@ -0,0 +1,87 @@ +use super::WHILE_LET_LOOP; +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir::{Block, Expr, ExprKind, MatchSource, StmtKind}; +use rustc_lint::{LateContext, LintContext}; +use rustc_middle::lint::in_external_macro; + +pub(super) fn check_while_let_loop(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) { + // extract the expression from the first statement (if any) in a block + let inner_stmt_expr = extract_expr_from_first_stmt(loop_block); + // or extract the first expression (if any) from the block + if let Some(inner) = inner_stmt_expr.or_else(|| extract_first_expr(loop_block)) { + if let ExprKind::Match(ref matchexpr, ref arms, ref source) = inner.kind { + // ensure "if let" compatible match structure + match *source { + MatchSource::Normal | MatchSource::IfLetDesugar { .. } => { + if arms.len() == 2 + && arms[0].guard.is_none() + && arms[1].guard.is_none() + && is_simple_break_expr(&arms[1].body) + { + if in_external_macro(cx.sess(), expr.span) { + return; + } + + // NOTE: we used to build a body here instead of using + // ellipsis, this was removed because: + // 1) it was ugly with big bodies; + // 2) it was not indented properly; + // 3) it wasn’t very smart (see #675). + let mut applicability = Applicability::HasPlaceholders; + span_lint_and_sugg( + cx, + WHILE_LET_LOOP, + expr.span, + "this loop could be written as a `while let` loop", + "try", + format!( + "while let {} = {} {{ .. }}", + snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability), + snippet_with_applicability(cx, matchexpr.span, "..", &mut applicability), + ), + applicability, + ); + } + }, + _ => (), + } + } + } +} + +/// If a block begins with a statement (possibly a `let` binding) and has an +/// expression, return it. +fn extract_expr_from_first_stmt<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { + if block.stmts.is_empty() { + return None; + } + if let StmtKind::Local(ref local) = block.stmts[0].kind { + local.init //.map(|expr| expr) + } else { + None + } +} + +/// If a block begins with an expression (with or without semicolon), return it. +fn extract_first_expr<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { + match block.expr { + Some(ref expr) if block.stmts.is_empty() => Some(expr), + None if !block.stmts.is_empty() => match block.stmts[0].kind { + StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => Some(expr), + StmtKind::Local(..) | StmtKind::Item(..) => None, + }, + _ => None, + } +} + +/// Returns `true` if expr contains a single break expr without destination label +/// and +/// passed expression. The expression may be within a block. +fn is_simple_break_expr(expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::Break(dest, ref passed_expr) if dest.label.is_none() && passed_expr.is_none() => true, + ExprKind::Block(ref b, _) => extract_first_expr(b).map_or(false, |subexpr| is_simple_break_expr(subexpr)), + _ => false, + } +} From 7cfdef6de19a0aaddcc3018baf1031ae54c419f6 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 21 Feb 2021 17:10:07 +0100 Subject: [PATCH 070/226] Move MinifyingSugg into manual_memcpy --- clippy_lints/src/loops/manual_memcpy.rs | 72 +++++++++++++++++++++++- clippy_lints/src/loops/mod.rs | 73 +------------------------ 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs index 85b3dfaece736..13a434aa210d6 100644 --- a/clippy_lints/src/loops/manual_memcpy.rs +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -1,4 +1,4 @@ -use super::{get_span_of_entire_for_loop, IncrementVisitor, InitializeVisitor, MinifyingSugg}; +use super::{get_span_of_entire_for_loop, IncrementVisitor, InitializeVisitor}; use crate::utils::sugg::Sugg; use crate::utils::{ get_enclosing_block, higher, is_type_diagnostic_item, path_to_local, snippet, span_lint_and_sugg, sugg, @@ -194,6 +194,76 @@ fn build_manual_memcpy_suggestion<'tcx>( ) } +/// a wrapper of `Sugg`. Besides what `Sugg` do, this removes unnecessary `0`; +/// and also, it avoids subtracting a variable from the same one by replacing it with `0`. +/// it exists for the convenience of the overloaded operators while normal functions can do the +/// same. +#[derive(Clone)] +struct MinifyingSugg<'a>(Sugg<'a>); + +impl<'a> MinifyingSugg<'a> { + fn as_str(&self) -> &str { + let Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) = &self.0; + s.as_ref() + } + + fn into_sugg(self) -> Sugg<'a> { + self.0 + } +} + +impl<'a> From> for MinifyingSugg<'a> { + fn from(sugg: Sugg<'a>) -> Self { + Self(sugg) + } +} + +impl std::ops::Add for &MinifyingSugg<'static> { + type Output = MinifyingSugg<'static>; + fn add(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { + match (self.as_str(), rhs.as_str()) { + ("0", _) => rhs.clone(), + (_, "0") => self.clone(), + (_, _) => (&self.0 + &rhs.0).into(), + } + } +} + +impl std::ops::Sub for &MinifyingSugg<'static> { + type Output = MinifyingSugg<'static>; + fn sub(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { + match (self.as_str(), rhs.as_str()) { + (_, "0") => self.clone(), + ("0", _) => (-rhs.0.clone()).into(), + (x, y) if x == y => sugg::ZERO.into(), + (_, _) => (&self.0 - &rhs.0).into(), + } + } +} + +impl std::ops::Add<&MinifyingSugg<'static>> for MinifyingSugg<'static> { + type Output = MinifyingSugg<'static>; + fn add(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { + match (self.as_str(), rhs.as_str()) { + ("0", _) => rhs.clone(), + (_, "0") => self, + (_, _) => (self.0 + &rhs.0).into(), + } + } +} + +impl std::ops::Sub<&MinifyingSugg<'static>> for MinifyingSugg<'static> { + type Output = MinifyingSugg<'static>; + fn sub(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { + match (self.as_str(), rhs.as_str()) { + (_, "0") => self, + ("0", _) => (-rhs.0.clone()).into(), + (x, y) if x == y => sugg::ZERO.into(), + (_, _) => (self.0 - &rhs.0).into(), + } + } +} + /// a wrapper around `MinifyingSugg`, which carries a operator like currying /// so that the suggested code become more efficient (e.g. `foo + -bar` `foo - bar`). struct Offset { diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 9076e48584a7a..c0191e43dea96 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -15,8 +15,7 @@ mod utils; mod while_let_loop; mod while_let_on_iterator; -use crate::utils::sugg::Sugg; -use crate::utils::{higher, sugg}; +use crate::utils::higher; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -596,73 +595,3 @@ fn check_for_loop<'tcx>( same_item_push::detect_same_item_push(cx, pat, arg, body, expr); manual_flatten::check_manual_flatten(cx, pat, arg, body, span); } - -/// a wrapper of `Sugg`. Besides what `Sugg` do, this removes unnecessary `0`; -/// and also, it avoids subtracting a variable from the same one by replacing it with `0`. -/// it exists for the convenience of the overloaded operators while normal functions can do the -/// same. -#[derive(Clone)] -struct MinifyingSugg<'a>(Sugg<'a>); - -impl<'a> MinifyingSugg<'a> { - fn as_str(&self) -> &str { - let Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) = &self.0; - s.as_ref() - } - - fn into_sugg(self) -> Sugg<'a> { - self.0 - } -} - -impl<'a> From> for MinifyingSugg<'a> { - fn from(sugg: Sugg<'a>) -> Self { - Self(sugg) - } -} - -impl std::ops::Add for &MinifyingSugg<'static> { - type Output = MinifyingSugg<'static>; - fn add(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { - match (self.as_str(), rhs.as_str()) { - ("0", _) => rhs.clone(), - (_, "0") => self.clone(), - (_, _) => (&self.0 + &rhs.0).into(), - } - } -} - -impl std::ops::Sub for &MinifyingSugg<'static> { - type Output = MinifyingSugg<'static>; - fn sub(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { - match (self.as_str(), rhs.as_str()) { - (_, "0") => self.clone(), - ("0", _) => (-rhs.0.clone()).into(), - (x, y) if x == y => sugg::ZERO.into(), - (_, _) => (&self.0 - &rhs.0).into(), - } - } -} - -impl std::ops::Add<&MinifyingSugg<'static>> for MinifyingSugg<'static> { - type Output = MinifyingSugg<'static>; - fn add(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { - match (self.as_str(), rhs.as_str()) { - ("0", _) => rhs.clone(), - (_, "0") => self, - (_, _) => (self.0 + &rhs.0).into(), - } - } -} - -impl std::ops::Sub<&MinifyingSugg<'static>> for MinifyingSugg<'static> { - type Output = MinifyingSugg<'static>; - fn sub(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> { - match (self.as_str(), rhs.as_str()) { - (_, "0") => self, - ("0", _) => (-rhs.0.clone()).into(), - (x, y) if x == y => sugg::ZERO.into(), - (_, _) => (self.0 - &rhs.0).into(), - } - } -} From ecebfe0c9cee0694e986af63a446031606825d18 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 21 Feb 2021 18:12:17 +0100 Subject: [PATCH 071/226] Move check_for_loop_arg back to mod; split into 4 lint files --- .../src/loops/explicit_into_iter_loop.rs | 20 +++++ clippy_lints/src/loops/explicit_iter_loop.rs | 21 +++++ .../src/loops/for_loops_over_fallibles.rs | 45 +++++++++++ clippy_lints/src/loops/iter_next_loop.rs | 14 ++++ clippy_lints/src/loops/mod.rs | 80 ++++++++++++++++++- 5 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 clippy_lints/src/loops/explicit_into_iter_loop.rs create mode 100644 clippy_lints/src/loops/explicit_iter_loop.rs create mode 100644 clippy_lints/src/loops/for_loops_over_fallibles.rs create mode 100644 clippy_lints/src/loops/iter_next_loop.rs diff --git a/clippy_lints/src/loops/explicit_into_iter_loop.rs b/clippy_lints/src/loops/explicit_into_iter_loop.rs new file mode 100644 index 0000000000000..d5d2bedaf1b4e --- /dev/null +++ b/clippy_lints/src/loops/explicit_into_iter_loop.rs @@ -0,0 +1,20 @@ +use super::EXPLICIT_INTO_ITER_LOOP; +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; + +pub(super) fn check_explicit_into_iter_loop(cx: &LateContext<'_>, method_args: &'hir [Expr<'hir>], arg: &Expr<'_>) { + let mut applicability = Applicability::MachineApplicable; + let object = snippet_with_applicability(cx, method_args[0].span, "_", &mut applicability); + span_lint_and_sugg( + cx, + EXPLICIT_INTO_ITER_LOOP, + arg.span, + "it is more concise to loop over containers instead of using explicit \ + iteration methods", + "to write this more concisely, try", + object.to_string(), + applicability, + ); +} diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs new file mode 100644 index 0000000000000..14184865da337 --- /dev/null +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -0,0 +1,21 @@ +use super::EXPLICIT_ITER_LOOP; +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; + +pub(super) fn lint_iter_method(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { + let mut applicability = Applicability::MachineApplicable; + let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); + let muta = if method_name == "iter_mut" { "mut " } else { "" }; + span_lint_and_sugg( + cx, + EXPLICIT_ITER_LOOP, + arg.span, + "it is more concise to loop over references to containers instead of using explicit \ + iteration methods", + "to write this more concisely, try", + format!("&{}{}", muta, object), + applicability, + ) +} diff --git a/clippy_lints/src/loops/for_loops_over_fallibles.rs b/clippy_lints/src/loops/for_loops_over_fallibles.rs new file mode 100644 index 0000000000000..1339af33759af --- /dev/null +++ b/clippy_lints/src/loops/for_loops_over_fallibles.rs @@ -0,0 +1,45 @@ +use super::FOR_LOOPS_OVER_FALLIBLES; +use crate::utils::{is_type_diagnostic_item, snippet, span_lint_and_help}; +use rustc_hir::{Expr, Pat}; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +/// Checks for `for` loops over `Option`s and `Result`s. +pub(super) fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { + let ty = cx.typeck_results().expr_ty(arg); + if is_type_diagnostic_item(cx, ty, sym::option_type) { + span_lint_and_help( + cx, + FOR_LOOPS_OVER_FALLIBLES, + arg.span, + &format!( + "for loop over `{0}`, which is an `Option`. This is more readably written as an \ + `if let` statement", + snippet(cx, arg.span, "_") + ), + None, + &format!( + "consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`", + snippet(cx, pat.span, "_"), + snippet(cx, arg.span, "_") + ), + ); + } else if is_type_diagnostic_item(cx, ty, sym::result_type) { + span_lint_and_help( + cx, + FOR_LOOPS_OVER_FALLIBLES, + arg.span, + &format!( + "for loop over `{0}`, which is a `Result`. This is more readably written as an \ + `if let` statement", + snippet(cx, arg.span, "_") + ), + None, + &format!( + "consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`", + snippet(cx, pat.span, "_"), + snippet(cx, arg.span, "_") + ), + ); + } +} diff --git a/clippy_lints/src/loops/iter_next_loop.rs b/clippy_lints/src/loops/iter_next_loop.rs new file mode 100644 index 0000000000000..7a5a873a358a5 --- /dev/null +++ b/clippy_lints/src/loops/iter_next_loop.rs @@ -0,0 +1,14 @@ +use super::ITER_NEXT_LOOP; +use crate::utils::span_lint; +use rustc_hir::Expr; +use rustc_lint::LateContext; + +pub(super) fn lint(cx: &LateContext<'_>, expr: &Expr<'_>) { + span_lint( + cx, + ITER_NEXT_LOOP, + expr.span, + "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ + probably not what you want", + ); +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index c0191e43dea96..4594afc233283 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -1,11 +1,14 @@ mod empty_loop; mod explicit_counter_loop; -mod for_loop_arg; +mod explicit_into_iter_loop; +mod explicit_iter_loop; mod for_loop_over_map_kv; mod for_loop_range; +mod for_loops_over_fallibles; mod for_mut_range_bound; mod for_single_element_loop; mod infinite_loop; +mod iter_next_loop; mod manual_flatten; mod manual_memcpy; mod needless_collect; @@ -15,11 +18,13 @@ mod utils; mod while_let_loop; mod while_let_on_iterator; -use crate::utils::higher; -use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; +use crate::utils::{higher, is_type_diagnostic_item, match_trait_method, match_type, paths}; +use rustc_hir::{Expr, ExprKind, LoopSource, Mutability, Pat}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{self, Ty, TyS}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; +use rustc_span::symbol::sym; use utils::{get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor}; declare_clippy_lint! { @@ -588,10 +593,77 @@ fn check_for_loop<'tcx>( for_loop_range::check_for_loop_range(cx, pat, arg, body, expr); explicit_counter_loop::check_for_loop_explicit_counter(cx, pat, arg, body, expr); } - for_loop_arg::check_for_loop_arg(cx, pat, arg, expr); + check_for_loop_arg(cx, pat, arg, expr); for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); for_mut_range_bound::check_for_mut_range_bound(cx, arg, body); for_single_element_loop::check_for_single_element_loop(cx, pat, arg, body, expr); same_item_push::detect_same_item_push(cx, pat, arg, body, expr); manual_flatten::check_manual_flatten(cx, pat, arg, body, span); } + +fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { + let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used + if let ExprKind::MethodCall(ref method, _, ref args, _) = arg.kind { + // just the receiver, no arguments + if args.len() == 1 { + let method_name = &*method.ident.as_str(); + // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x + if method_name == "iter" || method_name == "iter_mut" { + if is_ref_iterable_type(cx, &args[0]) { + explicit_iter_loop::lint_iter_method(cx, args, arg, method_name); + } + } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { + let receiver_ty = cx.typeck_results().expr_ty(&args[0]); + let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); + if TyS::same_type(receiver_ty, receiver_ty_adjusted) { + explicit_into_iter_loop::check_explicit_into_iter_loop(cx, args, arg); + } else { + let ref_receiver_ty = cx.tcx.mk_ref( + cx.tcx.lifetimes.re_erased, + ty::TypeAndMut { + ty: receiver_ty, + mutbl: Mutability::Not, + }, + ); + if TyS::same_type(receiver_ty_adjusted, ref_receiver_ty) { + explicit_iter_loop::lint_iter_method(cx, args, arg, method_name) + } + } + } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { + iter_next_loop::lint(cx, expr); + next_loop_linted = true; + } + } + } + if !next_loop_linted { + for_loops_over_fallibles::check_arg_type(cx, pat, arg); + } +} + +/// Returns `true` if the type of expr is one that provides `IntoIterator` impls +/// for `&T` and `&mut T`, such as `Vec`. +#[rustfmt::skip] +fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { + // no walk_ptrs_ty: calling iter() on a reference can make sense because it + // will allow further borrows afterwards + let ty = cx.typeck_results().expr_ty(e); + is_iterable_array(ty, cx) || + is_type_diagnostic_item(cx, ty, sym::vec_type) || + match_type(cx, ty, &paths::LINKED_LIST) || + is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || + is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || + is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + match_type(cx, ty, &paths::BINARY_HEAP) || + match_type(cx, ty, &paths::BTREEMAP) || + match_type(cx, ty, &paths::BTREESET) +} + +fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { + // IntoIterator is currently only implemented for array sizes <= 32 in rustc + match ty.kind() { + ty::Array(_, n) => n + .try_eval_usize(cx.tcx, cx.param_env) + .map_or(false, |val| (0..=32).contains(&val)), + _ => false, + } +} From 2229a0839efe52a3014133db5e469770000341c4 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Sun, 21 Feb 2021 18:25:50 +0100 Subject: [PATCH 072/226] Clean up: Rename some files to be consistent with lint names; import lints to each file --- .../src/loops/explicit_counter_loop.rs | 6 ++++-- ...{for_loop_over_map_kv.rs => for_kv_map.rs} | 3 ++- clippy_lints/src/loops/manual_flatten.rs | 3 ++- clippy_lints/src/loops/manual_memcpy.rs | 4 ++-- clippy_lints/src/loops/mod.rs | 20 +++++++++---------- ..._mut_range_bound.rs => mut_range_bound.rs} | 3 ++- clippy_lints/src/loops/needless_collect.rs | 7 ++++--- ...r_loop_range.rs => needless_range_loop.rs} | 5 +++-- clippy_lints/src/loops/same_item_push.rs | 3 ++- ...element_loop.rs => single_element_loop.rs} | 4 ++-- ...e_loop.rs => while_immutable_condition.rs} | 3 ++- 11 files changed, 35 insertions(+), 26 deletions(-) rename clippy_lints/src/loops/{for_loop_over_map_kv.rs => for_kv_map.rs} (97%) rename clippy_lints/src/loops/{for_mut_range_bound.rs => mut_range_bound.rs} (98%) rename clippy_lints/src/loops/{for_loop_range.rs => needless_range_loop.rs} (99%) rename clippy_lints/src/loops/{for_single_element_loop.rs => single_element_loop.rs} (93%) rename clippy_lints/src/loops/{infinite_loop.rs => while_immutable_condition.rs} (98%) diff --git a/clippy_lints/src/loops/explicit_counter_loop.rs b/clippy_lints/src/loops/explicit_counter_loop.rs index 68fee269eb1d6..59116032f664a 100644 --- a/clippy_lints/src/loops/explicit_counter_loop.rs +++ b/clippy_lints/src/loops/explicit_counter_loop.rs @@ -1,4 +1,6 @@ -use super::{get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor}; +use super::{ + get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor, EXPLICIT_COUNTER_LOOP, +}; use crate::utils::{get_enclosing_block, is_integer_const, snippet_with_applicability, span_lint_and_sugg}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -37,7 +39,7 @@ pub(super) fn check_for_loop_explicit_counter<'tcx>( span_lint_and_sugg( cx, - super::EXPLICIT_COUNTER_LOOP, + EXPLICIT_COUNTER_LOOP, for_span.with_hi(arg.span.hi()), &format!("the variable `{}` is used as a loop counter", name), "consider using", diff --git a/clippy_lints/src/loops/for_loop_over_map_kv.rs b/clippy_lints/src/loops/for_kv_map.rs similarity index 97% rename from clippy_lints/src/loops/for_loop_over_map_kv.rs rename to clippy_lints/src/loops/for_kv_map.rs index c5f0b0909ba64..228d462f6e18e 100644 --- a/clippy_lints/src/loops/for_loop_over_map_kv.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -1,3 +1,4 @@ +use super::FOR_KV_MAP; use crate::utils::visitors::LocalUsedVisitor; use crate::utils::{is_type_diagnostic_item, match_type, multispan_sugg, paths, snippet, span_lint_and_then, sugg}; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; @@ -37,7 +38,7 @@ pub(super) fn check_for_loop_over_map_kv<'tcx>( if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP) { span_lint_and_then( cx, - super::FOR_KV_MAP, + FOR_KV_MAP, expr.span, &format!("you seem to want to iterate on a map's {}s", kind), |diag| { diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs index db90d2c0468fc..efacda772848f 100644 --- a/clippy_lints/src/loops/manual_flatten.rs +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -1,4 +1,5 @@ use super::utils::make_iterator_snippet; +use super::MANUAL_FLATTEN; use crate::utils::{is_ok_ctor, is_some_ctor, path_to_local_id, span_lint_and_then}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -55,7 +56,7 @@ pub(super) fn check_manual_flatten<'tcx>( span_lint_and_then( cx, - super::MANUAL_FLATTEN, + MANUAL_FLATTEN, span, &msg, |diag| { diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs index 13a434aa210d6..e3080d9f556a3 100644 --- a/clippy_lints/src/loops/manual_memcpy.rs +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -1,4 +1,4 @@ -use super::{get_span_of_entire_for_loop, IncrementVisitor, InitializeVisitor}; +use super::{get_span_of_entire_for_loop, IncrementVisitor, InitializeVisitor, MANUAL_MEMCPY}; use crate::utils::sugg::Sugg; use crate::utils::{ get_enclosing_block, higher, is_type_diagnostic_item, path_to_local, snippet, span_lint_and_sugg, sugg, @@ -84,7 +84,7 @@ pub(super) fn detect_manual_memcpy<'tcx>( if let Some(big_sugg) = big_sugg { span_lint_and_sugg( cx, - super::MANUAL_MEMCPY, + MANUAL_MEMCPY, get_span_of_entire_for_loop(expr), "it looks like you're manually copying between slices", "try replacing the loop by", diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 4594afc233283..0d408698fc96b 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -2,19 +2,19 @@ mod empty_loop; mod explicit_counter_loop; mod explicit_into_iter_loop; mod explicit_iter_loop; -mod for_loop_over_map_kv; -mod for_loop_range; +mod for_kv_map; mod for_loops_over_fallibles; -mod for_mut_range_bound; -mod for_single_element_loop; -mod infinite_loop; mod iter_next_loop; mod manual_flatten; mod manual_memcpy; +mod mut_range_bound; mod needless_collect; +mod needless_range_loop; mod never_loop; mod same_item_push; +mod single_element_loop; mod utils; +mod while_immutable_condition; mod while_let_loop; mod while_let_on_iterator; @@ -573,7 +573,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { while_let_on_iterator::check_while_let_on_iterator(cx, expr); if let Some((cond, body)) = higher::while_loop(&expr) { - infinite_loop::check_infinite_loop(cx, cond, body); + while_immutable_condition::check_infinite_loop(cx, cond, body); } needless_collect::check_needless_collect(expr, cx); @@ -590,13 +590,13 @@ fn check_for_loop<'tcx>( ) { let is_manual_memcpy_triggered = manual_memcpy::detect_manual_memcpy(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { - for_loop_range::check_for_loop_range(cx, pat, arg, body, expr); + needless_range_loop::check_for_loop_range(cx, pat, arg, body, expr); explicit_counter_loop::check_for_loop_explicit_counter(cx, pat, arg, body, expr); } check_for_loop_arg(cx, pat, arg, expr); - for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr); - for_mut_range_bound::check_for_mut_range_bound(cx, arg, body); - for_single_element_loop::check_for_single_element_loop(cx, pat, arg, body, expr); + for_kv_map::check_for_loop_over_map_kv(cx, pat, arg, body, expr); + mut_range_bound::check_for_mut_range_bound(cx, arg, body); + single_element_loop::check_for_single_element_loop(cx, pat, arg, body, expr); same_item_push::detect_same_item_push(cx, pat, arg, body, expr); manual_flatten::check_manual_flatten(cx, pat, arg, body, span); } diff --git a/clippy_lints/src/loops/for_mut_range_bound.rs b/clippy_lints/src/loops/mut_range_bound.rs similarity index 98% rename from clippy_lints/src/loops/for_mut_range_bound.rs rename to clippy_lints/src/loops/mut_range_bound.rs index d305c55cb9515..9f31617edeb5e 100644 --- a/clippy_lints/src/loops/for_mut_range_bound.rs +++ b/clippy_lints/src/loops/mut_range_bound.rs @@ -1,3 +1,4 @@ +use super::MUT_RANGE_BOUND; use crate::utils::{higher, path_to_local, span_lint}; use if_chain::if_chain; use rustc_hir::{BindingAnnotation, Expr, HirId, Node, PatKind}; @@ -27,7 +28,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option) { if let Some(sp) = span { span_lint( cx, - super::MUT_RANGE_BOUND, + MUT_RANGE_BOUND, sp, "attempt to mutate range bound within loop; note that the range of the loop is unchanged", ); diff --git a/clippy_lints/src/loops/needless_collect.rs b/clippy_lints/src/loops/needless_collect.rs index cc2e297549276..d1ce055445b50 100644 --- a/clippy_lints/src/loops/needless_collect.rs +++ b/clippy_lints/src/loops/needless_collect.rs @@ -1,3 +1,4 @@ +use super::NEEDLESS_COLLECT; use crate::utils::sugg::Sugg; use crate::utils::{ is_type_diagnostic_item, match_trait_method, match_type, path_to_local_id, paths, snippet, span_lint_and_sugg, @@ -35,7 +36,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont let span = shorten_needless_collect_span(expr); span_lint_and_sugg( cx, - super::NEEDLESS_COLLECT, + NEEDLESS_COLLECT, span, NEEDLESS_COLLECT_MSG, "replace with", @@ -47,7 +48,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont let span = shorten_needless_collect_span(expr); span_lint_and_sugg( cx, - super::NEEDLESS_COLLECT, + NEEDLESS_COLLECT, span, NEEDLESS_COLLECT_MSG, "replace with", @@ -60,7 +61,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont let span = shorten_needless_collect_span(expr); span_lint_and_then( cx, - super::NEEDLESS_COLLECT, + NEEDLESS_COLLECT, span, NEEDLESS_COLLECT_MSG, |diag| { diff --git a/clippy_lints/src/loops/for_loop_range.rs b/clippy_lints/src/loops/needless_range_loop.rs similarity index 99% rename from clippy_lints/src/loops/for_loop_range.rs rename to clippy_lints/src/loops/needless_range_loop.rs index 43560abb7f2db..298753cc0310a 100644 --- a/clippy_lints/src/loops/for_loop_range.rs +++ b/clippy_lints/src/loops/needless_range_loop.rs @@ -1,3 +1,4 @@ +use super::NEEDLESS_RANGE_LOOP; use crate::utils::visitors::LocalUsedVisitor; use crate::utils::{ contains_name, has_iter_method, higher, is_integer_const, match_trait_method, multispan_sugg, path_to_local_id, @@ -142,7 +143,7 @@ pub(super) fn check_for_loop_range<'tcx>( if visitor.nonindex { span_lint_and_then( cx, - super::NEEDLESS_RANGE_LOOP, + NEEDLESS_RANGE_LOOP, expr.span, &format!("the loop variable `{}` is used to index `{}`", ident.name, indexed), |diag| { @@ -168,7 +169,7 @@ pub(super) fn check_for_loop_range<'tcx>( span_lint_and_then( cx, - super::NEEDLESS_RANGE_LOOP, + NEEDLESS_RANGE_LOOP, expr.span, &format!("the loop variable `{}` is only used to index `{}`", ident.name, indexed), |diag| { diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs index 62efb58a38f7d..c1d5f8b7186b0 100644 --- a/clippy_lints/src/loops/same_item_push.rs +++ b/clippy_lints/src/loops/same_item_push.rs @@ -1,3 +1,4 @@ +use super::SAME_ITEM_PUSH; use crate::utils::{implements_trait, is_type_diagnostic_item, snippet_with_macro_callsite, span_lint_and_help}; use if_chain::if_chain; use rustc_hir::def::{DefKind, Res}; @@ -22,7 +23,7 @@ pub(super) fn detect_same_item_push<'tcx>( span_lint_and_help( cx, - super::SAME_ITEM_PUSH, + SAME_ITEM_PUSH, vec.span, "it looks like the same item is being pushed into this Vec", None, diff --git a/clippy_lints/src/loops/for_single_element_loop.rs b/clippy_lints/src/loops/single_element_loop.rs similarity index 93% rename from clippy_lints/src/loops/for_single_element_loop.rs rename to clippy_lints/src/loops/single_element_loop.rs index 8ba19a2233a53..9e2697186db71 100644 --- a/clippy_lints/src/loops/for_single_element_loop.rs +++ b/clippy_lints/src/loops/single_element_loop.rs @@ -1,4 +1,4 @@ -use super::get_span_of_entire_for_loop; +use super::{get_span_of_entire_for_loop, SINGLE_ELEMENT_LOOP}; use crate::utils::{indent_of, single_segment_path, snippet, span_lint_and_sugg}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -30,7 +30,7 @@ pub(super) fn check_for_single_element_loop<'tcx>( span_lint_and_sugg( cx, - super::SINGLE_ELEMENT_LOOP, + SINGLE_ELEMENT_LOOP, for_span, "for loop over a single element", "try", diff --git a/clippy_lints/src/loops/infinite_loop.rs b/clippy_lints/src/loops/while_immutable_condition.rs similarity index 98% rename from clippy_lints/src/loops/infinite_loop.rs rename to clippy_lints/src/loops/while_immutable_condition.rs index b89942fb64755..42e6551b6817e 100644 --- a/clippy_lints/src/loops/infinite_loop.rs +++ b/clippy_lints/src/loops/while_immutable_condition.rs @@ -1,3 +1,4 @@ +use super::WHILE_IMMUTABLE_CONDITION; use crate::consts::constant; use crate::utils::span_lint_and_then; use crate::utils::usage::mutated_variables; @@ -43,7 +44,7 @@ pub(super) fn check_infinite_loop<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr if no_cond_variable_mutated && !mutable_static_in_cond { span_lint_and_then( cx, - super::WHILE_IMMUTABLE_CONDITION, + WHILE_IMMUTABLE_CONDITION, cond.span, "variables in the condition are not mutated in the loop body", |diag| { From 845a3a061c541a4c2b2293022113cbfd3e6e9cb2 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 22 Feb 2021 16:24:25 +0100 Subject: [PATCH 073/226] Include loops.rs changes from PR#6698 --- clippy_lints/src/loops/for_kv_map.rs | 8 ++++---- clippy_lints/src/loops/needless_range_loop.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index 228d462f6e18e..a5aaf082dd87a 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -20,8 +20,8 @@ pub(super) fn check_for_loop_over_map_kv<'tcx>( let arg_span = arg.span; let (new_pat_span, kind, ty, mutbl) = match *cx.typeck_results().expr_ty(arg).kind() { ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) { - (key, _) if pat_is_wild(key, body) => (pat[1].span, "value", ty, mutbl), - (_, value) if pat_is_wild(value, body) => (pat[0].span, "key", ty, Mutability::Not), + (key, _) if pat_is_wild(cx, key, body) => (pat[1].span, "value", ty, mutbl), + (_, value) if pat_is_wild(cx, value, body) => (pat[0].span, "key", ty, Mutability::Not), _ => return, }, _ => return, @@ -59,11 +59,11 @@ pub(super) fn check_for_loop_over_map_kv<'tcx>( } /// Returns `true` if the pattern is a `PatWild` or an ident prefixed with `_`. -fn pat_is_wild<'tcx>(pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { +fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { match *pat { PatKind::Wild => true, PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => { - !LocalUsedVisitor::new(id).check_expr(body) + !LocalUsedVisitor::new(cx, id).check_expr(body) }, _ => false, } diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs index 298753cc0310a..ee275bc5bd665 100644 --- a/clippy_lints/src/loops/needless_range_loop.rs +++ b/clippy_lints/src/loops/needless_range_loop.rs @@ -257,7 +257,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> { then { let index_used_directly = path_to_local_id(idx, self.var); let indexed_indirectly = { - let mut used_visitor = LocalUsedVisitor::new(self.var); + let mut used_visitor = LocalUsedVisitor::new(self.cx, self.var); walk_expr(&mut used_visitor, idx); used_visitor.used }; From eaf63d6df75e0a046ba65d8b3cad0314b447f63e Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 2 Mar 2021 11:49:14 +0900 Subject: [PATCH 074/226] Unify names of lint entry functions in loops to 'check' --- clippy_lints/src/loops/empty_loop.rs | 2 +- .../src/loops/explicit_counter_loop.rs | 2 +- .../src/loops/explicit_into_iter_loop.rs | 2 +- clippy_lints/src/loops/explicit_iter_loop.rs | 2 +- clippy_lints/src/loops/for_kv_map.rs | 2 +- .../src/loops/for_loops_over_fallibles.rs | 2 +- clippy_lints/src/loops/iter_next_loop.rs | 2 +- clippy_lints/src/loops/manual_flatten.rs | 2 +- clippy_lints/src/loops/manual_memcpy.rs | 2 +- clippy_lints/src/loops/mod.rs | 38 +++++++++---------- clippy_lints/src/loops/mut_range_bound.rs | 2 +- clippy_lints/src/loops/needless_collect.rs | 2 +- clippy_lints/src/loops/needless_range_loop.rs | 2 +- clippy_lints/src/loops/never_loop.rs | 2 +- clippy_lints/src/loops/same_item_push.rs | 2 +- clippy_lints/src/loops/single_element_loop.rs | 2 +- .../src/loops/while_immutable_condition.rs | 2 +- clippy_lints/src/loops/while_let_loop.rs | 2 +- .../src/loops/while_let_on_iterator.rs | 2 +- 19 files changed, 37 insertions(+), 37 deletions(-) diff --git a/clippy_lints/src/loops/empty_loop.rs b/clippy_lints/src/loops/empty_loop.rs index fdc99e190e381..67d1ac89b97af 100644 --- a/clippy_lints/src/loops/empty_loop.rs +++ b/clippy_lints/src/loops/empty_loop.rs @@ -4,7 +4,7 @@ use crate::utils::{is_in_panic_handler, is_no_std_crate, span_lint_and_help}; use rustc_hir::{Block, Expr}; use rustc_lint::LateContext; -pub(super) fn check_empty_loop(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) { +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) { if loop_block.stmts.is_empty() && loop_block.expr.is_none() && !is_in_panic_handler(cx, expr) { let msg = "empty `loop {}` wastes CPU cycles"; let help = if is_no_std_crate(cx.tcx.hir().krate()) { diff --git a/clippy_lints/src/loops/explicit_counter_loop.rs b/clippy_lints/src/loops/explicit_counter_loop.rs index 59116032f664a..8d98b940c66a9 100644 --- a/clippy_lints/src/loops/explicit_counter_loop.rs +++ b/clippy_lints/src/loops/explicit_counter_loop.rs @@ -11,7 +11,7 @@ use rustc_lint::LateContext; // To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be // incremented exactly once in the loop body, and initialized to zero // at the start of the loop. -pub(super) fn check_for_loop_explicit_counter<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/explicit_into_iter_loop.rs b/clippy_lints/src/loops/explicit_into_iter_loop.rs index d5d2bedaf1b4e..f89c4b8510363 100644 --- a/clippy_lints/src/loops/explicit_into_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_into_iter_loop.rs @@ -4,7 +4,7 @@ use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -pub(super) fn check_explicit_into_iter_loop(cx: &LateContext<'_>, method_args: &'hir [Expr<'hir>], arg: &Expr<'_>) { +pub(super) fn check(cx: &LateContext<'_>, method_args: &'hir [Expr<'hir>], arg: &Expr<'_>) { let mut applicability = Applicability::MachineApplicable; let object = snippet_with_applicability(cx, method_args[0].span, "_", &mut applicability); span_lint_and_sugg( diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index 14184865da337..0836054796a6e 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -4,7 +4,7 @@ use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -pub(super) fn lint_iter_method(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { +pub(super) fn check(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { let mut applicability = Applicability::MachineApplicable; let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); let muta = if method_name == "iter_mut" { "mut " } else { "" }; diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index a5aaf082dd87a..eb53c3179ca4a 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -6,7 +6,7 @@ use rustc_lint::LateContext; use rustc_middle::ty; /// Checks for the `FOR_KV_MAP` lint. -pub(super) fn check_for_loop_over_map_kv<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/for_loops_over_fallibles.rs b/clippy_lints/src/loops/for_loops_over_fallibles.rs index 1339af33759af..db22d90a304bc 100644 --- a/clippy_lints/src/loops/for_loops_over_fallibles.rs +++ b/clippy_lints/src/loops/for_loops_over_fallibles.rs @@ -5,7 +5,7 @@ use rustc_lint::LateContext; use rustc_span::symbol::sym; /// Checks for `for` loops over `Option`s and `Result`s. -pub(super) fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { +pub(super) fn check(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { let ty = cx.typeck_results().expr_ty(arg); if is_type_diagnostic_item(cx, ty, sym::option_type) { span_lint_and_help( diff --git a/clippy_lints/src/loops/iter_next_loop.rs b/clippy_lints/src/loops/iter_next_loop.rs index 7a5a873a358a5..cb9916deb62b4 100644 --- a/clippy_lints/src/loops/iter_next_loop.rs +++ b/clippy_lints/src/loops/iter_next_loop.rs @@ -3,7 +3,7 @@ use crate::utils::span_lint; use rustc_hir::Expr; use rustc_lint::LateContext; -pub(super) fn lint(cx: &LateContext<'_>, expr: &Expr<'_>) { +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { span_lint( cx, ITER_NEXT_LOOP, diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs index efacda772848f..3d3ae6f3152a3 100644 --- a/clippy_lints/src/loops/manual_flatten.rs +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -9,7 +9,7 @@ use rustc_span::source_map::Span; /// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the /// iterator element is used. -pub(super) fn check_manual_flatten<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs index e3080d9f556a3..bf0b8cc24594c 100644 --- a/clippy_lints/src/loops/manual_memcpy.rs +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -15,7 +15,7 @@ use std::iter::Iterator; /// Checks for for loops that sequentially copy items from one slice-like /// object to another. -pub(super) fn detect_manual_memcpy<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 0d408698fc96b..5c96128c6a456 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -559,24 +559,24 @@ impl<'tcx> LateLintPass<'tcx> for Loops { } // check for never_loop - never_loop::check_never_loop(cx, expr); + never_loop::check(cx, expr); // check for `loop { if let {} else break }` that could be `while let` // (also matches an explicit "match" instead of "if let") // (even if the "match" or "if let" is used for declaration) if let ExprKind::Loop(ref block, _, LoopSource::Loop, _) = expr.kind { // also check for empty `loop {}` statements, skipping those in #[panic_handler] - empty_loop::check_empty_loop(cx, expr, block); - while_let_loop::check_while_let_loop(cx, expr, block); + empty_loop::check(cx, expr, block); + while_let_loop::check(cx, expr, block); } - while_let_on_iterator::check_while_let_on_iterator(cx, expr); + while_let_on_iterator::check(cx, expr); if let Some((cond, body)) = higher::while_loop(&expr) { - while_immutable_condition::check_infinite_loop(cx, cond, body); + while_immutable_condition::check(cx, cond, body); } - needless_collect::check_needless_collect(expr, cx); + needless_collect::check(expr, cx); } } @@ -588,17 +588,17 @@ fn check_for_loop<'tcx>( expr: &'tcx Expr<'_>, span: Span, ) { - let is_manual_memcpy_triggered = manual_memcpy::detect_manual_memcpy(cx, pat, arg, body, expr); + let is_manual_memcpy_triggered = manual_memcpy::check(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { - needless_range_loop::check_for_loop_range(cx, pat, arg, body, expr); - explicit_counter_loop::check_for_loop_explicit_counter(cx, pat, arg, body, expr); + needless_range_loop::check(cx, pat, arg, body, expr); + explicit_counter_loop::check(cx, pat, arg, body, expr); } check_for_loop_arg(cx, pat, arg, expr); - for_kv_map::check_for_loop_over_map_kv(cx, pat, arg, body, expr); - mut_range_bound::check_for_mut_range_bound(cx, arg, body); - single_element_loop::check_for_single_element_loop(cx, pat, arg, body, expr); - same_item_push::detect_same_item_push(cx, pat, arg, body, expr); - manual_flatten::check_manual_flatten(cx, pat, arg, body, span); + for_kv_map::check(cx, pat, arg, body, expr); + mut_range_bound::check(cx, arg, body); + single_element_loop::check(cx, pat, arg, body, expr); + same_item_push::check(cx, pat, arg, body, expr); + manual_flatten::check(cx, pat, arg, body, span); } fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { @@ -610,13 +610,13 @@ fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x if method_name == "iter" || method_name == "iter_mut" { if is_ref_iterable_type(cx, &args[0]) { - explicit_iter_loop::lint_iter_method(cx, args, arg, method_name); + explicit_iter_loop::check(cx, args, arg, method_name); } } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { let receiver_ty = cx.typeck_results().expr_ty(&args[0]); let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); if TyS::same_type(receiver_ty, receiver_ty_adjusted) { - explicit_into_iter_loop::check_explicit_into_iter_loop(cx, args, arg); + explicit_into_iter_loop::check(cx, args, arg); } else { let ref_receiver_ty = cx.tcx.mk_ref( cx.tcx.lifetimes.re_erased, @@ -626,17 +626,17 @@ fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: }, ); if TyS::same_type(receiver_ty_adjusted, ref_receiver_ty) { - explicit_iter_loop::lint_iter_method(cx, args, arg, method_name) + explicit_iter_loop::check(cx, args, arg, method_name) } } } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { - iter_next_loop::lint(cx, expr); + iter_next_loop::check(cx, expr); next_loop_linted = true; } } } if !next_loop_linted { - for_loops_over_fallibles::check_arg_type(cx, pat, arg); + for_loops_over_fallibles::check(cx, pat, arg); } } diff --git a/clippy_lints/src/loops/mut_range_bound.rs b/clippy_lints/src/loops/mut_range_bound.rs index 9f31617edeb5e..3ae592950f13b 100644 --- a/clippy_lints/src/loops/mut_range_bound.rs +++ b/clippy_lints/src/loops/mut_range_bound.rs @@ -8,7 +8,7 @@ use rustc_middle::ty; use rustc_span::source_map::Span; use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; -pub(super) fn check_for_mut_range_bound(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) { +pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) { if let Some(higher::Range { start: Some(start), end: Some(end), diff --git a/clippy_lints/src/loops/needless_collect.rs b/clippy_lints/src/loops/needless_collect.rs index d1ce055445b50..6f27130910550 100644 --- a/clippy_lints/src/loops/needless_collect.rs +++ b/clippy_lints/src/loops/needless_collect.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::{sym, Ident}; const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; -pub(super) fn check_needless_collect<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { +pub(super) fn check<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { check_needless_collect_direct_usage(expr, cx); check_needless_collect_indirect_usage(expr, cx); } diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs index ee275bc5bd665..5f02e4b9d875d 100644 --- a/clippy_lints/src/loops/needless_range_loop.rs +++ b/clippy_lints/src/loops/needless_range_loop.rs @@ -21,7 +21,7 @@ use std::mem; /// Checks for looping over a range and then indexing a sequence with it. /// The iteratee must be a range literal. #[allow(clippy::too_many_lines)] -pub(super) fn check_for_loop_range<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index d51ff81103fd4..45e1001d75555 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -4,7 +4,7 @@ use rustc_hir::{Block, Expr, ExprKind, HirId, InlineAsmOperand, Stmt, StmtKind}; use rustc_lint::LateContext; use std::iter::{once, Iterator}; -pub(super) fn check_never_loop(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Loop(ref block, _, _, _) = expr.kind { match never_loop_block(block, expr.hir_id) { NeverLoopResult::AlwaysBreak => span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops"), diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs index c1d5f8b7186b0..f3585830e4ae3 100644 --- a/clippy_lints/src/loops/same_item_push.rs +++ b/clippy_lints/src/loops/same_item_push.rs @@ -10,7 +10,7 @@ use rustc_span::symbol::sym; use std::iter::Iterator; /// Detects for loop pushing the same item into a Vec -pub(super) fn detect_same_item_push<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, _: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/single_element_loop.rs b/clippy_lints/src/loops/single_element_loop.rs index 9e2697186db71..38400c93c9ab2 100644 --- a/clippy_lints/src/loops/single_element_loop.rs +++ b/clippy_lints/src/loops/single_element_loop.rs @@ -5,7 +5,7 @@ use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind}; use rustc_lint::LateContext; -pub(super) fn check_for_single_element_loop<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, diff --git a/clippy_lints/src/loops/while_immutable_condition.rs b/clippy_lints/src/loops/while_immutable_condition.rs index 42e6551b6817e..05e0a7225631c 100644 --- a/clippy_lints/src/loops/while_immutable_condition.rs +++ b/clippy_lints/src/loops/while_immutable_condition.rs @@ -11,7 +11,7 @@ use rustc_lint::LateContext; use rustc_middle::hir::map::Map; use std::iter::Iterator; -pub(super) fn check_infinite_loop<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { if constant(cx, cx.typeck_results(), cond).is_some() { // A pure constant condition (e.g., `while false`) is not linted. return; diff --git a/clippy_lints/src/loops/while_let_loop.rs b/clippy_lints/src/loops/while_let_loop.rs index 0c95798696457..65d8f2f1111a3 100644 --- a/clippy_lints/src/loops/while_let_loop.rs +++ b/clippy_lints/src/loops/while_let_loop.rs @@ -5,7 +5,7 @@ use rustc_hir::{Block, Expr, ExprKind, MatchSource, StmtKind}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; -pub(super) fn check_while_let_loop(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) { +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) { // extract the expression from the first statement (if any) in a block let inner_stmt_expr = extract_expr_from_first_stmt(loop_block); // or extract the first expression (if any) from the block diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index 090c8ceba9744..e5a47694faa4e 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -14,7 +14,7 @@ use rustc_middle::hir::map::Map; use rustc_span::symbol::sym; -pub(super) fn check_while_let_on_iterator(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Match(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.kind { let pat = &arms[0].pat.kind; if let ( From 74bd806b05b16528ff773e469145df215760a88b Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 2 Mar 2021 12:41:06 +0900 Subject: [PATCH 075/226] Simplify check_for_loop_arg --- .../src/loops/explicit_into_iter_loop.rs | 11 +++- clippy_lints/src/loops/explicit_iter_loop.rs | 57 +++++++++++++++- clippy_lints/src/loops/iter_next_loop.rs | 23 ++++--- clippy_lints/src/loops/mod.rs | 66 ++++--------------- 4 files changed, 90 insertions(+), 67 deletions(-) diff --git a/clippy_lints/src/loops/explicit_into_iter_loop.rs b/clippy_lints/src/loops/explicit_into_iter_loop.rs index f89c4b8510363..1d778205a2ad1 100644 --- a/clippy_lints/src/loops/explicit_into_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_into_iter_loop.rs @@ -3,10 +3,17 @@ use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; +use rustc_middle::ty::TyS; + +pub(super) fn check(cx: &LateContext<'_>, args: &'hir [Expr<'hir>], arg: &Expr<'_>) { + let receiver_ty = cx.typeck_results().expr_ty(&args[0]); + let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); + if !TyS::same_type(receiver_ty, receiver_ty_adjusted) { + return; + } -pub(super) fn check(cx: &LateContext<'_>, method_args: &'hir [Expr<'hir>], arg: &Expr<'_>) { let mut applicability = Applicability::MachineApplicable; - let object = snippet_with_applicability(cx, method_args[0].span, "_", &mut applicability); + let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); span_lint_and_sugg( cx, EXPLICIT_INTO_ITER_LOOP, diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index 0836054796a6e..44d0891689105 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -1,10 +1,35 @@ use super::EXPLICIT_ITER_LOOP; -use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; +use crate::utils::{match_trait_method, snippet_with_applicability, span_lint_and_sugg}; use rustc_errors::Applicability; -use rustc_hir::Expr; +use rustc_hir::{Expr, Mutability}; use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty, TyS}; +use rustc_span::symbol::sym; + +use crate::utils::{is_type_diagnostic_item, match_type, paths}; pub(super) fn check(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { + let should_lint = match method_name { + "iter" | "iter_mut" => is_ref_iterable_type(cx, &args[0]), + "into_iter" if match_trait_method(cx, arg, &paths::INTO_ITERATOR) => { + let receiver_ty = cx.typeck_results().expr_ty(&args[0]); + let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); + let ref_receiver_ty = cx.tcx.mk_ref( + cx.tcx.lifetimes.re_erased, + ty::TypeAndMut { + ty: receiver_ty, + mutbl: Mutability::Not, + }, + ); + TyS::same_type(receiver_ty_adjusted, ref_receiver_ty) + }, + _ => false, + }; + + if !should_lint { + return; + } + let mut applicability = Applicability::MachineApplicable; let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); let muta = if method_name == "iter_mut" { "mut " } else { "" }; @@ -19,3 +44,31 @@ pub(super) fn check(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, met applicability, ) } + +/// Returns `true` if the type of expr is one that provides `IntoIterator` impls +/// for `&T` and `&mut T`, such as `Vec`. +#[rustfmt::skip] +fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { + // no walk_ptrs_ty: calling iter() on a reference can make sense because it + // will allow further borrows afterwards + let ty = cx.typeck_results().expr_ty(e); + is_iterable_array(ty, cx) || + is_type_diagnostic_item(cx, ty, sym::vec_type) || + match_type(cx, ty, &paths::LINKED_LIST) || + is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || + is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || + is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + match_type(cx, ty, &paths::BINARY_HEAP) || + match_type(cx, ty, &paths::BTREEMAP) || + match_type(cx, ty, &paths::BTREESET) +} + +fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { + // IntoIterator is currently only implemented for array sizes <= 32 in rustc + match ty.kind() { + ty::Array(_, n) => n + .try_eval_usize(cx.tcx, cx.param_env) + .map_or(false, |val| (0..=32).contains(&val)), + _ => false, + } +} diff --git a/clippy_lints/src/loops/iter_next_loop.rs b/clippy_lints/src/loops/iter_next_loop.rs index cb9916deb62b4..cf78bbc49a362 100644 --- a/clippy_lints/src/loops/iter_next_loop.rs +++ b/clippy_lints/src/loops/iter_next_loop.rs @@ -1,14 +1,19 @@ use super::ITER_NEXT_LOOP; -use crate::utils::span_lint; +use crate::utils::{match_trait_method, paths, span_lint}; use rustc_hir::Expr; use rustc_lint::LateContext; -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { - span_lint( - cx, - ITER_NEXT_LOOP, - expr.span, - "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ - probably not what you want", - ); +pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, expr: &Expr<'_>) -> bool { + if match_trait_method(cx, arg, &paths::ITERATOR) { + span_lint( + cx, + ITER_NEXT_LOOP, + expr.span, + "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ + probably not what you want", + ); + true + } else { + false + } } diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 5c96128c6a456..2a372c6307eab 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -18,13 +18,11 @@ mod while_immutable_condition; mod while_let_loop; mod while_let_on_iterator; -use crate::utils::{higher, is_type_diagnostic_item, match_trait_method, match_type, paths}; -use rustc_hir::{Expr, ExprKind, LoopSource, Mutability, Pat}; +use crate::utils::higher; +use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, Ty, TyS}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; -use rustc_span::symbol::sym; use utils::{get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor, InitializeVisitor}; declare_clippy_lint! { @@ -603,67 +601,27 @@ fn check_for_loop<'tcx>( fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used + if let ExprKind::MethodCall(ref method, _, ref args, _) = arg.kind { // just the receiver, no arguments if args.len() == 1 { let method_name = &*method.ident.as_str(); // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x - if method_name == "iter" || method_name == "iter_mut" { - if is_ref_iterable_type(cx, &args[0]) { + match method_name { + "iter" | "iter_mut" => explicit_iter_loop::check(cx, args, arg, method_name), + "into_iter" => { explicit_iter_loop::check(cx, args, arg, method_name); - } - } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { - let receiver_ty = cx.typeck_results().expr_ty(&args[0]); - let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); - if TyS::same_type(receiver_ty, receiver_ty_adjusted) { explicit_into_iter_loop::check(cx, args, arg); - } else { - let ref_receiver_ty = cx.tcx.mk_ref( - cx.tcx.lifetimes.re_erased, - ty::TypeAndMut { - ty: receiver_ty, - mutbl: Mutability::Not, - }, - ); - if TyS::same_type(receiver_ty_adjusted, ref_receiver_ty) { - explicit_iter_loop::check(cx, args, arg, method_name) - } - } - } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { - iter_next_loop::check(cx, expr); - next_loop_linted = true; + }, + "next" => { + next_loop_linted = iter_next_loop::check(cx, arg, expr); + }, + _ => {}, } } } + if !next_loop_linted { for_loops_over_fallibles::check(cx, pat, arg); } } - -/// Returns `true` if the type of expr is one that provides `IntoIterator` impls -/// for `&T` and `&mut T`, such as `Vec`. -#[rustfmt::skip] -fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - // no walk_ptrs_ty: calling iter() on a reference can make sense because it - // will allow further borrows afterwards - let ty = cx.typeck_results().expr_ty(e); - is_iterable_array(ty, cx) || - is_type_diagnostic_item(cx, ty, sym::vec_type) || - match_type(cx, ty, &paths::LINKED_LIST) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || - is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || - match_type(cx, ty, &paths::BINARY_HEAP) || - match_type(cx, ty, &paths::BTREEMAP) || - match_type(cx, ty, &paths::BTREESET) -} - -fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { - // IntoIterator is currently only implemented for array sizes <= 32 in rustc - match ty.kind() { - ty::Array(_, n) => n - .try_eval_usize(cx.tcx, cx.param_env) - .map_or(false, |val| (0..=32).contains(&val)), - _ => false, - } -} From 306545ff9653a8e1d00c4f381c8e609d3ad49adb Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Wed, 10 Feb 2021 22:59:08 +0900 Subject: [PATCH 076/226] Create transmute directory --- clippy_lints/src/{transmute.rs => transmute/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clippy_lints/src/{transmute.rs => transmute/mod.rs} (100%) diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute/mod.rs similarity index 100% rename from clippy_lints/src/transmute.rs rename to clippy_lints/src/transmute/mod.rs From 4ac438bfed36c1de307cac0f86d8d4938157ac50 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Wed, 10 Feb 2021 23:15:06 +0900 Subject: [PATCH 077/226] Add transmute/utils.rs --- clippy_lints/src/transmute/mod.rs | 110 ++-------------------------- clippy_lints/src/transmute/utils.rs | 109 +++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 103 deletions(-) create mode 100644 clippy_lints/src/transmute/utils.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index dc938ed02383d..0258244a07bad 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,16 +1,16 @@ +mod utils; +use utils::*; + use crate::utils::{ - in_constant, is_normalizable, last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_sugg, - span_lint_and_then, sugg, + in_constant, match_def_path, paths, snippet, span_lint, span_lint_and_sugg, span_lint_and_then, sugg, }; use if_chain::if_chain; use rustc_ast as ast; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, TyKind, UnOp}; +use rustc_hir::{Expr, ExprKind, Mutability, UnOp}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, cast::CastKind, Ty}; +use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::DUMMY_SP; -use rustc_typeck::check::{cast::CastCheck, FnCtxt, Inherited}; use std::borrow::Cow; declare_clippy_lint! { @@ -326,6 +326,7 @@ static COLLECTIONS: &[&[&str]] = &[ &paths::HASHSET, &paths::HASHMAP, ]; + impl<'tcx> LateLintPass<'tcx> for Transmute { #[allow(clippy::similar_names, clippy::too_many_lines)] fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { @@ -664,100 +665,3 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { } } } - -/// Gets the snippet of `Bar` in `…::transmute`. If that snippet is -/// not available , use -/// the type's `ToString` implementation. In weird cases it could lead to types -/// with invalid `'_` -/// lifetime, but it should be rare. -fn get_type_snippet(cx: &LateContext<'_>, path: &QPath<'_>, to_ref_ty: Ty<'_>) -> String { - let seg = last_path_segment(path); - if_chain! { - if let Some(ref params) = seg.args; - if !params.parenthesized; - if let Some(to_ty) = params.args.iter().filter_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty), - _ => None, - }).nth(1); - if let TyKind::Rptr(_, ref to_ty) = to_ty.kind; - then { - return snippet(cx, to_ty.ty.span, &to_ref_ty.to_string()).to_string(); - } - } - - to_ref_ty.to_string() -} - -// check if the component types of the transmuted collection and the result have different ABI, -// size or alignment -fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool { - let empty_param_env = ty::ParamEnv::empty(); - // check if `from` and `to` are normalizable to avoid ICE (#4968) - if !(is_normalizable(cx, empty_param_env, from) && is_normalizable(cx, empty_param_env, to)) { - return false; - } - let from_ty_layout = cx.tcx.layout_of(empty_param_env.and(from)); - let to_ty_layout = cx.tcx.layout_of(empty_param_env.and(to)); - if let (Ok(from_layout), Ok(to_layout)) = (from_ty_layout, to_ty_layout) { - from_layout.size != to_layout.size || from_layout.align != to_layout.align || from_layout.abi != to_layout.abi - } else { - // no idea about layout, so don't lint - false - } -} - -/// Check if the type conversion can be expressed as a pointer cast, instead of -/// a transmute. In certain cases, including some invalid casts from array -/// references to pointers, this may cause additional errors to be emitted and/or -/// ICE error messages. This function will panic if that occurs. -fn can_be_expressed_as_pointer_cast<'tcx>( - cx: &LateContext<'tcx>, - e: &'tcx Expr<'_>, - from_ty: Ty<'tcx>, - to_ty: Ty<'tcx>, -) -> bool { - use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast}; - matches!( - check_cast(cx, e, from_ty, to_ty), - Some(PtrPtrCast | PtrAddrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) - ) -} - -/// If a cast from `from_ty` to `to_ty` is valid, returns an Ok containing the kind of -/// the cast. In certain cases, including some invalid casts from array references -/// to pointers, this may cause additional errors to be emitted and/or ICE error -/// messages. This function will panic if that occurs. -fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> Option { - let hir_id = e.hir_id; - let local_def_id = hir_id.owner; - - Inherited::build(cx.tcx, local_def_id).enter(|inherited| { - let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, hir_id); - - // If we already have errors, we can't be sure we can pointer cast. - assert!( - !fn_ctxt.errors_reported_since_creation(), - "Newly created FnCtxt contained errors" - ); - - if let Ok(check) = CastCheck::new( - &fn_ctxt, e, from_ty, to_ty, - // We won't show any error to the user, so we don't care what the span is here. - DUMMY_SP, DUMMY_SP, - ) { - let res = check.do_check(&fn_ctxt); - - // do_check's documentation says that it might return Ok and create - // errors in the fcx instead of returing Err in some cases. Those cases - // should be filtered out before getting here. - assert!( - !fn_ctxt.errors_reported_since_creation(), - "`fn_ctxt` contained errors after cast check!" - ); - - res.ok() - } else { - None - } - }) -} diff --git a/clippy_lints/src/transmute/utils.rs b/clippy_lints/src/transmute/utils.rs new file mode 100644 index 0000000000000..734a92d50d2ad --- /dev/null +++ b/clippy_lints/src/transmute/utils.rs @@ -0,0 +1,109 @@ +use crate::utils::{is_normalizable, last_path_segment, snippet}; +use if_chain::if_chain; +use rustc_hir::{Expr, GenericArg, QPath, TyKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, cast::CastKind, Ty}; +use rustc_span::DUMMY_SP; +use rustc_typeck::check::{cast::CastCheck, FnCtxt, Inherited}; + +/// Gets the snippet of `Bar` in `…::transmute`. If that snippet is +/// not available , use +/// the type's `ToString` implementation. In weird cases it could lead to types +/// with invalid `'_` +/// lifetime, but it should be rare. +pub(super) fn get_type_snippet(cx: &LateContext<'_>, path: &QPath<'_>, to_ref_ty: Ty<'_>) -> String { + let seg = last_path_segment(path); + if_chain! { + if let Some(ref params) = seg.args; + if !params.parenthesized; + if let Some(to_ty) = params.args.iter().filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + _ => None, + }).nth(1); + if let TyKind::Rptr(_, ref to_ty) = to_ty.kind; + then { + return snippet(cx, to_ty.ty.span, &to_ref_ty.to_string()).to_string(); + } + } + + to_ref_ty.to_string() +} + +// check if the component types of the transmuted collection and the result have different ABI, +// size or alignment +pub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool { + let empty_param_env = ty::ParamEnv::empty(); + // check if `from` and `to` are normalizable to avoid ICE (#4968) + if !(is_normalizable(cx, empty_param_env, from) && is_normalizable(cx, empty_param_env, to)) { + return false; + } + let from_ty_layout = cx.tcx.layout_of(empty_param_env.and(from)); + let to_ty_layout = cx.tcx.layout_of(empty_param_env.and(to)); + if let (Ok(from_layout), Ok(to_layout)) = (from_ty_layout, to_ty_layout) { + from_layout.size != to_layout.size || from_layout.align != to_layout.align || from_layout.abi != to_layout.abi + } else { + // no idea about layout, so don't lint + false + } +} + +/// Check if the type conversion can be expressed as a pointer cast, instead of +/// a transmute. In certain cases, including some invalid casts from array +/// references to pointers, this may cause additional errors to be emitted and/or +/// ICE error messages. This function will panic if that occurs. +pub(super) fn can_be_expressed_as_pointer_cast<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, +) -> bool { + use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast}; + matches!( + check_cast(cx, e, from_ty, to_ty), + Some(PtrPtrCast | PtrAddrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) + ) +} + +/// If a cast from `from_ty` to `to_ty` is valid, returns an Ok containing the kind of +/// the cast. In certain cases, including some invalid casts from array references +/// to pointers, this may cause additional errors to be emitted and/or ICE error +/// messages. This function will panic if that occurs. +pub(super) fn check_cast<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, +) -> Option { + let hir_id = e.hir_id; + let local_def_id = hir_id.owner; + + Inherited::build(cx.tcx, local_def_id).enter(|inherited| { + let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, hir_id); + + // If we already have errors, we can't be sure we can pointer cast. + assert!( + !fn_ctxt.errors_reported_since_creation(), + "Newly created FnCtxt contained errors" + ); + + if let Ok(check) = CastCheck::new( + &fn_ctxt, e, from_ty, to_ty, + // We won't show any error to the user, so we don't care what the span is here. + DUMMY_SP, DUMMY_SP, + ) { + let res = check.do_check(&fn_ctxt); + + // do_check's documentation says that it might return Ok and create + // errors in the fcx instead of returing Err in some cases. Those cases + // should be filtered out before getting here. + assert!( + !fn_ctxt.errors_reported_since_creation(), + "`fn_ctxt` contained errors after cast check!" + ); + + res.ok() + } else { + None + } + }) +} From 0d7dd00860e5a2b8b7c7a34daaa5553ff2e542f3 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Wed, 10 Feb 2021 23:54:11 +0900 Subject: [PATCH 078/226] Move useless_transmute to its own module --- clippy_lints/src/transmute/mod.rs | 51 ++----------- .../src/transmute/useless_transmute.rs | 74 +++++++++++++++++++ 2 files changed, 81 insertions(+), 44 deletions(-) create mode 100644 clippy_lints/src/transmute/useless_transmute.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 0258244a07bad..4897934376f1c 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,4 +1,6 @@ +mod useless_transmute; mod utils; + use utils::*; use crate::utils::{ @@ -344,51 +346,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { let from_ty = cx.typeck_results().expr_ty(&args[0]); let to_ty = cx.typeck_results().expr_ty(e); - match (&from_ty.kind(), &to_ty.kind()) { - _ if from_ty == to_ty => span_lint( - cx, - USELESS_TRANSMUTE, - e.span, - &format!("transmute from a type (`{}`) to itself", from_ty), - ), - (ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty)) => span_lint_and_then( - cx, - USELESS_TRANSMUTE, - e.span, - "transmute from a reference to a pointer", - |diag| { - if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - let rty_and_mut = ty::TypeAndMut { - ty: rty, - mutbl: *rty_mutbl, - }; - - let sugg = if *ptr_ty == rty_and_mut { - arg.as_ty(to_ty) - } else { - arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty) - }; + let triggered = useless_transmute::check(cx, e, from_ty, to_ty, args); + if triggered { + return; + } - diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified); - } - }, - ), - (ty::Int(_) | ty::Uint(_), ty::RawPtr(_)) => span_lint_and_then( - cx, - USELESS_TRANSMUTE, - e.span, - "transmute from an integer to a pointer", - |diag| { - if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - diag.span_suggestion( - e.span, - "try", - arg.as_ty(&to_ty.to_string()).to_string(), - Applicability::Unspecified, - ); - } - }, - ), + match (&from_ty.kind(), &to_ty.kind()) { (ty::Float(_) | ty::Char, ty::Ref(..) | ty::RawPtr(_)) => span_lint( cx, WRONG_TRANSMUTE, diff --git a/clippy_lints/src/transmute/useless_transmute.rs b/clippy_lints/src/transmute/useless_transmute.rs new file mode 100644 index 0000000000000..86d75fd2ee0b0 --- /dev/null +++ b/clippy_lints/src/transmute/useless_transmute.rs @@ -0,0 +1,74 @@ +use super::USELESS_TRANSMUTE; +use crate::utils::{span_lint, span_lint_and_then, sugg}; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `useless_transmute` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], +) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + _ if from_ty == to_ty => { + span_lint( + cx, + USELESS_TRANSMUTE, + e.span, + &format!("transmute from a type (`{}`) to itself", from_ty), + ); + true + }, + (ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty)) => { + span_lint_and_then( + cx, + USELESS_TRANSMUTE, + e.span, + "transmute from a reference to a pointer", + |diag| { + if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + let rty_and_mut = ty::TypeAndMut { + ty: rty, + mutbl: *rty_mutbl, + }; + + let sugg = if *ptr_ty == rty_and_mut { + arg.as_ty(to_ty) + } else { + arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty) + }; + + diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified); + } + }, + ); + true + }, + (ty::Int(_) | ty::Uint(_), ty::RawPtr(_)) => { + span_lint_and_then( + cx, + USELESS_TRANSMUTE, + e.span, + "transmute from an integer to a pointer", + |diag| { + if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + diag.span_suggestion( + e.span, + "try", + arg.as_ty(&to_ty.to_string()).to_string(), + Applicability::Unspecified, + ); + } + }, + ); + true + }, + _ => false, + } +} From ef97764dcc45493eebe0332acf4b2410583af5e4 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Wed, 10 Feb 2021 23:57:56 +0900 Subject: [PATCH 079/226] Move wrong_transmute to its own module --- clippy_lints/src/transmute/mod.rs | 11 ++++----- clippy_lints/src/transmute/wrong_transmute.rs | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 clippy_lints/src/transmute/wrong_transmute.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 4897934376f1c..09e0fe257a5ee 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,5 +1,6 @@ mod useless_transmute; mod utils; +mod wrong_transmute; use utils::*; @@ -350,14 +351,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = wrong_transmute::check(cx, e, from_ty, to_ty); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::Float(_) | ty::Char, ty::Ref(..) | ty::RawPtr(_)) => span_lint( - cx, - WRONG_TRANSMUTE, - e.span, - &format!("transmute from a `{}` to a pointer", from_ty), - ), (ty::RawPtr(from_ptr), _) if from_ptr.ty == to_ty => span_lint( cx, CROSSPOINTER_TRANSMUTE, diff --git a/clippy_lints/src/transmute/wrong_transmute.rs b/clippy_lints/src/transmute/wrong_transmute.rs new file mode 100644 index 0000000000000..d2d3f0a9c8902 --- /dev/null +++ b/clippy_lints/src/transmute/wrong_transmute.rs @@ -0,0 +1,23 @@ +use super::WRONG_TRANSMUTE; +use crate::utils::span_lint; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `wrong_transmute` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::Float(_) | ty::Char, ty::Ref(..) | ty::RawPtr(_)) => { + span_lint( + cx, + WRONG_TRANSMUTE, + e.span, + &format!("transmute from a `{}` to a pointer", from_ty), + ); + true + }, + _ => false, + } +} From afc9275928905d2142da027815aac67b81d0a89b Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 00:02:21 +0900 Subject: [PATCH 080/226] Move crosspointer_transmute to its own module --- .../src/transmute/crosspointer_transmute.rs | 38 +++++++++++++++++++ clippy_lints/src/transmute/mod.rs | 23 +++-------- 2 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 clippy_lints/src/transmute/crosspointer_transmute.rs diff --git a/clippy_lints/src/transmute/crosspointer_transmute.rs b/clippy_lints/src/transmute/crosspointer_transmute.rs new file mode 100644 index 0000000000000..b570bb3a396e4 --- /dev/null +++ b/clippy_lints/src/transmute/crosspointer_transmute.rs @@ -0,0 +1,38 @@ +use super::CROSSPOINTER_TRANSMUTE; +use crate::utils::span_lint; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `crosspointer_transmute` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::RawPtr(from_ptr), _) if from_ptr.ty == to_ty => { + span_lint( + cx, + CROSSPOINTER_TRANSMUTE, + e.span, + &format!( + "transmute from a type (`{}`) to the type that it points to (`{}`)", + from_ty, to_ty + ), + ); + true + }, + (_, ty::RawPtr(to_ptr)) if to_ptr.ty == from_ty => { + span_lint( + cx, + CROSSPOINTER_TRANSMUTE, + e.span, + &format!( + "transmute from a type (`{}`) to a pointer to that type (`{}`)", + from_ty, to_ty + ), + ); + true + }, + _ => false, + } +} diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 09e0fe257a5ee..7e05771c8851c 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,3 +1,4 @@ +mod crosspointer_transmute; mod useless_transmute; mod utils; mod wrong_transmute; @@ -355,26 +356,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = crosspointer_transmute::check(cx, e, from_ty, to_ty); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::RawPtr(from_ptr), _) if from_ptr.ty == to_ty => span_lint( - cx, - CROSSPOINTER_TRANSMUTE, - e.span, - &format!( - "transmute from a type (`{}`) to the type that it points to (`{}`)", - from_ty, to_ty - ), - ), - (_, ty::RawPtr(to_ptr)) if to_ptr.ty == from_ty => span_lint( - cx, - CROSSPOINTER_TRANSMUTE, - e.span, - &format!( - "transmute from a type (`{}`) to a pointer to that type (`{}`)", - from_ty, to_ty - ), - ), (ty::RawPtr(from_pty), ty::Ref(_, to_ref_ty, mutbl)) => span_lint_and_then( cx, TRANSMUTE_PTR_TO_REF, From 6442d45d3a55cee14ccee14c004ea344072d54cd Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 00:10:19 +0900 Subject: [PATCH 081/226] Move transmute_ptr_to_ref to its own module --- clippy_lints/src/transmute/mod.rs | 36 ++---------- .../src/transmute/transmute_ptr_to_ref.rs | 56 +++++++++++++++++++ 2 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 clippy_lints/src/transmute/transmute_ptr_to_ref.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 7e05771c8851c..f00cb9b935c23 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,4 +1,5 @@ mod crosspointer_transmute; +mod transmute_ptr_to_ref; mod useless_transmute; mod utils; mod wrong_transmute; @@ -360,39 +361,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, args, qpath); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::RawPtr(from_pty), ty::Ref(_, to_ref_ty, mutbl)) => span_lint_and_then( - cx, - TRANSMUTE_PTR_TO_REF, - e.span, - &format!( - "transmute from a pointer type (`{}`) to a reference type \ - (`{}`)", - from_ty, to_ty - ), - |diag| { - let arg = sugg::Sugg::hir(cx, &args[0], ".."); - let (deref, cast) = if *mutbl == Mutability::Mut { - ("&mut *", "*mut") - } else { - ("&*", "*const") - }; - - let arg = if from_pty.ty == *to_ref_ty { - arg - } else { - arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_ref_ty))) - }; - - diag.span_suggestion( - e.span, - "try", - sugg::make_unop(deref, arg).to_string(), - Applicability::Unspecified, - ); - }, - ), (ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => { span_lint_and_then( cx, diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs new file mode 100644 index 0000000000000..7be47da35dac7 --- /dev/null +++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -0,0 +1,56 @@ +use super::utils::get_type_snippet; +use super::TRANSMUTE_PTR_TO_REF; +use crate::utils::{span_lint_and_then, sugg}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, Mutability, QPath}; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `transmute_ptr_to_ref` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], + qpath: &'tcx QPath<'_>, +) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::RawPtr(from_pty), ty::Ref(_, to_ref_ty, mutbl)) => { + span_lint_and_then( + cx, + TRANSMUTE_PTR_TO_REF, + e.span, + &format!( + "transmute from a pointer type (`{}`) to a reference type (`{}`)", + from_ty, to_ty + ), + |diag| { + let arg = sugg::Sugg::hir(cx, &args[0], ".."); + let (deref, cast) = if *mutbl == Mutability::Mut { + ("&mut *", "*mut") + } else { + ("&*", "*const") + }; + + let arg = if from_pty.ty == *to_ref_ty { + arg + } else { + arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_ref_ty))) + }; + + diag.span_suggestion( + e.span, + "try", + sugg::make_unop(deref, arg).to_string(), + Applicability::Unspecified, + ); + }, + ); + true + }, + _ => false, + } +} From 4c6522118802b5fd98337eeb57d3d81268069385 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 00:18:45 +0900 Subject: [PATCH 082/226] Move transmute_int_to_char to its own module --- clippy_lints/src/transmute/mod.rs | 27 ++--------- .../src/transmute/transmute_int_to_char.rs | 47 +++++++++++++++++++ 2 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 clippy_lints/src/transmute/transmute_int_to_char.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index f00cb9b935c23..376f9bd78c0d3 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,4 +1,5 @@ mod crosspointer_transmute; +mod transmute_int_to_char; mod transmute_ptr_to_ref; mod useless_transmute; mod utils; @@ -365,30 +366,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = transmute_int_to_char::check(cx, e, from_ty, to_ty, args); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => { - span_lint_and_then( - cx, - TRANSMUTE_INT_TO_CHAR, - e.span, - &format!("transmute from a `{}` to a `char`", from_ty), - |diag| { - let arg = sugg::Sugg::hir(cx, &args[0], ".."); - let arg = if let ty::Int(_) = from_ty.kind() { - arg.as_ty(ast::UintTy::U32.name_str()) - } else { - arg - }; - diag.span_suggestion( - e.span, - "consider using", - format!("std::char::from_u32({}).unwrap()", arg.to_string()), - Applicability::Unspecified, - ); - }, - ) - }, (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) => { if_chain! { if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind()); diff --git a/clippy_lints/src/transmute/transmute_int_to_char.rs b/clippy_lints/src/transmute/transmute_int_to_char.rs new file mode 100644 index 0000000000000..179627d9964b2 --- /dev/null +++ b/clippy_lints/src/transmute/transmute_int_to_char.rs @@ -0,0 +1,47 @@ +use super::TRANSMUTE_INT_TO_CHAR; +use crate::utils::{span_lint_and_then, sugg}; +use rustc_ast as ast; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `transmute_int_to_char` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], +) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => { + { + span_lint_and_then( + cx, + TRANSMUTE_INT_TO_CHAR, + e.span, + &format!("transmute from a `{}` to a `char`", from_ty), + |diag| { + let arg = sugg::Sugg::hir(cx, &args[0], ".."); + let arg = if let ty::Int(_) = from_ty.kind() { + arg.as_ty(ast::UintTy::U32.name_str()) + } else { + arg + }; + diag.span_suggestion( + e.span, + "consider using", + format!("std::char::from_u32({}).unwrap()", arg.to_string()), + Applicability::Unspecified, + ); + }, + ) + }; + true + }, + _ => false, + } +} From 7af3458b5458ad99dc900b9fe744f39b9dae449e Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 00:40:57 +0900 Subject: [PATCH 083/226] Move transmute_bytes_to_str and transmute_ptr_to_ptr to transmute_ref_to_ref module --- clippy_lints/src/transmute/mod.rs | 64 ++----------- .../src/transmute/transmute_ref_to_ref.rs | 89 +++++++++++++++++++ 2 files changed, 94 insertions(+), 59 deletions(-) create mode 100644 clippy_lints/src/transmute/transmute_ref_to_ref.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 376f9bd78c0d3..8a0c83789d54f 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,6 +1,7 @@ mod crosspointer_transmute; mod transmute_int_to_char; mod transmute_ptr_to_ref; +mod transmute_ref_to_ref; mod useless_transmute; mod utils; mod wrong_transmute; @@ -370,67 +371,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = transmute_ref_to_ref::check(cx, e, from_ty, to_ty, args, const_context); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) => { - if_chain! { - if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind()); - if let ty::Uint(ty::UintTy::U8) = slice_ty.kind(); - if from_mutbl == to_mutbl; - then { - let postfix = if *from_mutbl == Mutability::Mut { - "_mut" - } else { - "" - }; - - span_lint_and_sugg( - cx, - TRANSMUTE_BYTES_TO_STR, - e.span, - &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), - "consider using", - format!( - "std::str::from_utf8{}({}).unwrap()", - postfix, - snippet(cx, args[0].span, ".."), - ), - Applicability::Unspecified, - ); - } else { - if (cx.tcx.erase_regions(from_ty) != cx.tcx.erase_regions(to_ty)) - && !const_context { - span_lint_and_then( - cx, - TRANSMUTE_PTR_TO_PTR, - e.span, - "transmute from a reference to a reference", - |diag| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - let ty_from_and_mut = ty::TypeAndMut { - ty: ty_from, - mutbl: *from_mutbl - }; - let ty_to_and_mut = ty::TypeAndMut { ty: ty_to, mutbl: *to_mutbl }; - let sugg_paren = arg - .as_ty(cx.tcx.mk_ptr(ty_from_and_mut)) - .as_ty(cx.tcx.mk_ptr(ty_to_and_mut)); - let sugg = if *to_mutbl == Mutability::Mut { - sugg_paren.mut_addr_deref() - } else { - sugg_paren.addr_deref() - }; - diag.span_suggestion( - e.span, - "try", - sugg.to_string(), - Applicability::Unspecified, - ); - }, - ) - } - } - } - }, (ty::RawPtr(_), ty::RawPtr(to_ty)) => span_lint_and_then( cx, TRANSMUTE_PTR_TO_PTR, diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs new file mode 100644 index 0000000000000..a9e3385664bdb --- /dev/null +++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -0,0 +1,89 @@ +use super::{TRANSMUTE_BYTES_TO_STR, TRANSMUTE_PTR_TO_PTR}; +use crate::utils::{snippet, span_lint_and_sugg, span_lint_and_then, sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::{Expr, Mutability}; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `transmute_bytes_to_str` and `transmute_ptr_to_ptr` lints. +/// Returns `true` if either one triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], + const_context: bool, +) -> bool { + let mut triggered = false; + + match (&from_ty.kind(), &to_ty.kind()) { + (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) => { + if_chain! { + if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind()); + if let ty::Uint(ty::UintTy::U8) = slice_ty.kind(); + if from_mutbl == to_mutbl; + then { + let postfix = if *from_mutbl == Mutability::Mut { + "_mut" + } else { + "" + }; + + span_lint_and_sugg( + cx, + TRANSMUTE_BYTES_TO_STR, + e.span, + &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), + "consider using", + format!( + "std::str::from_utf8{}({}).unwrap()", + postfix, + snippet(cx, args[0].span, ".."), + ), + Applicability::Unspecified, + ); + triggered = true; + } else { + if (cx.tcx.erase_regions(from_ty) != cx.tcx.erase_regions(to_ty)) + && !const_context { + span_lint_and_then( + cx, + TRANSMUTE_PTR_TO_PTR, + e.span, + "transmute from a reference to a reference", + |diag| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + let ty_from_and_mut = ty::TypeAndMut { + ty: ty_from, + mutbl: *from_mutbl + }; + let ty_to_and_mut = ty::TypeAndMut { ty: ty_to, mutbl: *to_mutbl }; + let sugg_paren = arg + .as_ty(cx.tcx.mk_ptr(ty_from_and_mut)) + .as_ty(cx.tcx.mk_ptr(ty_to_and_mut)); + let sugg = if *to_mutbl == Mutability::Mut { + sugg_paren.mut_addr_deref() + } else { + sugg_paren.addr_deref() + }; + diag.span_suggestion( + e.span, + "try", + sugg.to_string(), + Applicability::Unspecified, + ); + }, + ); + + triggered = true; + } + } + } + }, + _ => {}, + } + + triggered +} From f8bc0e249c532ceacc9897ea08f7b97ecba5408e Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 00:50:09 +0900 Subject: [PATCH 084/226] Move transmute_ptr_to_ptr to its own module --- clippy_lints/src/transmute/mod.rs | 17 +++------ .../src/transmute/transmute_ptr_to_ptr.rs | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 clippy_lints/src/transmute/transmute_ptr_to_ptr.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 8a0c83789d54f..e144c96498bdd 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,5 +1,6 @@ mod crosspointer_transmute; mod transmute_int_to_char; +mod transmute_ptr_to_ptr; mod transmute_ptr_to_ref; mod transmute_ref_to_ref; mod useless_transmute; @@ -375,20 +376,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, args); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::RawPtr(_), ty::RawPtr(to_ty)) => span_lint_and_then( - cx, - TRANSMUTE_PTR_TO_PTR, - e.span, - "transmute from a pointer to a pointer", - |diag| { - if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - let sugg = arg.as_ty(cx.tcx.mk_ptr(*to_ty)); - diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified); - } - }, - ), (ty::Int(ty::IntTy::I8) | ty::Uint(ty::UintTy::U8), ty::Bool) => { span_lint_and_then( cx, diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs new file mode 100644 index 0000000000000..68668ec30db00 --- /dev/null +++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -0,0 +1,36 @@ +use super::TRANSMUTE_PTR_TO_PTR; +use crate::utils::{span_lint_and_then, sugg}; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `transmute_ptr_to_ptr` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], +) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::RawPtr(_), ty::RawPtr(to_ty)) => { + span_lint_and_then( + cx, + TRANSMUTE_PTR_TO_PTR, + e.span, + "transmute from a pointer to a pointer", + |diag| { + if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + let sugg = arg.as_ty(cx.tcx.mk_ptr(*to_ty)); + diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified); + } + }, + ); + true + }, + _ => false, + } +} From d04ea41d1fbf8c60115bf0746fd9756ff17183c2 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 00:55:32 +0900 Subject: [PATCH 085/226] Move transmute_int_to_bool to its own module --- clippy_lints/src/transmute/mod.rs | 23 +++------- .../src/transmute/transmute_int_to_bool.rs | 42 +++++++++++++++++++ 2 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 clippy_lints/src/transmute/transmute_int_to_bool.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index e144c96498bdd..fa9edc9ae2cb4 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,4 +1,5 @@ mod crosspointer_transmute; +mod transmute_int_to_bool; mod transmute_int_to_char; mod transmute_ptr_to_ptr; mod transmute_ptr_to_ref; @@ -380,26 +381,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = transmute_int_to_bool::check(cx, e, from_ty, to_ty, args); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::Int(ty::IntTy::I8) | ty::Uint(ty::UintTy::U8), ty::Bool) => { - span_lint_and_then( - cx, - TRANSMUTE_INT_TO_BOOL, - e.span, - &format!("transmute from a `{}` to a `bool`", from_ty), - |diag| { - let arg = sugg::Sugg::hir(cx, &args[0], ".."); - let zero = sugg::Sugg::NonParen(Cow::from("0")); - diag.span_suggestion( - e.span, - "consider using", - sugg::make_binop(ast::BinOpKind::Ne, &arg, &zero).to_string(), - Applicability::Unspecified, - ); - }, - ) - }, (ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context => span_lint_and_then( cx, TRANSMUTE_INT_TO_FLOAT, diff --git a/clippy_lints/src/transmute/transmute_int_to_bool.rs b/clippy_lints/src/transmute/transmute_int_to_bool.rs new file mode 100644 index 0000000000000..c66c7bff23257 --- /dev/null +++ b/clippy_lints/src/transmute/transmute_int_to_bool.rs @@ -0,0 +1,42 @@ +use super::TRANSMUTE_INT_TO_BOOL; +use crate::utils::{span_lint_and_then, sugg}; +use rustc_ast as ast; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; +use std::borrow::Cow; + +/// Checks for `transmute_int_to_bool` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], +) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::Int(ty::IntTy::I8) | ty::Uint(ty::UintTy::U8), ty::Bool) => { + span_lint_and_then( + cx, + TRANSMUTE_INT_TO_BOOL, + e.span, + &format!("transmute from a `{}` to a `bool`", from_ty), + |diag| { + let arg = sugg::Sugg::hir(cx, &args[0], ".."); + let zero = sugg::Sugg::NonParen(Cow::from("0")); + diag.span_suggestion( + e.span, + "consider using", + sugg::make_binop(ast::BinOpKind::Ne, &arg, &zero).to_string(), + Applicability::Unspecified, + ); + }, + ); + true + }, + _ => false, + } +} From acedc7b8f261e97ea544b7d43a053312e55e6ebf Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 01:03:08 +0900 Subject: [PATCH 086/226] Move transmute_int_to_float to its own module --- clippy_lints/src/transmute/mod.rs | 28 ++--------- .../src/transmute/transmute_int_to_float.rs | 48 +++++++++++++++++++ 2 files changed, 53 insertions(+), 23 deletions(-) create mode 100644 clippy_lints/src/transmute/transmute_int_to_float.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index fa9edc9ae2cb4..6e1207abd524c 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,6 +1,7 @@ mod crosspointer_transmute; mod transmute_int_to_bool; mod transmute_int_to_char; +mod transmute_int_to_float; mod transmute_ptr_to_ptr; mod transmute_ptr_to_ref; mod transmute_ref_to_ref; @@ -385,31 +386,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = transmute_int_to_float::check(cx, e, from_ty, to_ty, args, const_context); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context => span_lint_and_then( - cx, - TRANSMUTE_INT_TO_FLOAT, - e.span, - &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), - |diag| { - let arg = sugg::Sugg::hir(cx, &args[0], ".."); - let arg = if let ty::Int(int_ty) = from_ty.kind() { - arg.as_ty(format!( - "u{}", - int_ty.bit_width().map_or_else(|| "size".to_string(), |v| v.to_string()) - )) - } else { - arg - }; - diag.span_suggestion( - e.span, - "consider using", - format!("{}::from_bits({})", to_ty, arg.to_string()), - Applicability::Unspecified, - ); - }, - ), (ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => span_lint_and_then( cx, TRANSMUTE_FLOAT_TO_INT, diff --git a/clippy_lints/src/transmute/transmute_int_to_float.rs b/clippy_lints/src/transmute/transmute_int_to_float.rs new file mode 100644 index 0000000000000..564a27df562d6 --- /dev/null +++ b/clippy_lints/src/transmute/transmute_int_to_float.rs @@ -0,0 +1,48 @@ +use super::TRANSMUTE_INT_TO_FLOAT; +use crate::utils::{span_lint_and_then, sugg}; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `transmute_int_to_float` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], + const_context: bool, +) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context => { + span_lint_and_then( + cx, + TRANSMUTE_INT_TO_FLOAT, + e.span, + &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), + |diag| { + let arg = sugg::Sugg::hir(cx, &args[0], ".."); + let arg = if let ty::Int(int_ty) = from_ty.kind() { + arg.as_ty(format!( + "u{}", + int_ty.bit_width().map_or_else(|| "size".to_string(), |v| v.to_string()) + )) + } else { + arg + }; + diag.span_suggestion( + e.span, + "consider using", + format!("{}::from_bits({})", to_ty, arg.to_string()), + Applicability::Unspecified, + ); + }, + ); + true + }, + _ => false, + } +} From e7d2393d0182f9837897723e1541c0404bdcd55b Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 01:08:48 +0900 Subject: [PATCH 087/226] Move transmute_float_to_int to its own module --- clippy_lints/src/transmute/mod.rs | 49 ++------------ .../src/transmute/transmute_float_to_int.rs | 66 +++++++++++++++++++ 2 files changed, 71 insertions(+), 44 deletions(-) create mode 100644 clippy_lints/src/transmute/transmute_float_to_int.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 6e1207abd524c..3ba0872393d0d 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -1,4 +1,5 @@ mod crosspointer_transmute; +mod transmute_float_to_int; mod transmute_int_to_bool; mod transmute_int_to_char; mod transmute_int_to_float; @@ -390,52 +391,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = transmute_float_to_int::check(cx, e, from_ty, to_ty, args, const_context); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => span_lint_and_then( - cx, - TRANSMUTE_FLOAT_TO_INT, - e.span, - &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), - |diag| { - let mut expr = &args[0]; - let mut arg = sugg::Sugg::hir(cx, expr, ".."); - - if let ExprKind::Unary(UnOp::Neg, inner_expr) = &expr.kind { - expr = &inner_expr; - } - - if_chain! { - // if the expression is a float literal and it is unsuffixed then - // add a suffix so the suggestion is valid and unambiguous - let op = format!("{}{}", arg, float_ty.name_str()).into(); - if let ExprKind::Lit(lit) = &expr.kind; - if let ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) = lit.node; - then { - match arg { - sugg::Sugg::MaybeParen(_) => arg = sugg::Sugg::MaybeParen(op), - _ => arg = sugg::Sugg::NonParen(op) - } - } - } - - arg = sugg::Sugg::NonParen(format!("{}.to_bits()", arg.maybe_par()).into()); - - // cast the result of `to_bits` if `to_ty` is signed - arg = if let ty::Int(int_ty) = to_ty.kind() { - arg.as_ty(int_ty.name_str().to_string()) - } else { - arg - }; - - diag.span_suggestion( - e.span, - "consider using", - arg.to_string(), - Applicability::Unspecified, - ); - }, - ), (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => { if from_adt.did != to_adt.did || !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) { diff --git a/clippy_lints/src/transmute/transmute_float_to_int.rs b/clippy_lints/src/transmute/transmute_float_to_int.rs new file mode 100644 index 0000000000000..58cd0e217925b --- /dev/null +++ b/clippy_lints/src/transmute/transmute_float_to_int.rs @@ -0,0 +1,66 @@ +use super::TRANSMUTE_FLOAT_TO_INT; +use crate::utils::{span_lint_and_then, sugg}; +use if_chain::if_chain; +use rustc_ast as ast; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, UnOp}; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +/// Checks for `transmute_float_to_int` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], + const_context: bool, +) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => { + span_lint_and_then( + cx, + TRANSMUTE_FLOAT_TO_INT, + e.span, + &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), + |diag| { + let mut expr = &args[0]; + let mut arg = sugg::Sugg::hir(cx, expr, ".."); + + if let ExprKind::Unary(UnOp::Neg, inner_expr) = &expr.kind { + expr = &inner_expr; + } + + if_chain! { + // if the expression is a float literal and it is unsuffixed then + // add a suffix so the suggestion is valid and unambiguous + let op = format!("{}{}", arg, float_ty.name_str()).into(); + if let ExprKind::Lit(lit) = &expr.kind; + if let ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) = lit.node; + then { + match arg { + sugg::Sugg::MaybeParen(_) => arg = sugg::Sugg::MaybeParen(op), + _ => arg = sugg::Sugg::NonParen(op) + } + } + } + + arg = sugg::Sugg::NonParen(format!("{}.to_bits()", arg.maybe_par()).into()); + + // cast the result of `to_bits` if `to_ty` is signed + arg = if let ty::Int(int_ty) = to_ty.kind() { + arg.as_ty(int_ty.name_str().to_string()) + } else { + arg + }; + + diag.span_suggestion(e.span, "consider using", arg.to_string(), Applicability::Unspecified); + }, + ); + true + }, + _ => false, + } +} From c57a8260f22d4968f8c802ce92593a32e1e27f4c Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 01:21:38 +0900 Subject: [PATCH 088/226] Move unsound_collection_transmute to its own module --- clippy_lints/src/transmute/mod.rs | 35 ++----------- .../transmute/unsound_collection_transmute.rs | 49 +++++++++++++++++++ 2 files changed, 54 insertions(+), 30 deletions(-) create mode 100644 clippy_lints/src/transmute/unsound_collection_transmute.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 3ba0872393d0d..8cb4f6500574b 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -6,6 +6,7 @@ mod transmute_int_to_float; mod transmute_ptr_to_ptr; mod transmute_ptr_to_ref; mod transmute_ref_to_ref; +mod unsound_collection_transmute; mod useless_transmute; mod utils; mod wrong_transmute; @@ -327,17 +328,6 @@ declare_lint_pass!(Transmute => [ TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS, ]); -// used to check for UNSOUND_COLLECTION_TRANSMUTE -static COLLECTIONS: &[&[&str]] = &[ - &paths::VEC, - &paths::VEC_DEQUE, - &paths::BINARY_HEAP, - &paths::BTREESET, - &paths::BTREEMAP, - &paths::HASHSET, - &paths::HASHMAP, -]; - impl<'tcx> LateLintPass<'tcx> for Transmute { #[allow(clippy::similar_names, clippy::too_many_lines)] fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { @@ -395,27 +385,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } + let triggered = unsound_collection_transmute::check(cx, e, from_ty, to_ty); + if triggered { + return; + } match (&from_ty.kind(), &to_ty.kind()) { - (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => { - if from_adt.did != to_adt.did || - !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) { - return; - } - if from_substs.types().zip(to_substs.types()) - .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty)) { - span_lint( - cx, - UNSOUND_COLLECTION_TRANSMUTE, - e.span, - &format!( - "transmute from `{}` to `{}` with mismatched layout is unsound", - from_ty, - to_ty - ) - ); - } - }, (_, _) if can_be_expressed_as_pointer_cast(cx, e, from_ty, to_ty) => span_lint_and_then( cx, TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS, diff --git a/clippy_lints/src/transmute/unsound_collection_transmute.rs b/clippy_lints/src/transmute/unsound_collection_transmute.rs new file mode 100644 index 0000000000000..3ce6bcd3ea039 --- /dev/null +++ b/clippy_lints/src/transmute/unsound_collection_transmute.rs @@ -0,0 +1,49 @@ +use super::utils::is_layout_incompatible; +use super::UNSOUND_COLLECTION_TRANSMUTE; +use crate::utils::{match_def_path, paths, span_lint}; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::Ty; + +// used to check for UNSOUND_COLLECTION_TRANSMUTE +static COLLECTIONS: &[&[&str]] = &[ + &paths::VEC, + &paths::VEC_DEQUE, + &paths::BINARY_HEAP, + &paths::BTREESET, + &paths::BTREEMAP, + &paths::HASHSET, + &paths::HASHMAP, +]; + +/// Checks for `unsound_collection_transmute` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool { + match (&from_ty.kind(), &to_ty.kind()) { + (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => { + if from_adt.did != to_adt.did || !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) { + return false; + } + if from_substs + .types() + .zip(to_substs.types()) + .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty)) + { + span_lint( + cx, + UNSOUND_COLLECTION_TRANSMUTE, + e.span, + &format!( + "transmute from `{}` to `{}` with mismatched layout is unsound", + from_ty, to_ty + ), + ); + true + } else { + false + } + }, + _ => false, + } +} From 25c221ec92bdf7be29335f4ea830edb9509a8ce9 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 01:27:44 +0900 Subject: [PATCH 089/226] Move transmutes_expressible_as_ptr_casts to its own module --- clippy_lints/src/transmute/mod.rs | 25 ++---------- .../transmutes_expressible_as_ptr_casts.rs | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 8cb4f6500574b..3b010f39c8ab5 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -6,6 +6,7 @@ mod transmute_int_to_float; mod transmute_ptr_to_ptr; mod transmute_ptr_to_ref; mod transmute_ref_to_ref; +mod transmutes_expressible_as_ptr_casts; mod unsound_collection_transmute; mod useless_transmute; mod utils; @@ -389,27 +390,9 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { if triggered { return; } - - match (&from_ty.kind(), &to_ty.kind()) { - (_, _) if can_be_expressed_as_pointer_cast(cx, e, from_ty, to_ty) => span_lint_and_then( - cx, - TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS, - e.span, - &format!( - "transmute from `{}` to `{}` which could be expressed as a pointer cast instead", - from_ty, - to_ty - ), - |diag| { - if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - let sugg = arg.as_ty(&to_ty.to_string()).to_string(); - diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable); - } - } - ), - _ => { - return; - }, + let triggered = transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, to_ty, args); + if triggered { + return; } } } diff --git a/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs new file mode 100644 index 0000000000000..dea896622f11c --- /dev/null +++ b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -0,0 +1,38 @@ +use super::utils::can_be_expressed_as_pointer_cast; +use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS; +use crate::utils::{span_lint_and_then, sugg}; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::Ty; + +/// Checks for `transmutes_expressible_as_ptr_casts` lint. +/// Returns `true` if it's triggered, otherwise returns `false`. +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + from_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + args: &'tcx [Expr<'_>], +) -> bool { + if can_be_expressed_as_pointer_cast(cx, e, from_ty, to_ty) { + span_lint_and_then( + cx, + TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS, + e.span, + &format!( + "transmute from `{}` to `{}` which could be expressed as a pointer cast instead", + from_ty, to_ty + ), + |diag| { + if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + let sugg = arg.as_ty(&to_ty.to_string()).to_string(); + diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable); + } + }, + ); + true + } else { + false + } +} From 89ef26a68131d846b07e339e277232ff8737be3e Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 01:29:45 +0900 Subject: [PATCH 090/226] Cleanup imports --- clippy_lints/src/transmute/crosspointer_transmute.rs | 3 +-- clippy_lints/src/transmute/mod.rs | 12 ++---------- clippy_lints/src/transmute/transmute_float_to_int.rs | 3 +-- clippy_lints/src/transmute/transmute_int_to_bool.rs | 3 +-- clippy_lints/src/transmute/transmute_int_to_char.rs | 3 +-- clippy_lints/src/transmute/transmute_int_to_float.rs | 3 +-- clippy_lints/src/transmute/transmute_ptr_to_ptr.rs | 3 +-- clippy_lints/src/transmute/transmute_ptr_to_ref.rs | 3 +-- clippy_lints/src/transmute/transmute_ref_to_ref.rs | 3 +-- .../src/transmute/unsound_collection_transmute.rs | 3 +-- clippy_lints/src/transmute/useless_transmute.rs | 3 +-- clippy_lints/src/transmute/wrong_transmute.rs | 3 +-- 12 files changed, 13 insertions(+), 32 deletions(-) diff --git a/clippy_lints/src/transmute/crosspointer_transmute.rs b/clippy_lints/src/transmute/crosspointer_transmute.rs index b570bb3a396e4..ce87defaa9406 100644 --- a/clippy_lints/src/transmute/crosspointer_transmute.rs +++ b/clippy_lints/src/transmute/crosspointer_transmute.rs @@ -2,8 +2,7 @@ use super::CROSSPOINTER_TRANSMUTE; use crate::utils::span_lint; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `crosspointer_transmute` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 3b010f39c8ab5..e16dfa8722999 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -12,19 +12,11 @@ mod useless_transmute; mod utils; mod wrong_transmute; -use utils::*; - -use crate::utils::{ - in_constant, match_def_path, paths, snippet, span_lint, span_lint_and_sugg, span_lint_and_then, sugg, -}; +use crate::utils::{in_constant, match_def_path, paths}; use if_chain::if_chain; -use rustc_ast as ast; -use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, Mutability, UnOp}; +use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use std::borrow::Cow; declare_clippy_lint! { /// **What it does:** Checks for transmutes that can't ever be correct on any diff --git a/clippy_lints/src/transmute/transmute_float_to_int.rs b/clippy_lints/src/transmute/transmute_float_to_int.rs index 58cd0e217925b..562d880e39afb 100644 --- a/clippy_lints/src/transmute/transmute_float_to_int.rs +++ b/clippy_lints/src/transmute/transmute_float_to_int.rs @@ -5,8 +5,7 @@ use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, UnOp}; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `transmute_float_to_int` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/transmute_int_to_bool.rs b/clippy_lints/src/transmute/transmute_int_to_bool.rs index c66c7bff23257..5b609f906a3d7 100644 --- a/clippy_lints/src/transmute/transmute_int_to_bool.rs +++ b/clippy_lints/src/transmute/transmute_int_to_bool.rs @@ -4,8 +4,7 @@ use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; use std::borrow::Cow; /// Checks for `transmute_int_to_bool` lint. diff --git a/clippy_lints/src/transmute/transmute_int_to_char.rs b/clippy_lints/src/transmute/transmute_int_to_char.rs index 179627d9964b2..48473e0d799da 100644 --- a/clippy_lints/src/transmute/transmute_int_to_char.rs +++ b/clippy_lints/src/transmute/transmute_int_to_char.rs @@ -4,8 +4,7 @@ use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `transmute_int_to_char` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/transmute_int_to_float.rs b/clippy_lints/src/transmute/transmute_int_to_float.rs index 564a27df562d6..f83fba8966a11 100644 --- a/clippy_lints/src/transmute/transmute_int_to_float.rs +++ b/clippy_lints/src/transmute/transmute_int_to_float.rs @@ -3,8 +3,7 @@ use crate::utils::{span_lint_and_then, sugg}; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `transmute_int_to_float` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index 68668ec30db00..f4e60a3020cf5 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -3,8 +3,7 @@ use crate::utils::{span_lint_and_then, sugg}; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `transmute_ptr_to_ptr` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index 7be47da35dac7..a6719b68098a5 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -4,8 +4,7 @@ use crate::utils::{span_lint_and_then, sugg}; use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability, QPath}; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `transmute_ptr_to_ref` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs index a9e3385664bdb..ccfcb03e87ac3 100644 --- a/clippy_lints/src/transmute/transmute_ref_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -4,8 +4,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability}; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `transmute_bytes_to_str` and `transmute_ptr_to_ptr` lints. /// Returns `true` if either one triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/unsound_collection_transmute.rs b/clippy_lints/src/transmute/unsound_collection_transmute.rs index 3ce6bcd3ea039..503c5e0ff3822 100644 --- a/clippy_lints/src/transmute/unsound_collection_transmute.rs +++ b/clippy_lints/src/transmute/unsound_collection_transmute.rs @@ -3,8 +3,7 @@ use super::UNSOUND_COLLECTION_TRANSMUTE; use crate::utils::{match_def_path, paths, span_lint}; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; // used to check for UNSOUND_COLLECTION_TRANSMUTE static COLLECTIONS: &[&[&str]] = &[ diff --git a/clippy_lints/src/transmute/useless_transmute.rs b/clippy_lints/src/transmute/useless_transmute.rs index 86d75fd2ee0b0..83441514af051 100644 --- a/clippy_lints/src/transmute/useless_transmute.rs +++ b/clippy_lints/src/transmute/useless_transmute.rs @@ -3,8 +3,7 @@ use crate::utils::{span_lint, span_lint_and_then, sugg}; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `useless_transmute` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/wrong_transmute.rs b/clippy_lints/src/transmute/wrong_transmute.rs index d2d3f0a9c8902..d6d77f2c83456 100644 --- a/clippy_lints/src/transmute/wrong_transmute.rs +++ b/clippy_lints/src/transmute/wrong_transmute.rs @@ -2,8 +2,7 @@ use super::WRONG_TRANSMUTE; use crate::utils::span_lint; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; /// Checks for `wrong_transmute` lint. /// Returns `true` if it's triggered, otherwise returns `false`. From 8a8f7b4cf5c7642e72b0c0e40586a9310b1ca48b Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 01:41:52 +0900 Subject: [PATCH 091/226] Refactor calls to lint check functions --- clippy_lints/src/transmute/mod.rs | 61 ++++++++----------------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index e16dfa8722999..c1870f5208b45 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -338,53 +338,24 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { let from_ty = cx.typeck_results().expr_ty(&args[0]); let to_ty = cx.typeck_results().expr_ty(e); - let triggered = useless_transmute::check(cx, e, from_ty, to_ty, args); - if triggered { + // If useless_transmute is triggered, the other lints can be skipped. + if useless_transmute::check(cx, e, from_ty, to_ty, args) { return; } - let triggered = wrong_transmute::check(cx, e, from_ty, to_ty); - if triggered { - return; - } - let triggered = crosspointer_transmute::check(cx, e, from_ty, to_ty); - if triggered { - return; - } - let triggered = transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, args, qpath); - if triggered { - return; - } - let triggered = transmute_int_to_char::check(cx, e, from_ty, to_ty, args); - if triggered { - return; - } - let triggered = transmute_ref_to_ref::check(cx, e, from_ty, to_ty, args, const_context); - if triggered { - return; - } - let triggered = transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, args); - if triggered { - return; - } - let triggered = transmute_int_to_bool::check(cx, e, from_ty, to_ty, args); - if triggered { - return; - } - let triggered = transmute_int_to_float::check(cx, e, from_ty, to_ty, args, const_context); - if triggered { - return; - } - let triggered = transmute_float_to_int::check(cx, e, from_ty, to_ty, args, const_context); - if triggered { - return; - } - let triggered = unsound_collection_transmute::check(cx, e, from_ty, to_ty); - if triggered { - return; - } - let triggered = transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, to_ty, args); - if triggered { - return; + + let mut linted = wrong_transmute::check(cx, e, from_ty, to_ty); + linted |= crosspointer_transmute::check(cx, e, from_ty, to_ty); + linted |= transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, args, qpath); + linted |= transmute_int_to_char::check(cx, e, from_ty, to_ty, args); + linted |= transmute_ref_to_ref::check(cx, e, from_ty, to_ty, args, const_context); + linted |= transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, args); + linted |= transmute_int_to_bool::check(cx, e, from_ty, to_ty, args); + linted |= transmute_int_to_float::check(cx, e, from_ty, to_ty, args, const_context); + linted |= transmute_float_to_int::check(cx, e, from_ty, to_ty, args, const_context); + linted |= unsound_collection_transmute::check(cx, e, from_ty, to_ty); + + if !linted { + transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, to_ty, args); } } } From bf000985f50af1e506709ea5d735a35fac13925c Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 11 Feb 2021 01:42:12 +0900 Subject: [PATCH 092/226] Make check_cast private --- clippy_lints/src/transmute/utils.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/clippy_lints/src/transmute/utils.rs b/clippy_lints/src/transmute/utils.rs index 734a92d50d2ad..55008d8ec3f16 100644 --- a/clippy_lints/src/transmute/utils.rs +++ b/clippy_lints/src/transmute/utils.rs @@ -68,12 +68,7 @@ pub(super) fn can_be_expressed_as_pointer_cast<'tcx>( /// the cast. In certain cases, including some invalid casts from array references /// to pointers, this may cause additional errors to be emitted and/or ICE error /// messages. This function will panic if that occurs. -pub(super) fn check_cast<'tcx>( - cx: &LateContext<'tcx>, - e: &'tcx Expr<'_>, - from_ty: Ty<'tcx>, - to_ty: Ty<'tcx>, -) -> Option { +fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> Option { let hir_id = e.hir_id; let local_def_id = hir_id.owner; From 19c886b4076ebf264ef919b1fd78ebb9f193476c Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 2 Mar 2021 21:09:04 +0900 Subject: [PATCH 093/226] Remove "for_loop_arg.rs" --- clippy_lints/src/loops/for_loop_arg.rs | 149 ------------------------- 1 file changed, 149 deletions(-) delete mode 100644 clippy_lints/src/loops/for_loop_arg.rs diff --git a/clippy_lints/src/loops/for_loop_arg.rs b/clippy_lints/src/loops/for_loop_arg.rs deleted file mode 100644 index b33e7183984da..0000000000000 --- a/clippy_lints/src/loops/for_loop_arg.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::utils::{ - is_type_diagnostic_item, match_trait_method, match_type, paths, snippet, snippet_with_applicability, span_lint, - span_lint_and_help, span_lint_and_sugg, -}; -use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, Mutability, Pat}; -use rustc_lint::LateContext; -use rustc_middle::ty::{self, Ty, TyS}; -use rustc_span::symbol::sym; - -pub(super) fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { - let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used - if let ExprKind::MethodCall(ref method, _, ref args, _) = arg.kind { - // just the receiver, no arguments - if args.len() == 1 { - let method_name = &*method.ident.as_str(); - // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x - if method_name == "iter" || method_name == "iter_mut" { - if is_ref_iterable_type(cx, &args[0]) { - lint_iter_method(cx, args, arg, method_name); - } - } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { - let receiver_ty = cx.typeck_results().expr_ty(&args[0]); - let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(&args[0]); - if TyS::same_type(receiver_ty, receiver_ty_adjusted) { - let mut applicability = Applicability::MachineApplicable; - let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); - span_lint_and_sugg( - cx, - super::EXPLICIT_INTO_ITER_LOOP, - arg.span, - "it is more concise to loop over containers instead of using explicit \ - iteration methods", - "to write this more concisely, try", - object.to_string(), - applicability, - ); - } else { - let ref_receiver_ty = cx.tcx.mk_ref( - cx.tcx.lifetimes.re_erased, - ty::TypeAndMut { - ty: receiver_ty, - mutbl: Mutability::Not, - }, - ); - if TyS::same_type(receiver_ty_adjusted, ref_receiver_ty) { - lint_iter_method(cx, args, arg, method_name) - } - } - } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { - span_lint( - cx, - super::ITER_NEXT_LOOP, - expr.span, - "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ - probably not what you want", - ); - next_loop_linted = true; - } - } - } - if !next_loop_linted { - check_arg_type(cx, pat, arg); - } -} - -/// Checks for `for` loops over `Option`s and `Result`s. -fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { - let ty = cx.typeck_results().expr_ty(arg); - if is_type_diagnostic_item(cx, ty, sym::option_type) { - span_lint_and_help( - cx, - super::FOR_LOOPS_OVER_FALLIBLES, - arg.span, - &format!( - "for loop over `{0}`, which is an `Option`. This is more readably written as an \ - `if let` statement", - snippet(cx, arg.span, "_") - ), - None, - &format!( - "consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`", - snippet(cx, pat.span, "_"), - snippet(cx, arg.span, "_") - ), - ); - } else if is_type_diagnostic_item(cx, ty, sym::result_type) { - span_lint_and_help( - cx, - super::FOR_LOOPS_OVER_FALLIBLES, - arg.span, - &format!( - "for loop over `{0}`, which is a `Result`. This is more readably written as an \ - `if let` statement", - snippet(cx, arg.span, "_") - ), - None, - &format!( - "consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`", - snippet(cx, pat.span, "_"), - snippet(cx, arg.span, "_") - ), - ); - } -} - -fn lint_iter_method(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { - let mut applicability = Applicability::MachineApplicable; - let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); - let muta = if method_name == "iter_mut" { "mut " } else { "" }; - span_lint_and_sugg( - cx, - super::EXPLICIT_ITER_LOOP, - arg.span, - "it is more concise to loop over references to containers instead of using explicit \ - iteration methods", - "to write this more concisely, try", - format!("&{}{}", muta, object), - applicability, - ) -} - -/// Returns `true` if the type of expr is one that provides `IntoIterator` impls -/// for `&T` and `&mut T`, such as `Vec`. -#[rustfmt::skip] -fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - // no walk_ptrs_ty: calling iter() on a reference can make sense because it - // will allow further borrows afterwards - let ty = cx.typeck_results().expr_ty(e); - is_iterable_array(ty, cx) || - is_type_diagnostic_item(cx, ty, sym::vec_type) || - match_type(cx, ty, &paths::LINKED_LIST) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || - is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || - match_type(cx, ty, &paths::BINARY_HEAP) || - match_type(cx, ty, &paths::BTREEMAP) || - match_type(cx, ty, &paths::BTREESET) -} - -fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { - // IntoIterator is currently only implemented for array sizes <= 32 in rustc - match ty.kind() { - ty::Array(_, n) => n - .try_eval_usize(cx.tcx, cx.param_env) - .map_or(false, |val| (0..=32).contains(&val)), - _ => false, - } -} From 9e4a064f0878215fccaa3bebdfaf4459db984da3 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 2 Mar 2021 14:26:23 +0100 Subject: [PATCH 094/226] Move naive_bytecount to pedantic As discussed on Zulip, current best practice is to avoid recommending external crates. This lint is from before that was enforced. Move it to the pedantic group to avoid enabling it by default. https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/naive_bytecount.20suggesting.20extra.20dependency --- clippy_lints/src/bytecount.rs | 2 +- clippy_lints/src/lib.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index b8828719f627c..eb5dc7ceecdc7 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -28,7 +28,7 @@ declare_clippy_lint! { /// &vec.iter().filter(|x| **x == 0u8).count(); // use bytecount::count instead /// ``` pub NAIVE_BYTECOUNT, - perf, + pedantic, "use of naive `.filter(|&x| x == y).count()` to count byte values" } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 1ace4c8a10c91..4a19da60c0239 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1343,6 +1343,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&await_holding_invalid::AWAIT_HOLDING_LOCK), LintId::of(&await_holding_invalid::AWAIT_HOLDING_REFCELL_REF), LintId::of(&bit_mask::VERBOSE_BIT_MASK), + LintId::of(&bytecount::NAIVE_BYTECOUNT), LintId::of(&case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS), LintId::of(&checked_conversions::CHECKED_CONVERSIONS), LintId::of(&copies::SAME_FUNCTIONS_IN_IF_CONDITION), @@ -1458,7 +1459,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS), LintId::of(&booleans::LOGIC_BUG), LintId::of(&booleans::NONMINIMAL_BOOL), - LintId::of(&bytecount::NAIVE_BYTECOUNT), LintId::of(&collapsible_if::COLLAPSIBLE_ELSE_IF), LintId::of(&collapsible_if::COLLAPSIBLE_IF), LintId::of(&collapsible_match::COLLAPSIBLE_MATCH), @@ -2013,7 +2013,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: ]); store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![ - LintId::of(&bytecount::NAIVE_BYTECOUNT), LintId::of(&entry::MAP_ENTRY), LintId::of(&escape::BOXED_LOCAL), LintId::of(&large_const_arrays::LARGE_CONST_ARRAYS), From e3f48559edd2918acf4a28c8554b6d4a92431c94 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 18 Jan 2021 14:15:19 +0100 Subject: [PATCH 095/226] Allow noop_method_call in clippy ui test --- tests/ui/unnecessary_clone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index 6770a7fac90fd..ce26634a995d9 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -1,7 +1,7 @@ // does not test any rustfixable lints #![warn(clippy::clone_on_ref_ptr)] -#![allow(unused, clippy::redundant_clone, clippy::unnecessary_wraps)] +#![allow(unused, noop_method_call, clippy::redundant_clone, clippy::unnecessary_wraps)] use std::cell::RefCell; use std::rc::{self, Rc}; From 09c4503cae7c088b3df5181aa2429884b3b559ea Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 16 Feb 2021 22:39:05 +0100 Subject: [PATCH 096/226] Fix borrow and deref --- tests/ui/unnecessary_clone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index ce26634a995d9..6770a7fac90fd 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -1,7 +1,7 @@ // does not test any rustfixable lints #![warn(clippy::clone_on_ref_ptr)] -#![allow(unused, noop_method_call, clippy::redundant_clone, clippy::unnecessary_wraps)] +#![allow(unused, clippy::redundant_clone, clippy::unnecessary_wraps)] use std::cell::RefCell; use std::rc::{self, Rc}; From 5656510eed663b5d5be6b6df3d033b836da5f759 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 3 Mar 2021 17:32:49 +0100 Subject: [PATCH 097/226] Fix false-positive in `use_self` --- clippy_lints/src/use_self.rs | 17 +++++++++++------ tests/ui/use_self.fixed | 7 +++++++ tests/ui/use_self.rs | 7 +++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index be7b9e9ff2dcc..c262ec993b1f4 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -262,12 +262,17 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { // FIXME: this span manipulation should not be necessary // @flip1995 found an ast lowering issue in // https://github.com/rust-lang/rust/blob/master/src/librustc_ast_lowering/path.rs#l142-l162 - match cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_ty.hir_id)) { - Some(Node::Expr(Expr { - kind: ExprKind::Path(QPath::TypeRelative(_, segment)), - .. - })) => span_lint_until_last_segment(cx, hir_ty.span, segment), - _ => span_lint(cx, hir_ty.span), + let hir = cx.tcx.hir(); + let id = hir.get_parent_node(hir_ty.hir_id); + + if !hir.opt_span(id).map(in_macro).unwrap_or(false) { + match hir.find(id) { + Some(Node::Expr(Expr { + kind: ExprKind::Path(QPath::TypeRelative(_, segment)), + .. + })) => span_lint_until_last_segment(cx, hir_ty.span, segment), + _ => span_lint(cx, hir_ty.span), + } } } } diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 2b22a2ed2d565..a630936e3b1d0 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -454,3 +454,10 @@ mod nested_paths { } } } + +mod issue6818 { + #[derive(serde::Deserialize)] + struct A { + a: i32, + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 609625abdec0a..f3e081dd20328 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -454,3 +454,10 @@ mod nested_paths { } } } + +mod issue6818 { + #[derive(serde::Deserialize)] + struct A { + a: i32, + } +} From 03e72d5446bd104ac4480032ea44bd7419ce5694 Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Wed, 3 Mar 2021 22:06:36 +0800 Subject: [PATCH 098/226] Let Cargo track `CLIPPY_ARGS` --- README.md | 1 - src/driver.rs | 60 +++++++++++++++++++++++++----- tests/dogfood.rs | 97 ++++++++++++++++++++++++++++++++---------------- 3 files changed, 117 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 3cc03cf360336..63057609bb6fe 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,6 @@ the lint(s) you are interested in: ```terminal cargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::... ``` -Note that if you've run clippy before, this may only take effect after you've modified a file or ran `cargo clean`. ### Specifying the minimum supported Rust version diff --git a/src/driver.rs b/src/driver.rs index d5143e1438ee0..081a2ddeb1648 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -11,12 +11,16 @@ extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_interface; +extern crate rustc_session; +extern crate rustc_span; use rustc_interface::interface; +use rustc_session::Session; +use rustc_span::symbol::Symbol; use rustc_tools_util::VersionInfo; use std::borrow::Cow; -use std::env; +use std::env::{self, VarError}; use std::lazy::SyncLazy; use std::ops::Deref; use std::panic; @@ -59,13 +63,42 @@ fn test_arg_value() { assert_eq!(arg_value(args, "--foo", |_| true), None); } +fn track_clippy_args(sess: &Session, args_env_var: &Option) { + sess.parse_sess.env_depinfo.borrow_mut().insert(( + Symbol::intern("CLIPPY_ARGS"), + args_env_var.as_deref().map(Symbol::intern), + )); +} + struct DefaultCallbacks; impl rustc_driver::Callbacks for DefaultCallbacks {} -struct ClippyCallbacks; +struct ClippyArgsCallbacks { + clippy_args_var: Option, +} + +impl rustc_driver::Callbacks for ClippyArgsCallbacks { + fn config(&mut self, config: &mut interface::Config) { + let previous = config.register_lints.take(); + let clippy_args_var = self.clippy_args_var.take(); + config.register_lints = Some(Box::new(move |sess, lint_store| { + if let Some(ref previous) = previous { + (previous)(sess, lint_store); + } + + track_clippy_args(sess, &clippy_args_var); + })); + } +} + +struct ClippyCallbacks { + clippy_args_var: Option, +} + impl rustc_driver::Callbacks for ClippyCallbacks { fn config(&mut self, config: &mut interface::Config) { let previous = config.register_lints.take(); + let clippy_args_var = self.clippy_args_var.take(); config.register_lints = Some(Box::new(move |sess, mut lint_store| { // technically we're ~guaranteed that this is none but might as well call anything that // is there already. Certainly it can't hurt. @@ -73,6 +106,8 @@ impl rustc_driver::Callbacks for ClippyCallbacks { (previous)(sess, lint_store); } + track_clippy_args(sess, &clippy_args_var); + let conf = clippy_lints::read_conf(&[], &sess); clippy_lints::register_plugins(&mut lint_store, &sess, &conf); clippy_lints::register_pre_expansion_lints(&mut lint_store); @@ -277,7 +312,15 @@ pub fn main() { }; let mut no_deps = false; - let clippy_args = env::var("CLIPPY_ARGS") + let clippy_args_var = env::var("CLIPPY_ARGS").map_or_else( + |e| match e { + VarError::NotPresent => None, + VarError::NotUnicode(s) => panic!("CLIPPY_ARGS is not valid Unicode: {:?}", s), + }, + Some, + ); + let clippy_args = clippy_args_var + .as_deref() .unwrap_or_default() .split("__CLIPPY_HACKERY__") .filter_map(|s| match s { @@ -305,11 +348,10 @@ pub fn main() { args.extend(clippy_args); } - let mut clippy = ClippyCallbacks; - let mut default = DefaultCallbacks; - let callbacks: &mut (dyn rustc_driver::Callbacks + Send) = - if clippy_enabled { &mut clippy } else { &mut default }; - - rustc_driver::RunCompiler::new(&args, callbacks).run() + if clippy_enabled { + rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run() + } else { + rustc_driver::RunCompiler::new(&args, &mut ClippyArgsCallbacks { clippy_args_var }).run() + } })) } diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 8fe48a67beb57..2505836a5ed89 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -3,7 +3,7 @@ #![feature(once_cell)] use std::lazy::SyncLazy; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::process::Command; mod cargo; @@ -49,17 +49,6 @@ fn dogfood_clippy() { #[test] fn dogfood_subprojects() { fn test_no_deps_ignores_path_deps_in_workspaces() { - fn clean(cwd: &Path, target_dir: &Path) { - Command::new("cargo") - .current_dir(cwd) - .env("CARGO_TARGET_DIR", target_dir) - .arg("clean") - .args(&["-p", "subcrate"]) - .args(&["-p", "path_dep"]) - .output() - .unwrap(); - } - if cargo::is_rustc_test_suite() { return; } @@ -68,7 +57,14 @@ fn dogfood_subprojects() { let cwd = root.join("clippy_workspace_tests"); // Make sure we start with a clean state - clean(&cwd, &target_dir); + Command::new("cargo") + .current_dir(&cwd) + .env("CARGO_TARGET_DIR", &target_dir) + .arg("clean") + .args(&["-p", "subcrate"]) + .args(&["-p", "path_dep"]) + .output() + .unwrap(); // `path_dep` is a path dependency of `subcrate` that would trigger a denied lint. // Make sure that with the `--no-deps` argument Clippy does not run on `path_dep`. @@ -90,26 +86,65 @@ fn dogfood_subprojects() { assert!(output.status.success()); - // Make sure we start with a clean state - clean(&cwd, &target_dir); + let lint_path_dep = || { + // Test that without the `--no-deps` argument, `path_dep` is linted. + let output = Command::new(&*CLIPPY_PATH) + .current_dir(&cwd) + .env("CLIPPY_DOGFOOD", "1") + .env("CARGO_INCREMENTAL", "0") + .arg("clippy") + .args(&["-p", "subcrate"]) + .arg("--") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .args(&["--cfg", r#"feature="primary_package_test""#]) + .output() + .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + + assert!(!output.status.success()); + assert!( + String::from_utf8(output.stderr) + .unwrap() + .contains("error: empty `loop {}` wastes CPU cycles") + ); + }; + + // Make sure Cargo is aware of the removal of `--no-deps`. + lint_path_dep(); + + let successful_build = || { + let output = Command::new(&*CLIPPY_PATH) + .current_dir(&cwd) + .env("CLIPPY_DOGFOOD", "1") + .env("CARGO_INCREMENTAL", "0") + .arg("clippy") + .args(&["-p", "subcrate"]) + .arg("--") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .output() + .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); - // Test that without the `--no-deps` argument, `path_dep` is linted. - let output = Command::new(&*CLIPPY_PATH) - .current_dir(&cwd) - .env("CLIPPY_DOGFOOD", "1") - .env("CARGO_INCREMENTAL", "0") - .arg("clippy") - .args(&["-p", "subcrate"]) - .arg("--") - .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir - .args(&["--cfg", r#"feature="primary_package_test""#]) - .output() - .unwrap(); - println!("status: {}", output.status); - println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); - println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + assert!(output.status.success()); + + output + }; + + // Trigger a sucessful build, so Cargo would like to cache the build result. + successful_build(); + + // Make sure there's no spurious rebuild when nothing changes. + let stderr = String::from_utf8(successful_build().stderr).unwrap(); + assert!(!stderr.contains("Compiling")); + assert!(!stderr.contains("Checking")); + assert!(stderr.contains("Finished")); - assert!(!output.status.success()); + // Make sure Cargo is aware of the new `--cfg` flag. + lint_path_dep(); } // run clippy on remaining subprojects and fail the test if lint warnings are reported From bbe641678c70924de9dd6624db819ef0324bbb22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 2 Mar 2021 20:20:51 +0100 Subject: [PATCH 099/226] lintcheck: fix clippy warnings --- clippy_dev/src/lintcheck.rs | 53 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 1db0445559cd5..977ff771a99f4 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -5,14 +5,19 @@ // positives. #![cfg(feature = "lintcheck")] -#![allow(clippy::filter_map)] +#![allow(clippy::filter_map, clippy::collapsible_else_if)] +#![allow(clippy::blocks_in_if_conditions)] // FP on `if x.iter().any(|x| ...)` use crate::clippy_project_root; use std::collections::HashMap; use std::process::Command; use std::sync::atomic::{AtomicUsize, Ordering}; -use std::{env, fmt, fs::write, path::PathBuf}; +use std::{ + env, fmt, + fs::write, + path::{Path, PathBuf}, +}; use clap::ArgMatches; use rayon::prelude::*; @@ -196,11 +201,9 @@ impl CrateSource { if !crate_root.exists() { println!("Copying {} to {}", path.display(), copy_dest.display()); - dir::copy(path, ©_dest, &dir::CopyOptions::new()).expect(&format!( - "Failed to copy from {}, to {}", - path.display(), - crate_root.display() - )); + dir::copy(path, ©_dest, &dir::CopyOptions::new()).unwrap_or_else(|_| { + panic!("Failed to copy from {}, to {}", path.display(), crate_root.display()) + }); } else { println!( "Not copying {} to {}, destination already exists", @@ -225,7 +228,7 @@ impl Crate { /// issued fn run_clippy_lints( &self, - cargo_clippy_path: &PathBuf, + cargo_clippy_path: &Path, target_dir_index: &AtomicUsize, thread_limit: usize, total_crates_to_lint: usize, @@ -308,13 +311,13 @@ impl LintcheckConfig { // first, check if we got anything passed via the LINTCHECK_TOML env var, // if not, ask clap if we got any value for --crates-toml // if not, use the default "clippy_dev/lintcheck_crates.toml" - let sources_toml = env::var("LINTCHECK_TOML").unwrap_or( + let sources_toml = env::var("LINTCHECK_TOML").unwrap_or_else(|_| { clap_config .value_of("crates-toml") .clone() .unwrap_or("clippy_dev/lintcheck_crates.toml") - .to_string(), - ); + .to_string() + }); let sources_toml_path = PathBuf::from(sources_toml); @@ -330,7 +333,7 @@ impl LintcheckConfig { Some(threads) => { let threads: usize = threads .parse() - .expect(&format!("Failed to parse '{}' to a digit", threads)); + .unwrap_or_else(|_| panic!("Failed to parse '{}' to a digit", threads)); if threads == 0 { // automatic choice // Rayon seems to return thread count so half that for core count @@ -387,7 +390,7 @@ fn build_clippy() { } /// Read a `toml` file and return a list of `CrateSources` that we want to check with clippy -fn read_crates(toml_path: &PathBuf) -> Vec { +fn read_crates(toml_path: &Path) -> Vec { let toml_content: String = std::fs::read_to_string(&toml_path).unwrap_or_else(|_| panic!("Failed to read {}", toml_path.display())); let crate_list: SourceList = @@ -499,7 +502,7 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String, /// check if the latest modification of the logfile is older than the modification date of the /// clippy binary, if this is true, we should clean the lintchec shared target directory and recheck -fn lintcheck_needs_rerun(lintcheck_logs_path: &PathBuf) -> bool { +fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool { let clippy_modified: std::time::SystemTime = { let mut times = [CLIPPY_DRIVER_PATH, CARGO_CLIPPY_PATH].iter().map(|p| { std::fs::metadata(p) @@ -533,15 +536,13 @@ pub fn run(clap_config: &ArgMatches) { // refresh the logs if lintcheck_needs_rerun(&config.lintcheck_results_path) { let shared_target_dir = "target/lintcheck/shared_target_dir"; - match std::fs::metadata(&shared_target_dir) { - Ok(metadata) => { - if metadata.is_dir() { - println!("Clippy is newer than lint check logs, clearing lintcheck shared target dir..."); - std::fs::remove_dir_all(&shared_target_dir) - .expect("failed to remove target/lintcheck/shared_target_dir"); - } - }, - Err(_) => { /* dir probably does not exist, don't remove anything */ }, + // if we get an Err here, the shared target dir probably does simply not exist + if let Ok(metadata) = std::fs::metadata(&shared_target_dir) { + if metadata.is_dir() { + println!("Clippy is newer than lint check logs, clearing lintcheck shared target dir..."); + std::fs::remove_dir_all(&shared_target_dir) + .expect("failed to remove target/lintcheck/shared_target_dir"); + } } } @@ -660,7 +661,7 @@ pub fn run(clap_config: &ArgMatches) { } /// read the previous stats from the lintcheck-log file -fn read_stats_from_file(file_path: &PathBuf) -> HashMap { +fn read_stats_from_file(file_path: &Path) -> HashMap { let file_content: String = match std::fs::read_to_string(file_path).ok() { Some(content) => content, None => { @@ -678,9 +679,9 @@ fn read_stats_from_file(file_path: &PathBuf) -> HashMap { let stats_lines = &lines[start + 1..=end - 1]; stats_lines - .into_iter() + .iter() .map(|line| { - let mut spl = line.split(" ").into_iter(); + let mut spl = line.split(' '); ( spl.next().unwrap().to_string(), spl.next().unwrap().parse::().unwrap(), From 39c5e863378270c25ef75f3ae53d908565bc2619 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Thu, 4 Mar 2021 11:06:24 -0500 Subject: [PATCH 100/226] When checking if two empty hir blocks are equal also check to see if the tokens used are the same as well --- clippy_utils/src/hir_utils.rs | 81 +++++++++++++++++++++++++++++--- clippy_utils/src/lib.rs | 1 + tests/ui/match_same_arms2.rs | 29 ++++++++++++ tests/ui/match_same_arms2.stderr | 27 ++++++++++- 4 files changed, 130 insertions(+), 8 deletions(-) diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 81be9254cbe1a..e28ad27d9a6f8 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -1,5 +1,5 @@ use crate::consts::{constant_context, constant_simple}; -use crate::differing_macro_contexts; +use crate::{differing_macro_contexts, snippet_opt}; use rustc_ast::ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -9,6 +9,7 @@ use rustc_hir::{ GenericArg, GenericArgs, Guard, HirId, InlineAsmOperand, Lifetime, LifetimeName, ParamName, Pat, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, }; +use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::LateContext; use rustc_middle::ich::StableHashingContextProvider; use rustc_middle::ty::TypeckResults; @@ -110,8 +111,54 @@ impl HirEqInterExpr<'_, '_, '_> { /// Checks whether two blocks are the same. fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool { - over(&left.stmts, &right.stmts, |l, r| self.eq_stmt(l, r)) - && both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r)) + match (left.stmts, left.expr, right.stmts, right.expr) { + ([], None, [], None) => { + // For empty blocks, check to see if the tokens are equal. This will catch the case where a macro + // expanded to nothing, or the cfg attribute was used. + let (left, right) = match ( + snippet_opt(self.inner.cx, left.span), + snippet_opt(self.inner.cx, right.span), + ) { + (Some(left), Some(right)) => (left, right), + _ => return true, + }; + let mut left_pos = 0; + let left = tokenize(&left) + .map(|t| { + let end = left_pos + t.len; + let s = &left[left_pos..end]; + left_pos = end; + (t, s) + }) + .filter(|(t, _)| { + !matches!( + t.kind, + TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace + ) + }) + .map(|(_, s)| s); + let mut right_pos = 0; + let right = tokenize(&right) + .map(|t| { + let end = right_pos + t.len; + let s = &right[right_pos..end]; + right_pos = end; + (t, s) + }) + .filter(|(t, _)| { + !matches!( + t.kind, + TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace + ) + }) + .map(|(_, s)| s); + left.eq(right) + }, + _ => { + over(&left.stmts, &right.stmts, |l, r| self.eq_stmt(l, r)) + && both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r)) + }, + } } #[allow(clippy::similar_names)] @@ -131,7 +178,10 @@ impl HirEqInterExpr<'_, '_, '_> { } } - let is_eq = match (&reduce_exprkind(&left.kind), &reduce_exprkind(&right.kind)) { + let is_eq = match ( + &reduce_exprkind(self.inner.cx, &left.kind), + &reduce_exprkind(self.inner.cx, &right.kind), + ) { (&ExprKind::AddrOf(lb, l_mut, ref le), &ExprKind::AddrOf(rb, r_mut, ref re)) => { lb == rb && l_mut == r_mut && self.eq_expr(le, re) }, @@ -360,11 +410,30 @@ impl HirEqInterExpr<'_, '_, '_> { } /// Some simple reductions like `{ return }` => `return` -fn reduce_exprkind<'hir>(kind: &'hir ExprKind<'hir>) -> &ExprKind<'hir> { +fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &'hir ExprKind<'hir> { if let ExprKind::Block(block, _) = kind { match (block.stmts, block.expr) { + // From an `if let` expression without an `else` block. The arm for the implicit wild pattern is an empty + // block with an empty span. + ([], None) if block.span.is_empty() => &ExprKind::Tup(&[]), // `{}` => `()` - ([], None) => &ExprKind::Tup(&[]), + ([], None) => match snippet_opt(cx, block.span) { + // Don't reduce if there are any tokens contained in the braces + Some(snip) + if tokenize(&snip) + .map(|t| t.kind) + .filter(|t| { + !matches!( + t, + TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace + ) + }) + .ne([TokenKind::OpenBrace, TokenKind::CloseBrace].iter().cloned()) => + { + kind + }, + _ => &ExprKind::Tup(&[]), + }, ([], Some(expr)) => match expr.kind { // `{ return .. }` => `return ..` ExprKind::Ret(..) => &expr.kind, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 00455d4102f98..0395079901cb3 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -14,6 +14,7 @@ extern crate rustc_errors; extern crate rustc_hir; extern crate rustc_hir_pretty; extern crate rustc_infer; +extern crate rustc_lexer; extern crate rustc_lint; extern crate rustc_middle; extern crate rustc_mir; diff --git a/tests/ui/match_same_arms2.rs b/tests/ui/match_same_arms2.rs index 06d91497242e1..da4e3020d5b83 100644 --- a/tests/ui/match_same_arms2.rs +++ b/tests/ui/match_same_arms2.rs @@ -120,6 +120,35 @@ fn match_same_arms() { }, } + // False positive #1390 + macro_rules! empty { + ($e:expr) => {}; + } + match 0 { + 0 => { + empty!(0); + }, + 1 => { + empty!(1); + }, + x => { + empty!(x); + }, + }; + + // still lint if the tokens are the same + match 0 { + 0 => { + empty!(0); + }, + 1 => { + empty!(0); + }, + x => { + empty!(x); + }, + } + match_expr_like_matches_macro_priority(); } diff --git a/tests/ui/match_same_arms2.stderr b/tests/ui/match_same_arms2.stderr index fccaf805616b4..95f9494cdc99e 100644 --- a/tests/ui/match_same_arms2.stderr +++ b/tests/ui/match_same_arms2.stderr @@ -141,8 +141,31 @@ LL | Ok(3) => println!("ok"), | ^^^^^ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) +error: this `match` has identical arm bodies + --> $DIR/match_same_arms2.rs:144:14 + | +LL | 1 => { + | ______________^ +LL | | empty!(0); +LL | | }, + | |_________^ + | +note: same as this + --> $DIR/match_same_arms2.rs:141:14 + | +LL | 0 => { + | ______________^ +LL | | empty!(0); +LL | | }, + | |_________^ +help: consider refactoring into `0 | 1` + --> $DIR/match_same_arms2.rs:141:9 + | +LL | 0 => { + | ^ + error: match expression looks like `matches!` macro - --> $DIR/match_same_arms2.rs:133:16 + --> $DIR/match_same_arms2.rs:162:16 | LL | let _ans = match x { | ________________^ @@ -154,5 +177,5 @@ LL | | }; | = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors From 37c4b11a84eb07c0d9a0b95ad81a7ae72ec1370a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 4 Mar 2021 22:33:22 +0100 Subject: [PATCH 101/226] lintcheck: add test --- clippy_dev/src/lintcheck.rs | 32 +++++++++++++++++++++++++++++++- clippy_dev/test_sources.toml | 4 ++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 clippy_dev/test_sources.toml diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 977ff771a99f4..01f3c9a5bd8a2 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -503,6 +503,10 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String, /// check if the latest modification of the logfile is older than the modification date of the /// clippy binary, if this is true, we should clean the lintchec shared target directory and recheck fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool { + if !lintcheck_logs_path.exists() { + return true; + } + let clippy_modified: std::time::SystemTime = { let mut times = [CLIPPY_DRIVER_PATH, CARGO_CLIPPY_PATH].iter().map(|p| { std::fs::metadata(p) @@ -665,7 +669,6 @@ fn read_stats_from_file(file_path: &Path) -> HashMap { let file_content: String = match std::fs::read_to_string(file_path).ok() { Some(content) => content, None => { - eprintln!("RETURND"); return HashMap::new(); }, }; @@ -734,3 +737,30 @@ fn print_stats(old_stats: HashMap, new_stats: HashMap<&String, us println!("{} {} => 0", old_key, old_value); }); } + +#[test] +fn lintcheck_test() { + let args = [ + "run", + "--target-dir", + "clippy_dev/target", + "--package", + "clippy_dev", + "--bin", + "clippy_dev", + "--manifest-path", + "clippy_dev/Cargo.toml", + "--features", + "lintcheck", + "--", + "lintcheck", + "--crates-toml", + "clippy_dev/test_sources.toml", + ]; + let status = std::process::Command::new("cargo") + .args(&args) + .current_dir("../" /* repo root */) + .status(); + + assert!(status.unwrap().success()); +} diff --git a/clippy_dev/test_sources.toml b/clippy_dev/test_sources.toml new file mode 100644 index 0000000000000..4b0eb71ef4bfe --- /dev/null +++ b/clippy_dev/test_sources.toml @@ -0,0 +1,4 @@ +[crates] +cc = {name = "cc", versions = ['1.0.67']} +home = {name = "home", git_url = "https://github.com/brson/home", git_hash = "32044e53dfbdcd32bafad3109d1fbab805fc0f40"} +rustc_tools_util = {name = "rustc_tools_util", versions = ['0.2.0']} From 3f7ad32a997c4947e7f010abe980862a2ff21f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 4 Mar 2021 22:40:04 +0100 Subject: [PATCH 102/226] update lintcheck logs --- lintcheck-logs/lintcheck_crates_logs.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lintcheck-logs/lintcheck_crates_logs.txt b/lintcheck-logs/lintcheck_crates_logs.txt index 167024b3a056b..47453f362547a 100644 --- a/lintcheck-logs/lintcheck_crates_logs.txt +++ b/lintcheck-logs/lintcheck_crates_logs.txt @@ -1,4 +1,4 @@ -clippy 0.1.52 (70d952e75 2021-02-28) +clippy 0.1.52 (37c4b11a8 2021-03-04) target/lintcheck/sources/anyhow-1.0.38/build.rs:1:null clippy::cargo_common_metadata "package `anyhow` is missing `package.keywords` metadata" target/lintcheck/sources/anyhow-1.0.38/src/error.rs:350:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" @@ -99,6 +99,7 @@ target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multi target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:72:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:79:40 clippy::manual_map "manual implementation of `Option::map`" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:94:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:96:41 clippy::redundant_closure_for_method_calls "redundant closure found" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:98:60 clippy::redundant_closure_for_method_calls "redundant closure found" @@ -1208,6 +1209,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:689:20 clippy target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:748:30 clippy::manual_map "manual implementation of `Option::map`" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:816:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/path.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/path.rs:14:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -1463,6 +1465,7 @@ target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:464:5 clippy::missing_pa target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:57:13 clippy::enum_glob_use "usage of wildcard import for enum variants" target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:586:33 clippy::match_same_arms "this `match` has identical arm bodies" target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:599:32 clippy::match_same_arms "this `match` has identical arm bodies" +target/lintcheck/sources/cfg-expr-0.7.1/src/expr/mod.rs:609:9 clippy::manual_map "manual implementation of `Option::map`" target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:116:31 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:124:36 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cfg-expr-0.7.1/src/expr/parser.rs:17:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -3509,6 +3512,7 @@ clippy::filter_map_next 3 clippy::fn_params_excessive_bools 3 clippy::if_same_then_else 3 clippy::inconsistent_struct_constructor 3 +clippy::manual_map 3 clippy::mut_mut 3 clippy::ptr_arg 3 clippy::zero_ptr 3 From 26265bb9bc815f8b508ae1743f816f76a0eeea41 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 5 Mar 2021 10:27:30 +0100 Subject: [PATCH 103/226] ci: Sync clippy and clippy_bors workflows Those workflows should always test exactly the same things --- .github/workflows/clippy.yml | 8 +++++--- .github/workflows/clippy_bors.yml | 12 ++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 9d5e12aac5f7b..32103f59d8b0e 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -27,6 +27,7 @@ env: jobs: base: + # NOTE: If you modify this job, make sure you copy the changes to clippy_bors.yml runs-on: ubuntu-latest steps: @@ -50,9 +51,6 @@ jobs: - name: Build run: cargo build --features deny-warnings,internal-lints - - name: Test "--fix -Zunstable-options" - run: cargo run --features deny-warnings,internal-lints --bin cargo-clippy -- clippy --fix -Zunstable-options - - name: Test run: cargo test --features deny-warnings,internal-lints @@ -72,6 +70,10 @@ jobs: run: ../target/debug/cargo-clippy working-directory: clippy_workspace_tests + - name: Test cargo-clippy --fix + run: ../target/debug/cargo-clippy clippy --fix -Zunstable-options + working-directory: clippy_workspace_tests + - name: Test clippy-driver run: bash .github/driver.sh env: diff --git a/.github/workflows/clippy_bors.yml b/.github/workflows/clippy_bors.yml index 5d846eb64c78e..47253eecc4c4c 100644 --- a/.github/workflows/clippy_bors.yml +++ b/.github/workflows/clippy_bors.yml @@ -72,6 +72,7 @@ jobs: runs-on: ${{ matrix.os }} + # NOTE: If you modify this job, make sure you copy the changes to clippy.yml steps: # Setup - uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master @@ -131,11 +132,22 @@ jobs: run: ../target/debug/cargo-clippy working-directory: clippy_workspace_tests + - name: Test cargo-clippy --fix + run: ../target/debug/cargo-clippy clippy --fix -Zunstable-options + working-directory: clippy_workspace_tests + - name: Test clippy-driver run: bash .github/driver.sh env: OS: ${{ runner.os }} + - name: Test cargo dev new lint + run: | + cargo dev new_lint --name new_early_pass --pass early + cargo dev new_lint --name new_late_pass --pass late + cargo check + git reset --hard HEAD + integration_build: needs: changelog runs-on: ubuntu-latest From 5b2e7e91c3c12fb1eaf12aadc1d01a3f5ec7670c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Mar 2021 09:32:47 +0000 Subject: [PATCH 104/226] Shrink the size of Rvalue by 16 bytes --- clippy_lints/src/redundant_clone.rs | 4 ++-- clippy_utils/src/qualify_min_const_fn.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index 06adbb523d706..6a4537e6735ce 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -584,10 +584,10 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) { match rvalue { Use(op) | Repeat(op, _) | Cast(_, op, _) | UnaryOp(_, op) => visit_op(op), Aggregate(_, ops) => ops.iter().for_each(visit_op), - BinaryOp(_, lhs, rhs) | CheckedBinaryOp(_, lhs, rhs) => { + BinaryOp(_, box (lhs, rhs)) | CheckedBinaryOp(_, box (lhs, rhs)) => { visit_op(lhs); visit_op(rhs); - }, + } _ => (), } } diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index a482017afeb13..2cb9588e13f98 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -172,7 +172,7 @@ fn check_rvalue(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rv } }, // binops are fine on integers - Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => { + Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => { check_operand(tcx, lhs, span, body)?; check_operand(tcx, rhs, span, body)?; let ty = lhs.ty(body, tcx); From 5ebe6d3234c285be553ad2f1a4b965d497c1d573 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 5 Mar 2021 10:30:26 +0100 Subject: [PATCH 105/226] Fix dogfood test Since clippy cannot be a workspace, we have to check the sub-crates separately --- tests/dogfood.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 8fe48a67beb57..89526648d2e03 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -23,10 +23,9 @@ fn dogfood_clippy() { .current_dir(root_dir) .env("CLIPPY_DOGFOOD", "1") .env("CARGO_INCREMENTAL", "0") - .arg("clippy-preview") + .arg("clippy") .arg("--all-targets") .arg("--all-features") - .args(&["-p", "clippy_lints", "-p", "clippy_utils", "-p", "rustc_tools_util"]) .arg("--") .args(&["-D", "clippy::all"]) .args(&["-D", "clippy::pedantic"]) @@ -125,19 +124,30 @@ fn dogfood_subprojects() { "clippy_workspace_tests/subcrate", "clippy_workspace_tests/subcrate/src", "clippy_dev", + "clippy_lints", + "clippy_utils", "rustc_tools_util", ] { - let output = Command::new(&*CLIPPY_PATH) + let mut command = Command::new(&*CLIPPY_PATH); + command .current_dir(root_dir.join(d)) .env("CLIPPY_DOGFOOD", "1") .env("CARGO_INCREMENTAL", "0") .arg("clippy") + .arg("--all-targets") + .arg("--all-features") .arg("--") .args(&["-D", "clippy::all"]) .args(&["-D", "clippy::pedantic"]) - .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir - .output() - .unwrap(); + .arg("-Cdebuginfo=0"); // disable debuginfo to generate less data in the target dir + + // internal lints only exist if we build with the internal-lints feature + if cfg!(feature = "internal-lints") { + command.args(&["-D", "clippy::internal"]); + } + + let output = command.output().unwrap(); + println!("status: {}", output.status); println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); From 3c502ec8a50177ea05b6de233bfe2420c4b08c15 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 5 Mar 2021 10:31:21 +0100 Subject: [PATCH 106/226] Remove hack that forces dogfood to run on nightly This isn't necessary anymore, since we don't use a custom toolchain anymore --- src/main.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index d13a831f5ff7d..7bb80b1196e59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,12 +92,6 @@ impl ClippyCmd { panic!("Usage of `--fix` requires `-Z unstable-options`"); } - // Run the dogfood tests directly on nightly cargo. This is required due - // to a bug in rustup.rs when running cargo on custom toolchains. See issue #3118. - if env::var_os("CLIPPY_DOGFOOD").is_some() && cfg!(windows) { - args.insert(0, "+nightly".to_string()); - } - let mut clippy_args: Vec = old_args.collect(); if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") { clippy_args.push("--no-deps".into()); From 1d71d9a106e12bd90f0f3be86e43736f89acc975 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 5 Mar 2021 11:08:25 +0100 Subject: [PATCH 107/226] Fix dogfood errors in clippy_lints --- .../src/transmute/transmute_int_to_char.rs | 42 ++++--- .../src/transmute/transmute_ptr_to_ref.rs | 4 +- .../src/transmute/transmute_ref_to_ref.rs | 111 +++++++++--------- clippy_lints/src/use_self.rs | 2 +- 4 files changed, 77 insertions(+), 82 deletions(-) diff --git a/clippy_lints/src/transmute/transmute_int_to_char.rs b/clippy_lints/src/transmute/transmute_int_to_char.rs index 48473e0d799da..29d2450618a7e 100644 --- a/clippy_lints/src/transmute/transmute_int_to_char.rs +++ b/clippy_lints/src/transmute/transmute_int_to_char.rs @@ -17,28 +17,26 @@ pub(super) fn check<'tcx>( ) -> bool { match (&from_ty.kind(), &to_ty.kind()) { (ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => { - { - span_lint_and_then( - cx, - TRANSMUTE_INT_TO_CHAR, - e.span, - &format!("transmute from a `{}` to a `char`", from_ty), - |diag| { - let arg = sugg::Sugg::hir(cx, &args[0], ".."); - let arg = if let ty::Int(_) = from_ty.kind() { - arg.as_ty(ast::UintTy::U32.name_str()) - } else { - arg - }; - diag.span_suggestion( - e.span, - "consider using", - format!("std::char::from_u32({}).unwrap()", arg.to_string()), - Applicability::Unspecified, - ); - }, - ) - }; + span_lint_and_then( + cx, + TRANSMUTE_INT_TO_CHAR, + e.span, + &format!("transmute from a `{}` to a `char`", from_ty), + |diag| { + let arg = sugg::Sugg::hir(cx, &args[0], ".."); + let arg = if let ty::Int(_) = from_ty.kind() { + arg.as_ty(ast::UintTy::U32.name_str()) + } else { + arg + }; + diag.span_suggestion( + e.span, + "consider using", + format!("std::char::from_u32({}).unwrap()", arg.to_string()), + Applicability::Unspecified, + ); + }, + ); true }, _ => false, diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index a6719b68098a5..f5dbbbe33bc64 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -17,7 +17,7 @@ pub(super) fn check<'tcx>( qpath: &'tcx QPath<'_>, ) -> bool { match (&from_ty.kind(), &to_ty.kind()) { - (ty::RawPtr(from_pty), ty::Ref(_, to_ref_ty, mutbl)) => { + (ty::RawPtr(from_ptr_ty), ty::Ref(_, to_ref_ty, mutbl)) => { span_lint_and_then( cx, TRANSMUTE_PTR_TO_REF, @@ -34,7 +34,7 @@ pub(super) fn check<'tcx>( ("&*", "*const") }; - let arg = if from_pty.ty == *to_ref_ty { + let arg = if from_ptr_ty.ty == *to_ref_ty { arg } else { arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_ref_ty))) diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs index ccfcb03e87ac3..01b00bb0a2229 100644 --- a/clippy_lints/src/transmute/transmute_ref_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -18,70 +18,67 @@ pub(super) fn check<'tcx>( ) -> bool { let mut triggered = false; - match (&from_ty.kind(), &to_ty.kind()) { - (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) => { - if_chain! { - if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind()); - if let ty::Uint(ty::UintTy::U8) = slice_ty.kind(); - if from_mutbl == to_mutbl; - then { - let postfix = if *from_mutbl == Mutability::Mut { - "_mut" - } else { - "" - }; + if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (&from_ty.kind(), &to_ty.kind()) { + if_chain! { + if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind()); + if let ty::Uint(ty::UintTy::U8) = slice_ty.kind(); + if from_mutbl == to_mutbl; + then { + let postfix = if *from_mutbl == Mutability::Mut { + "_mut" + } else { + "" + }; - span_lint_and_sugg( + span_lint_and_sugg( + cx, + TRANSMUTE_BYTES_TO_STR, + e.span, + &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), + "consider using", + format!( + "std::str::from_utf8{}({}).unwrap()", + postfix, + snippet(cx, args[0].span, ".."), + ), + Applicability::Unspecified, + ); + triggered = true; + } else { + if (cx.tcx.erase_regions(from_ty) != cx.tcx.erase_regions(to_ty)) + && !const_context { + span_lint_and_then( cx, - TRANSMUTE_BYTES_TO_STR, + TRANSMUTE_PTR_TO_PTR, e.span, - &format!("transmute from a `{}` to a `{}`", from_ty, to_ty), - "consider using", - format!( - "std::str::from_utf8{}({}).unwrap()", - postfix, - snippet(cx, args[0].span, ".."), - ), - Applicability::Unspecified, + "transmute from a reference to a reference", + |diag| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + let ty_from_and_mut = ty::TypeAndMut { + ty: ty_from, + mutbl: *from_mutbl + }; + let ty_to_and_mut = ty::TypeAndMut { ty: ty_to, mutbl: *to_mutbl }; + let sugg_paren = arg + .as_ty(cx.tcx.mk_ptr(ty_from_and_mut)) + .as_ty(cx.tcx.mk_ptr(ty_to_and_mut)); + let sugg = if *to_mutbl == Mutability::Mut { + sugg_paren.mut_addr_deref() + } else { + sugg_paren.addr_deref() + }; + diag.span_suggestion( + e.span, + "try", + sugg.to_string(), + Applicability::Unspecified, + ); + }, ); - triggered = true; - } else { - if (cx.tcx.erase_regions(from_ty) != cx.tcx.erase_regions(to_ty)) - && !const_context { - span_lint_and_then( - cx, - TRANSMUTE_PTR_TO_PTR, - e.span, - "transmute from a reference to a reference", - |diag| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - let ty_from_and_mut = ty::TypeAndMut { - ty: ty_from, - mutbl: *from_mutbl - }; - let ty_to_and_mut = ty::TypeAndMut { ty: ty_to, mutbl: *to_mutbl }; - let sugg_paren = arg - .as_ty(cx.tcx.mk_ptr(ty_from_and_mut)) - .as_ty(cx.tcx.mk_ptr(ty_to_and_mut)); - let sugg = if *to_mutbl == Mutability::Mut { - sugg_paren.mut_addr_deref() - } else { - sugg_paren.addr_deref() - }; - diag.span_suggestion( - e.span, - "try", - sugg.to_string(), - Applicability::Unspecified, - ); - }, - ); - triggered = true; - } + triggered = true; } } - }, - _ => {}, + } } triggered diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index c262ec993b1f4..f0523cec6211d 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -265,7 +265,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { let hir = cx.tcx.hir(); let id = hir.get_parent_node(hir_ty.hir_id); - if !hir.opt_span(id).map(in_macro).unwrap_or(false) { + if !hir.opt_span(id).map_or(false, in_macro) { match hir.find(id) { Some(Node::Expr(Expr { kind: ExprKind::Path(QPath::TypeRelative(_, segment)), From 4aaad086d2eff2d2f4e169551b6cffad22e7e751 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 5 Mar 2021 11:10:15 +0100 Subject: [PATCH 108/226] Fix dogfood errors in clippy_dev --- clippy_dev/src/lib.rs | 2 +- clippy_dev/src/lintcheck.rs | 68 ++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index 01d1fc9211a94..0244ff2b6c27b 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -530,7 +530,7 @@ fn test_gen_deprecated() { #[should_panic] fn test_gen_deprecated_fail() { let lints = vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")]; - let _ = gen_deprecated(lints.iter()); + let _deprecated_lints = gen_deprecated(lints.iter()); } #[test] diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 01f3c9a5bd8a2..81b86481f5709 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -6,13 +6,12 @@ #![cfg(feature = "lintcheck")] #![allow(clippy::filter_map, clippy::collapsible_else_if)] -#![allow(clippy::blocks_in_if_conditions)] // FP on `if x.iter().any(|x| ...)` use crate::clippy_project_root; -use std::collections::HashMap; use std::process::Command; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::{collections::HashMap, io::ErrorKind}; use std::{ env, fmt, fs::write, @@ -116,9 +115,21 @@ impl CrateSource { // url to download the crate from crates.io let url = format!("https://crates.io/api/v1/crates/{}/{}/download", name, version); println!("Downloading and extracting {} {} from {}", name, version, url); - let _ = std::fs::create_dir("target/lintcheck/"); - let _ = std::fs::create_dir(&krate_download_dir); - let _ = std::fs::create_dir(&extract_dir); + std::fs::create_dir("target/lintcheck/").unwrap_or_else(|err| { + if err.kind() != ErrorKind::AlreadyExists { + panic!("cannot create lintcheck target dir"); + } + }); + std::fs::create_dir(&krate_download_dir).unwrap_or_else(|err| { + if err.kind() != ErrorKind::AlreadyExists { + panic!("cannot create crate download dir"); + } + }); + std::fs::create_dir(&extract_dir).unwrap_or_else(|err| { + if err.kind() != ErrorKind::AlreadyExists { + panic!("cannot create crate extraction dir"); + } + }); let krate_file_path = krate_download_dir.join(format!("{}-{}.crate.tar.gz", name, version)); // don't download/extract if we already have done so @@ -198,18 +209,18 @@ impl CrateSource { // the source path of the crate we copied, ${copy_dest}/crate_name let crate_root = copy_dest.join(name); // .../crates/local_crate - if !crate_root.exists() { - println!("Copying {} to {}", path.display(), copy_dest.display()); - - dir::copy(path, ©_dest, &dir::CopyOptions::new()).unwrap_or_else(|_| { - panic!("Failed to copy from {}, to {}", path.display(), crate_root.display()) - }); - } else { + if crate_root.exists() { println!( "Not copying {} to {}, destination already exists", path.display(), crate_root.display() ); + } else { + println!("Copying {} to {}", path.display(), copy_dest.display()); + + dir::copy(path, ©_dest, &dir::CopyOptions::new()).unwrap_or_else(|_| { + panic!("Failed to copy from {}, to {}", path.display(), crate_root.display()) + }); } Crate { @@ -236,8 +247,8 @@ impl Crate { // advance the atomic index by one let index = target_dir_index.fetch_add(1, Ordering::SeqCst); // "loop" the index within 0..thread_limit - let target_dir_index = index % thread_limit; - let perc = ((index * 100) as f32 / total_crates_to_lint as f32) as u8; + let thread_index = index % thread_limit; + let perc = (index * 100) / total_crates_to_lint; if thread_limit == 1 { println!( @@ -247,7 +258,7 @@ impl Crate { } else { println!( "{}/{} {}% Linting {} {} in target dir {:?}", - index, total_crates_to_lint, perc, &self.name, &self.version, target_dir_index + index, total_crates_to_lint, perc, &self.name, &self.version, thread_index ); } @@ -269,7 +280,7 @@ impl Crate { // use the looping index to create individual target dirs .env( "CARGO_TARGET_DIR", - shared_target_dir.join(format!("_{:?}", target_dir_index)), + shared_target_dir.join(format!("_{:?}", thread_index)), ) // lint warnings will look like this: // src/cargo/ops/cargo_compile.rs:127:35: warning: usage of `FromIterator::from_iter` @@ -529,6 +540,10 @@ fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool { } /// lintchecks `main()` function +/// +/// # Panics +/// +/// This function panics if the clippy binaries don't exist. pub fn run(clap_config: &ArgMatches) { let config = LintcheckConfig::from_clap(clap_config); @@ -579,9 +594,9 @@ pub fn run(clap_config: &ArgMatches) { // if we don't have the specified crate in the .toml, throw an error if !crates.iter().any(|krate| { let name = match krate { - CrateSource::CratesIo { name, .. } => name, - CrateSource::Git { name, .. } => name, - CrateSource::Path { name, .. } => name, + CrateSource::CratesIo { name, .. } | CrateSource::Git { name, .. } | CrateSource::Path { name, .. } => { + name + }, }; name == only_one_crate }) { @@ -597,8 +612,7 @@ pub fn run(clap_config: &ArgMatches) { .into_iter() .map(|krate| krate.download_and_extract()) .filter(|krate| krate.name == only_one_crate) - .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, 1)) - .flatten() + .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, 1)) .collect() } else { if config.max_jobs > 1 { @@ -621,8 +635,7 @@ pub fn run(clap_config: &ArgMatches) { crates .into_par_iter() .map(|krate| krate.download_and_extract()) - .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates)) - .flatten() + .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates)) .collect() } else { // run sequential @@ -630,8 +643,7 @@ pub fn run(clap_config: &ArgMatches) { crates .into_iter() .map(|krate| krate.download_and_extract()) - .map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, 1, num_crates)) - .flatten() + .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, 1, num_crates)) .collect() } }; @@ -646,7 +658,7 @@ pub fn run(clap_config: &ArgMatches) { .map(|w| (&w.crate_name, &w.message)) .collect(); - let mut all_msgs: Vec = clippy_warnings.iter().map(|warning| warning.to_string()).collect(); + let mut all_msgs: Vec = clippy_warnings.iter().map(ToString::to_string).collect(); all_msgs.sort(); all_msgs.push("\n\n\n\nStats:\n".into()); all_msgs.push(stats_formatted); @@ -673,13 +685,13 @@ fn read_stats_from_file(file_path: &Path) -> HashMap { }, }; - let lines: Vec = file_content.lines().map(|l| l.to_string()).collect(); + let lines: Vec = file_content.lines().map(ToString::to_string).collect(); // search for the beginning "Stats:" and the end "ICEs:" of the section we want let start = lines.iter().position(|line| line == "Stats:").unwrap(); let end = lines.iter().position(|line| line == "ICEs:").unwrap(); - let stats_lines = &lines[start + 1..=end - 1]; + let stats_lines = &lines[start + 1..end]; stats_lines .iter() From 74eb44834cc12ce51396d94e98b04fdd0ad9bb64 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 5 Mar 2021 14:06:43 +0100 Subject: [PATCH 109/226] Extract directory creation into its own function --- clippy_dev/src/lintcheck.rs | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index 81b86481f5709..f01f14eb458fd 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -115,21 +115,7 @@ impl CrateSource { // url to download the crate from crates.io let url = format!("https://crates.io/api/v1/crates/{}/{}/download", name, version); println!("Downloading and extracting {} {} from {}", name, version, url); - std::fs::create_dir("target/lintcheck/").unwrap_or_else(|err| { - if err.kind() != ErrorKind::AlreadyExists { - panic!("cannot create lintcheck target dir"); - } - }); - std::fs::create_dir(&krate_download_dir).unwrap_or_else(|err| { - if err.kind() != ErrorKind::AlreadyExists { - panic!("cannot create crate download dir"); - } - }); - std::fs::create_dir(&extract_dir).unwrap_or_else(|err| { - if err.kind() != ErrorKind::AlreadyExists { - panic!("cannot create crate extraction dir"); - } - }); + create_dirs(&krate_download_dir, &extract_dir); let krate_file_path = krate_download_dir.join(format!("{}-{}.crate.tar.gz", name, version)); // don't download/extract if we already have done so @@ -750,6 +736,29 @@ fn print_stats(old_stats: HashMap, new_stats: HashMap<&String, us }); } +/// Create necessary directories to run the lintcheck tool. +/// +/// # Panics +/// +/// This function panics if creating one of the dirs fails. +fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) { + std::fs::create_dir("target/lintcheck/").unwrap_or_else(|err| { + if err.kind() != ErrorKind::AlreadyExists { + panic!("cannot create lintcheck target dir"); + } + }); + std::fs::create_dir(&krate_download_dir).unwrap_or_else(|err| { + if err.kind() != ErrorKind::AlreadyExists { + panic!("cannot create crate download dir"); + } + }); + std::fs::create_dir(&extract_dir).unwrap_or_else(|err| { + if err.kind() != ErrorKind::AlreadyExists { + panic!("cannot create crate extraction dir"); + } + }); +} + #[test] fn lintcheck_test() { let args = [ From 45424c7e757fc15c4dfe5b0ba281863173d785f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 5 Mar 2021 09:30:12 +0100 Subject: [PATCH 110/226] lintcheck: add --fix mode which tries to apply lint suggestions to the sources and prints a warning if that fails Great for spotting false positives/broken suggestions of applicable lints. There are false positives though becasue I'm not sure yet how to silence rustc warnings while keeping clippy warnings. Sometimes rustc makes a suggestion that fails to apply and the implementation does not differenciate between clippy and rustc warnings when applying lint suggestions. changelog: none --- clippy_dev/src/lintcheck.rs | 49 ++++++++++++++++++++++++++++++++++--- clippy_dev/src/main.rs | 3 ++- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/clippy_dev/src/lintcheck.rs b/clippy_dev/src/lintcheck.rs index f01f14eb458fd..765d3349ec01f 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/clippy_dev/src/lintcheck.rs @@ -229,6 +229,7 @@ impl Crate { target_dir_index: &AtomicUsize, thread_limit: usize, total_crates_to_lint: usize, + fix: bool, ) -> Vec { // advance the atomic index by one let index = target_dir_index.fetch_add(1, Ordering::SeqCst); @@ -252,7 +253,18 @@ impl Crate { let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir"); - let mut args = vec!["--", "--message-format=json", "--", "--cap-lints=warn"]; + let mut args = if fix { + vec![ + "-Zunstable-options", + "--fix", + "-Zunstable-options", + "--allow-no-vcs", + "--", + "--cap-lints=warn", + ] + } else { + vec!["--", "--message-format=json", "--", "--cap-lints=warn"] + }; if let Some(options) = &self.options { for opt in options { @@ -282,6 +294,23 @@ impl Crate { ); }); let stdout = String::from_utf8_lossy(&all_output.stdout); + let stderr = String::from_utf8_lossy(&all_output.stderr); + + if fix { + if let Some(stderr) = stderr + .lines() + .find(|line| line.contains("failed to automatically apply fixes suggested by rustc to crate")) + { + let subcrate = &stderr[63..]; + println!( + "ERROR: failed to apply some suggetion to {} / to (sub)crate {}", + self.name, subcrate + ); + } + // fast path, we don't need the warnings anyway + return Vec::new(); + } + let output_lines = stdout.lines(); let warnings: Vec = output_lines .into_iter() @@ -289,6 +318,7 @@ impl Crate { .filter(|line| filter_clippy_warnings(&line)) .map(|json_msg| parse_json_message(json_msg, &self)) .collect(); + warnings } } @@ -301,6 +331,8 @@ struct LintcheckConfig { sources_toml_path: PathBuf, // we save the clippy lint results here lintcheck_results_path: PathBuf, + // whether to just run --fix and not collect all the warnings + fix: bool, } impl LintcheckConfig { @@ -342,11 +374,13 @@ impl LintcheckConfig { // no -j passed, use a single thread None => 1, }; + let fix: bool = clap_config.is_present("fix"); LintcheckConfig { max_jobs, sources_toml_path, lintcheck_results_path, + fix, } } } @@ -598,7 +632,7 @@ pub fn run(clap_config: &ArgMatches) { .into_iter() .map(|krate| krate.download_and_extract()) .filter(|krate| krate.name == only_one_crate) - .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, 1)) + .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, 1, config.fix)) .collect() } else { if config.max_jobs > 1 { @@ -621,7 +655,9 @@ pub fn run(clap_config: &ArgMatches) { crates .into_par_iter() .map(|krate| krate.download_and_extract()) - .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates)) + .flat_map(|krate| { + krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates, config.fix) + }) .collect() } else { // run sequential @@ -629,11 +665,16 @@ pub fn run(clap_config: &ArgMatches) { crates .into_iter() .map(|krate| krate.download_and_extract()) - .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, 1, num_crates)) + .flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, 1, num_crates, config.fix)) .collect() } }; + // if we are in --fix mode, don't change the log files, terminate here + if config.fix { + return; + } + // generate some stats let (stats_formatted, new_stats) = gather_stats(&clippy_warnings); diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index 505d465760c57..33fef18d553af 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -77,7 +77,8 @@ fn get_clap_config<'a>() -> ArgMatches<'a> { .short("j") .long("jobs") .help("number of threads to use, 0 automatic choice"), - ); + ) + .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply")); let app = App::new("Clippy developer tooling") .subcommand( From 45454f073894d9e211d086d0c5a0c91fa54f67a9 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 5 Mar 2021 10:13:59 -0600 Subject: [PATCH 111/226] Avoid mir in implicit_return --- clippy_lints/src/implicit_return.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index 109d90ff772b5..b4f814e1dcccf 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -1,4 +1,4 @@ -use crate::utils::{fn_has_unsatisfiable_preds, match_panic_def_id, snippet_opt, span_lint_and_then}; +use crate::utils::{match_panic_def_id, snippet_opt, span_lint_and_then}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; @@ -133,19 +133,13 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn { span: Span, _: HirId, ) { - let def_id = cx.tcx.hir().body_owner_def_id(body.id()); - - // Building MIR for `fn`s with unsatisfiable preds results in ICE. - if fn_has_unsatisfiable_preds(cx, def_id.to_def_id()) { + if span.from_expansion() { return; } - - let mir = cx.tcx.optimized_mir(def_id.to_def_id()); - - // checking return type through MIR, HIR is not able to determine inferred closure return types - // make sure it's not a macro - if !mir.return_ty().is_unit() && !span.from_expansion() { - expr_match(cx, &body.value); + let body = cx.tcx.hir().body(body.id()); + if cx.typeck_results().expr_ty(&body.value).is_unit() { + return; } + expr_match(cx, &body.value); } } From ae8ec07d2e4a4b97168bc02e9bbebb50dd695c1e Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 5 Mar 2021 10:32:15 -0600 Subject: [PATCH 112/226] Avoid mir in missing_errors_doc --- clippy_lints/src/doc.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 39a202f281cb7..99c084af1b0d0 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -325,9 +325,9 @@ fn lint_for_missing_headers<'tcx>( if_chain! { if let Some(body_id) = body_id; if let Some(future) = cx.tcx.lang_items().future_trait(); - let def_id = cx.tcx.hir().body_owner_def_id(body_id); - let mir = cx.tcx.optimized_mir(def_id.to_def_id()); - let ret_ty = mir.return_ty(); + let typeck = cx.tcx.typeck_body(body_id); + let body = cx.tcx.hir().body(body_id); + let ret_ty = typeck.expr_ty(&body.value); if implements_trait(cx, ret_ty, future, &[]); if let ty::Opaque(_, subs) = ret_ty.kind(); if let Some(gen) = subs.types().next(); From 5abd8c599505e637c3ea43605abfbb55da6e6849 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 5 Mar 2021 10:35:39 -0600 Subject: [PATCH 113/226] Use typeck_body --- clippy_lints/src/async_yields_async.rs | 3 +-- clippy_lints/src/await_holding_invalid.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/async_yields_async.rs b/clippy_lints/src/async_yields_async.rs index 88d9d3b5a263d..869a5c28d0511 100644 --- a/clippy_lints/src/async_yields_async.rs +++ b/clippy_lints/src/async_yields_async.rs @@ -50,8 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync { let body_id = BodyId { hir_id: body.value.hir_id, }; - let def_id = cx.tcx.hir().body_owner_def_id(body_id); - let typeck_results = cx.tcx.typeck(def_id); + let typeck_results = cx.tcx.typeck_body(body_id); let expr_ty = typeck_results.expr_ty(&body.value); if implements_trait(cx, expr_ty, future_trait_def_id, &[]) { diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index 112c5bb14e359..14b6a156c621e 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -97,8 +97,7 @@ impl LateLintPass<'_> for AwaitHolding { let body_id = BodyId { hir_id: body.value.hir_id, }; - let def_id = cx.tcx.hir().body_owner_def_id(body_id); - let typeck_results = cx.tcx.typeck(def_id); + let typeck_results = cx.tcx.typeck_body(body_id); check_interior_types( cx, &typeck_results.generator_interior_types.as_ref().skip_binder(), From a0b7f9b3a09c9dbb3a773b1b584abbf3c6f031c7 Mon Sep 17 00:00:00 2001 From: Mateusz Gacek <96mateusz.gacek@gmail.com> Date: Fri, 5 Mar 2021 12:11:31 -0800 Subject: [PATCH 114/226] useless_format: fix examples in the description "Good" example was something not acceptable by the useless_format lint. --- clippy_lints/src/format.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 8e41e0e34daf7..fd6bf19db94c8 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -28,11 +28,11 @@ declare_clippy_lint! { /// ```rust /// /// // Bad - /// # let foo = "foo"; + /// let foo = "foo"; /// format!("{}", foo); /// /// // Good - /// format!("foo"); + /// foo.to_owned(); /// ``` pub USELESS_FORMAT, complexity, From 0941fc0bb5d655cdd0816f862af8cfe70556dad6 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 3 Mar 2021 23:33:18 -0300 Subject: [PATCH 115/226] Make clippy set mir_opt_level using Option --- src/driver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/driver.rs b/src/driver.rs index d5143e1438ee0..94af21568ee80 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -83,7 +83,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // run on the unoptimized MIR. On the other hand this results in some false negatives. If // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. - config.opts.debugging_opts.mir_opt_level = 0; + config.opts.debugging_opts.mir_opt_level = Some(0); } } From e4ffff9e72f155dfcd1fda6042b725007973835d Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Tue, 2 Mar 2021 13:06:30 -0500 Subject: [PATCH 116/226] Use `LanguageItems::require` --- clippy_lints/src/lifetimes.rs | 2 +- clippy_lints/src/types.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 5fed58b821097..3807d346f6816 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -360,7 +360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { let trait_ref = &poly_tref.trait_ref; if CLOSURE_TRAIT_BOUNDS .iter() - .any(|&item| trait_ref.trait_def_id() == self.cx.tcx.lang_items().items()[item as usize]) + .any(|&item| trait_ref.trait_def_id() == self.cx.tcx.lang_items().require(item).ok()) { let mut sub_visitor = RefVisitor::new(self.cx); sub_visitor.visit_trait_ref(trait_ref); diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index d1d9ef7d90219..c420be26fc644 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -294,7 +294,7 @@ fn is_ty_param_lang_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: LangIt if let TyKind::Path(qpath) = &ty.kind { cx.qpath_res(qpath, ty.hir_id) .opt_def_id() - .and_then(|id| (cx.tcx.lang_items().items()[item as usize] == Some(id)).then(|| ty)) + .and_then(|id| (cx.tcx.lang_items().require(item) == Ok(id)).then(|| ty)) } else { None } @@ -431,7 +431,7 @@ impl Types { }; let inner_span = match get_qpath_generic_tys(qpath).next() { Some(ty) => ty.span, - _ => return, + None => return, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -467,7 +467,7 @@ impl Types { }; let inner_span = match get_qpath_generic_tys(qpath).next() { Some(ty) => ty.span, - _ => return, + None => return, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -517,7 +517,7 @@ impl Types { }; let inner_span = match get_qpath_generic_tys(qpath).next() { Some(ty) => ty.span, - _ => return, + None => return, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( From 47145dec36fbe99960f45ee7065261e2dcfed152 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 5 Mar 2021 13:01:13 -0500 Subject: [PATCH 117/226] `len_without_is_empty` will now consider multiple impl blocks `len_without_is_empty` will now consider `#[allow]` on both the `len` method, and the type definition --- clippy_lints/src/len_zero.rs | 166 ++++++++++++++++++++------- clippy_utils/src/lib.rs | 21 +++- tests/ui/len_without_is_empty.rs | 45 ++++++++ tests/ui/len_without_is_empty.stderr | 76 ++++++------ 4 files changed, 231 insertions(+), 77 deletions(-) diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index dab3e0565cafb..1e1023b274350 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,11 +1,17 @@ -use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg}; +use crate::utils::{ + get_item_name, get_parent_as_impl, is_allowed, snippet_with_applicability, span_lint, span_lint_and_sugg, + span_lint_and_then, +}; +use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir::def_id::DefId; -use rustc_hir::{AssocItemKind, BinOpKind, Expr, ExprKind, Impl, ImplItemRef, Item, ItemKind, TraitItemRef}; +use rustc_hir::{ + def_id::DefId, AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, ImplItem, ImplItemKind, ImplicitSelfKind, Item, + ItemKind, Mutability, Node, TraitItemRef, TyKind, +}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; +use rustc_middle::ty::{self, AssocKind, FnSig}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::{Span, Spanned, Symbol}; @@ -113,14 +119,38 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { return; } - match item.kind { - ItemKind::Trait(_, _, _, _, ref trait_items) => check_trait_items(cx, item, trait_items), - ItemKind::Impl(Impl { - of_trait: None, - items: ref impl_items, - .. - }) => check_impl_items(cx, item, impl_items), - _ => (), + if let ItemKind::Trait(_, _, _, _, ref trait_items) = item.kind { + check_trait_items(cx, item, trait_items); + } + } + + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { + if_chain! { + if item.ident.as_str() == "len"; + if let ImplItemKind::Fn(sig, _) = &item.kind; + if sig.decl.implicit_self.has_implicit_self(); + if cx.access_levels.is_exported(item.hir_id()); + if matches!(sig.decl.output, FnRetTy::Return(_)); + if let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id()); + if imp.of_trait.is_none(); + if let TyKind::Path(ty_path) = &imp.self_ty.kind; + if let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id(); + if let Some(local_id) = ty_id.as_local(); + let ty_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id); + if !is_allowed(cx, LEN_WITHOUT_IS_EMPTY, ty_hir_id); + then { + let (name, kind) = match cx.tcx.hir().find(ty_hir_id) { + Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"), + Some(Node::Item(x)) => match x.kind { + ItemKind::Struct(..) => (x.ident.name, "struct"), + ItemKind::Enum(..) => (x.ident.name, "enum"), + ItemKind::Union(..) => (x.ident.name, "union"), + _ => (x.ident.name, "type"), + } + _ => return, + }; + check_for_is_empty(cx, sig.span, sig.decl.implicit_self, ty_id, name, kind) + } } } @@ -202,40 +232,94 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items } } -fn check_impl_items(cx: &LateContext<'_>, item: &Item<'_>, impl_items: &[ImplItemRef<'_>]) { - fn is_named_self(cx: &LateContext<'_>, item: &ImplItemRef<'_>, name: &str) -> bool { - item.ident.name.as_str() == name - && if let AssocItemKind::Fn { has_self } = item.kind { - has_self && cx.tcx.fn_sig(item.id.def_id).inputs().skip_binder().len() == 1 - } else { - false - } +/// Checks if the given signature matches the expectations for `is_empty` +fn check_is_empty_sig(cx: &LateContext<'_>, sig: FnSig<'_>, self_kind: ImplicitSelfKind) -> bool { + match &**sig.inputs_and_output { + [arg, res] if *res == cx.tcx.types.bool => { + matches!( + (arg.kind(), self_kind), + (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::ImmRef) + | (ty::Ref(_, _, Mutability::Mut), ImplicitSelfKind::MutRef) + ) || (!arg.is_ref() && matches!(self_kind, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut)) + }, + _ => false, } +} - let is_empty = if let Some(is_empty) = impl_items.iter().find(|i| is_named_self(cx, i, "is_empty")) { - if cx.access_levels.is_exported(is_empty.id.hir_id()) { - return; - } - "a private" - } else { - "no corresponding" - }; - - if let Some(i) = impl_items.iter().find(|i| is_named_self(cx, i, "len")) { - if cx.access_levels.is_exported(i.id.hir_id()) { - let ty = cx.tcx.type_of(item.def_id); +/// Checks if the given type has an `is_empty` method with the appropriate signature. +fn check_for_is_empty( + cx: &LateContext<'_>, + span: Span, + self_kind: ImplicitSelfKind, + impl_ty: DefId, + item_name: Symbol, + item_kind: &str, +) { + let is_empty = Symbol::intern("is_empty"); + let is_empty = cx + .tcx + .inherent_impls(impl_ty) + .iter() + .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty)) + .find(|item| item.kind == AssocKind::Fn); - span_lint( - cx, - LEN_WITHOUT_IS_EMPTY, - item.span, - &format!( - "item `{}` has a public `len` method but {} `is_empty` method", - ty, is_empty + let (msg, is_empty_span, self_kind) = match is_empty { + None => ( + format!( + "{} `{}` has a public `len` method, but no `is_empty` method", + item_kind, + item_name.as_str(), + ), + None, + None, + ), + Some(is_empty) + if !cx + .access_levels + .is_exported(cx.tcx.hir().local_def_id_to_hir_id(is_empty.def_id.expect_local())) => + { + ( + format!( + "{} `{}` has a public `len` method, but a private `is_empty` method", + item_kind, + item_name.as_str(), ), - ); + Some(cx.tcx.def_span(is_empty.def_id)), + None, + ) + }, + Some(is_empty) + if !(is_empty.fn_has_self_parameter + && check_is_empty_sig(cx, cx.tcx.fn_sig(is_empty.def_id).skip_binder(), self_kind)) => + { + ( + format!( + "{} `{}` has a public `len` method, but the `is_empty` method has an unexpected signature", + item_kind, + item_name.as_str(), + ), + Some(cx.tcx.def_span(is_empty.def_id)), + Some(self_kind), + ) + }, + Some(_) => return, + }; + + span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, span, &msg, |db| { + if let Some(span) = is_empty_span { + db.span_note(span, "`is_empty` defined here"); } - } + if let Some(self_kind) = self_kind { + db.note(&format!( + "expected signature: `({}self) -> bool`", + match self_kind { + ImplicitSelfKind::ImmRef => "&", + ImplicitSelfKind::MutRef => "&mut ", + _ => "", + } + )); + } + }); } fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index daeced6bad483..6582ad7170717 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -63,9 +63,9 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::Node; use rustc_hir::{ - def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, GenericArgs, HirId, ImplItem, ImplItemKind, Item, - ItemKind, MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, TyKind, - Unsafety, + def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, + Item, ItemKind, MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, + TyKind, Unsafety, }; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, Level, Lint, LintContext}; @@ -1004,6 +1004,21 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio }) } +/// Gets the parent node if it's an impl block. +pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> { + let map = tcx.hir(); + match map.parent_iter(id).next() { + Some(( + _, + Node::Item(Item { + kind: ItemKind::Impl(imp), + .. + }), + )) => Some(imp), + _ => None, + } +} + /// Returns the base type for HIR references and pointers. pub fn walk_ptrs_hir_ty<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> { match ty.kind { diff --git a/tests/ui/len_without_is_empty.rs b/tests/ui/len_without_is_empty.rs index b5211318a1504..6b3636a482e95 100644 --- a/tests/ui/len_without_is_empty.rs +++ b/tests/ui/len_without_is_empty.rs @@ -34,6 +34,24 @@ impl PubAllowed { } } +pub struct PubAllowedFn; + +impl PubAllowedFn { + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> isize { + 1 + } +} + +#[allow(clippy::len_without_is_empty)] +pub struct PubAllowedStruct; + +impl PubAllowedStruct { + pub fn len(&self) -> isize { + 1 + } +} + pub trait PubTraitsToo { fn len(&self) -> isize; } @@ -68,6 +86,18 @@ impl HasWrongIsEmpty { } } +pub struct MismatchedSelf; + +impl MismatchedSelf { + pub fn len(self) -> isize { + 1 + } + + pub fn is_empty(&self) -> bool { + false + } +} + struct NotPubOne; impl NotPubOne { @@ -142,4 +172,19 @@ pub trait DependsOnFoo: Foo { fn len(&mut self) -> usize; } +pub struct MultipleImpls; + +// issue #1562 +impl MultipleImpls { + pub fn len(&self) -> usize { + 1 + } +} + +impl MultipleImpls { + pub fn is_empty(&self) -> bool { + false + } +} + fn main() {} diff --git a/tests/ui/len_without_is_empty.stderr b/tests/ui/len_without_is_empty.stderr index d79c300c07445..f106506faf49e 100644 --- a/tests/ui/len_without_is_empty.stderr +++ b/tests/ui/len_without_is_empty.stderr @@ -1,54 +1,64 @@ -error: item `PubOne` has a public `len` method but no corresponding `is_empty` method - --> $DIR/len_without_is_empty.rs:6:1 +error: struct `PubOne` has a public `len` method, but no `is_empty` method + --> $DIR/len_without_is_empty.rs:7:5 | -LL | / impl PubOne { -LL | | pub fn len(&self) -> isize { -LL | | 1 -LL | | } -LL | | } - | |_^ +LL | pub fn len(&self) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::len-without-is-empty` implied by `-D warnings` error: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` method - --> $DIR/len_without_is_empty.rs:37:1 + --> $DIR/len_without_is_empty.rs:55:1 | LL | / pub trait PubTraitsToo { LL | | fn len(&self) -> isize; LL | | } | |_^ -error: item `HasIsEmpty` has a public `len` method but a private `is_empty` method - --> $DIR/len_without_is_empty.rs:49:1 - | -LL | / impl HasIsEmpty { -LL | | pub fn len(&self) -> isize { -LL | | 1 -LL | | } -... | -LL | | } -LL | | } - | |_^ +error: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` method + --> $DIR/len_without_is_empty.rs:68:5 + | +LL | pub fn len(&self) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `is_empty` defined here + --> $DIR/len_without_is_empty.rs:72:5 + | +LL | fn is_empty(&self) -> bool { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: item `HasWrongIsEmpty` has a public `len` method but no corresponding `is_empty` method - --> $DIR/len_without_is_empty.rs:61:1 - | -LL | / impl HasWrongIsEmpty { -LL | | pub fn len(&self) -> isize { -LL | | 1 -LL | | } -... | -LL | | } -LL | | } - | |_^ +error: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` method has an unexpected signature + --> $DIR/len_without_is_empty.rs:80:5 + | +LL | pub fn len(&self) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `is_empty` defined here + --> $DIR/len_without_is_empty.rs:84:5 + | +LL | pub fn is_empty(&self, x: u32) -> bool { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected signature: `(&self) -> bool` + +error: struct `MismatchedSelf` has a public `len` method, but the `is_empty` method has an unexpected signature + --> $DIR/len_without_is_empty.rs:92:5 + | +LL | pub fn len(self) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `is_empty` defined here + --> $DIR/len_without_is_empty.rs:96:5 + | +LL | pub fn is_empty(&self) -> bool { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected signature: `(self) -> bool` error: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method - --> $DIR/len_without_is_empty.rs:141:1 + --> $DIR/len_without_is_empty.rs:171:1 | LL | / pub trait DependsOnFoo: Foo { LL | | fn len(&mut self) -> usize; LL | | } | |_^ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors From 3877a410beac040c0cea3dfa5402d7a2da19df40 Mon Sep 17 00:00:00 2001 From: Andrea Nall Date: Fri, 26 Feb 2021 19:10:17 -0600 Subject: [PATCH 118/226] migrate paths to newly-added diagnostic items This gets rid of the following paths: * OS_STRING * TO_OWNED * TO_STRING Also removes some usages of: * PATH_BUF And the now completely unused `clippy_lints::types::is_ty_param_path` --- clippy_lints/src/misc.rs | 20 +++++++++++++------- clippy_lints/src/path_buf_push_overwrite.rs | 5 +++-- clippy_lints/src/ptr.rs | 2 +- clippy_lints/src/redundant_clone.rs | 8 ++++---- clippy_lints/src/to_string_in_display.rs | 6 ++++-- clippy_lints/src/types.rs | 17 ++--------------- clippy_utils/src/paths.rs | 3 --- 7 files changed, 27 insertions(+), 34 deletions(-) diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 12f91d7bf639b..b9be1f7e60cb2 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -12,12 +12,13 @@ use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::{ExpnKind, Span}; +use rustc_span::symbol::sym; use crate::consts::{constant, Constant}; use crate::utils::sugg::Sugg; use crate::utils::{ - get_item_name, get_parent_expr, higher, implements_trait, in_constant, is_integer_const, iter_input_pats, - last_path_segment, match_qpath, match_trait_method, paths, snippet, snippet_opt, span_lint, span_lint_and_sugg, + get_item_name, get_parent_expr, higher, implements_trait, in_constant, is_diagnostic_assoc_item, is_integer_const, + iter_input_pats, last_path_segment, match_qpath, snippet, snippet_opt, span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then, unsext, SpanlessEq, }; @@ -554,11 +555,16 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: let (arg_ty, snip) = match expr.kind { ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => { - if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) { - (cx.typeck_results().expr_ty(&args[0]), snippet(cx, args[0].span, "..")) - } else { - return; - } + if_chain!( + if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); + if is_diagnostic_assoc_item(cx, expr_def_id, sym::ToString) + || is_diagnostic_assoc_item(cx, expr_def_id, sym::ToOwned); + then { + (cx.typeck_results().expr_ty(&args[0]), snippet(cx, args[0].span, "..")) + } else { + return; + } + ) }, ExprKind::Call(ref path, ref v) if v.len() == 1 => { if let ExprKind::Path(ref path) = path.kind { diff --git a/clippy_lints/src/path_buf_push_overwrite.rs b/clippy_lints/src/path_buf_push_overwrite.rs index 6eeb031d383c8..4a7b0ad07aaeb 100644 --- a/clippy_lints/src/path_buf_push_overwrite.rs +++ b/clippy_lints/src/path_buf_push_overwrite.rs @@ -1,10 +1,11 @@ -use crate::utils::{match_type, paths, span_lint_and_sugg}; +use crate::utils::{is_type_diagnostic_item, span_lint_and_sugg}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; use std::path::{Component, Path}; declare_clippy_lint! { @@ -46,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for PathBufPushOverwrite { if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if path.ident.name == sym!(push); if args.len() == 2; - if match_type(cx, cx.typeck_results().expr_ty(&args[0]).peel_refs(), &paths::PATH_BUF); + if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&args[0]).peel_refs(), sym::PathBuf); if let Some(get_index_arg) = args.get(1); if let ExprKind::Lit(ref lit) = get_index_arg.kind; if let LitKind::Str(ref path_lit, _) = lit.node; diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 5474fdf30bfaf..6ea2d8b06d81c 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -233,7 +233,7 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: }, ); } - } else if match_type(cx, ty, &paths::PATH_BUF) { + } else if is_type_diagnostic_item(cx, ty, sym::PathBuf) { if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_path_buf()"), ("as_path", "")]) { span_lint_and_then( cx, diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index d74ba10ac506f..99263bf8b5cf7 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -1,6 +1,6 @@ use crate::utils::{ - fn_has_unsatisfiable_preds, has_drop, is_copy, is_type_diagnostic_item, match_def_path, match_type, paths, - snippet_opt, span_lint_hir, span_lint_hir_and_then, walk_ptrs_ty_depth, + fn_has_unsatisfiable_preds, has_drop, is_copy, is_type_diagnostic_item, match_def_path, paths, snippet_opt, + span_lint_hir, span_lint_hir_and_then, walk_ptrs_ty_depth, }; use if_chain::if_chain; use rustc_data_structures::{fx::FxHashMap, transitive_relation::TransitiveRelation}; @@ -166,8 +166,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { is_call_with_ref_arg(cx, mir, &pred_terminator.kind); if res == cloned; if cx.tcx.is_diagnostic_item(sym::deref_method, pred_fn_def_id); - if match_type(cx, pred_arg_ty, &paths::PATH_BUF) - || match_type(cx, pred_arg_ty, &paths::OS_STRING); + if is_type_diagnostic_item(cx, pred_arg_ty, sym::PathBuf) + || is_type_diagnostic_item(cx, pred_arg_ty, sym::OsString); then { (pred_arg, res) } else { diff --git a/clippy_lints/src/to_string_in_display.rs b/clippy_lints/src/to_string_in_display.rs index fdd105e624605..84ec2aa18abcc 100644 --- a/clippy_lints/src/to_string_in_display.rs +++ b/clippy_lints/src/to_string_in_display.rs @@ -1,8 +1,9 @@ -use crate::utils::{match_def_path, match_trait_method, path_to_local_id, paths, span_lint}; +use crate::utils::{is_diagnostic_assoc_item, match_def_path, path_to_local_id, paths, span_lint}; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::symbol::sym; declare_clippy_lint! { /// **What it does:** Checks for uses of `to_string()` in `Display` traits. @@ -92,7 +93,8 @@ impl LateLintPass<'_> for ToStringInDisplay { if let Some(self_hir_id) = self.self_hir_id; if let ExprKind::MethodCall(ref path, _, args, _) = expr.kind; if path.ident.name == sym!(to_string); - if match_trait_method(cx, expr, &paths::TO_STRING); + if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); + if is_diagnostic_assoc_item(cx, expr_def_id, sym::ToString); if path_to_local_id(&args[0], self_hir_id); then { span_lint( diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index c420be26fc644..827c4a2aaf628 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -313,25 +313,12 @@ fn is_ty_param_diagnostic_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: } } -/// Checks if the first type parameter is a given item. -fn is_ty_param_path(cx: &LateContext<'_>, qpath: &QPath<'tcx>, path: &[&str]) -> Option<&'tcx hir::Ty<'tcx>> { - let ty = get_qpath_generic_tys(qpath).next()?; - - if let TyKind::Path(qpath) = &ty.kind { - cx.qpath_res(qpath, ty.hir_id) - .opt_def_id() - .and_then(|id| match_def_path(cx, id, path).then(|| ty)) - } else { - None - } -} - fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { if is_ty_param_diagnostic_item(cx, qpath, sym::string_type).is_some() { Some("str") - } else if is_ty_param_path(cx, qpath, &paths::OS_STRING).is_some() { + } else if is_ty_param_diagnostic_item(cx, qpath, sym::OsString).is_some() { Some("std::ffi::OsStr") - } else if is_ty_param_path(cx, qpath, &paths::PATH_BUF).is_some() { + } else if is_ty_param_diagnostic_item(cx, qpath, sym::PathBuf).is_some() { Some("std::path::Path") } else { None diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 14c38459ddeae..3e79646da3f45 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -84,7 +84,6 @@ pub const OPTION: [&str; 3] = ["core", "option", "Option"]; pub const OPTION_NONE: [&str; 4] = ["core", "option", "Option", "None"]; pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"]; pub const ORD: [&str; 3] = ["core", "cmp", "Ord"]; -pub const OS_STRING: [&str; 4] = ["std", "ffi", "os_str", "OsString"]; pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"]; pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"]; pub(super) const PANICKING_PANIC: [&str; 3] = ["core", "panicking", "panic"]; @@ -155,9 +154,7 @@ pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"]; #[cfg(feature = "internal-lints")] pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"]; -pub const TO_OWNED: [&str; 3] = ["alloc", "borrow", "ToOwned"]; pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"]; -pub const TO_STRING: [&str; 3] = ["alloc", "string", "ToString"]; pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"]; pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"]; pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"]; From 9bdc273f038dfa573d8fbd377c063f330922a048 Mon Sep 17 00:00:00 2001 From: Andrea Nall Date: Sun, 7 Mar 2021 17:58:39 -0600 Subject: [PATCH 119/226] relocate functions from `clippy_lints::types` relocate `is_ty_param_lang_item` and `is_ty_param_diagnostic_item` to `clippy_utils` --- clippy_lints/src/types.rs | 36 +++++------------------------------- clippy_utils/src/lib.rs | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 827c4a2aaf628..ce201b956d83d 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -23,7 +23,7 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::Span; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::sym; use rustc_target::abi::LayoutOf; use rustc_target::spec::abi::Abi; use rustc_typeck::hir_ty_to_ty; @@ -33,10 +33,10 @@ use crate::utils::paths; use crate::utils::sugg::Sugg; use crate::utils::{ clip, comparisons, differing_macro_contexts, get_qpath_generic_tys, higher, in_constant, indent_of, int_bits, - is_hir_ty_cfg_dependant, is_type_diagnostic_item, last_path_segment, match_def_path, match_path, meets_msrv, - method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, - snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, - span_lint_and_then, unsext, + is_hir_ty_cfg_dependant, is_ty_param_diagnostic_item, is_ty_param_lang_item, is_type_diagnostic_item, + last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args, multispan_sugg, + numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, + snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext, }; declare_clippy_lint! { @@ -287,32 +287,6 @@ impl<'tcx> LateLintPass<'tcx> for Types { } } -/// Checks if the first type parameter is a lang item. -fn is_ty_param_lang_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: LangItem) -> Option<&'tcx hir::Ty<'tcx>> { - let ty = get_qpath_generic_tys(qpath).next()?; - - if let TyKind::Path(qpath) = &ty.kind { - cx.qpath_res(qpath, ty.hir_id) - .opt_def_id() - .and_then(|id| (cx.tcx.lang_items().require(item) == Ok(id)).then(|| ty)) - } else { - None - } -} - -/// Checks if the first type parameter is a diagnostic item. -fn is_ty_param_diagnostic_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: Symbol) -> Option<&'tcx hir::Ty<'tcx>> { - let ty = get_qpath_generic_tys(qpath).next()?; - - if let TyKind::Path(qpath) = &ty.kind { - cx.qpath_res(qpath, ty.hir_id) - .opt_def_id() - .and_then(|id| cx.tcx.is_diagnostic_item(item, id).then(|| ty)) - } else { - None - } -} - fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { if is_ty_param_diagnostic_item(cx, qpath, sym::string_type).is_some() { Some("str") diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 6582ad7170717..3845667802d80 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -64,8 +64,8 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::Node; use rustc_hir::{ def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, - Item, ItemKind, MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, - TyKind, Unsafety, + Item, ItemKind, LangItem, MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, + TraitRef, TyKind, Unsafety, }; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, Level, Lint, LintContext}; @@ -232,6 +232,36 @@ pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangI } } +/// Checks if the first type parameter is a lang item. +pub fn is_ty_param_lang_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: LangItem) -> Option<&'tcx hir::Ty<'tcx>> { + let ty = get_qpath_generic_tys(qpath).next()?; + + if let TyKind::Path(qpath) = &ty.kind { + cx.qpath_res(qpath, ty.hir_id) + .opt_def_id() + .and_then(|id| (cx.tcx.lang_items().require(item) == Ok(id)).then(|| ty)) + } else { + None + } +} + +/// Checks if the first type parameter is a diagnostic item. +pub fn is_ty_param_diagnostic_item( + cx: &LateContext<'_>, + qpath: &QPath<'tcx>, + item: Symbol, +) -> Option<&'tcx hir::Ty<'tcx>> { + let ty = get_qpath_generic_tys(qpath).next()?; + + if let TyKind::Path(qpath) = &ty.kind { + cx.qpath_res(qpath, ty.hir_id) + .opt_def_id() + .and_then(|id| cx.tcx.is_diagnostic_item(item, id).then(|| ty)) + } else { + None + } +} + /// Checks if the method call given in `expr` belongs to the given trait. pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool { let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); From 06fe44e721a70ed3d36769632ee10893a487a7e3 Mon Sep 17 00:00:00 2001 From: Takayuki Nakata Date: Mon, 8 Mar 2021 09:27:59 +0900 Subject: [PATCH 120/226] Add msrv to contents in adding lints md --- doc/adding_lints.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/adding_lints.md b/doc/adding_lints.md index f62c2d29c707e..575853996c0ad 100644 --- a/doc/adding_lints.md +++ b/doc/adding_lints.md @@ -18,6 +18,7 @@ because that's clearly a non-descriptive name. - [Lint passes](#lint-passes) - [Emitting a lint](#emitting-a-lint) - [Adding the lint logic](#adding-the-lint-logic) + - [Specifying the lint's minimum supported Rust version (msrv)](#specifying-the-lints-minimum-supported-rust-version-msrv) - [Author lint](#author-lint) - [Documentation](#documentation) - [Running rustfmt](#running-rustfmt) From b27cbda32b67b4fdd9113ed894b810fc8f3e180d Mon Sep 17 00:00:00 2001 From: Andrea Nall Date: Sun, 7 Mar 2021 21:45:41 -0600 Subject: [PATCH 121/226] make is_normalizable more strict --- clippy_utils/src/lib.rs | 42 +++++++++++++++++++++++++++++++++--- tests/ui/crashes/ice-6840.rs | 23 ++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 tests/ui/crashes/ice-6840.rs diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 3845667802d80..999b39852cd50 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -85,6 +85,7 @@ use rustc_trait_selection::traits::query::normalize::AtExt; use smallvec::SmallVec; use crate::consts::{constant, Constant}; +use std::collections::HashMap; pub fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option) -> Option { if let Ok(version) = RustcVersion::parse(msrv) { @@ -1488,10 +1489,45 @@ pub fn match_function_call<'tcx>( /// Checks if `Ty` is normalizable. This function is useful /// to avoid crashes on `layout_of`. pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { - cx.tcx.infer_ctxt().enter(|infcx| { + is_normalizable_helper(cx, param_env, ty, &mut HashMap::new()) +} + +fn is_normalizable_helper<'tcx>( + cx: &LateContext<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, + cache: &mut HashMap, bool>, +) -> bool { + if let Some(&cached_result) = cache.get(ty) { + return cached_result; + } + cache.insert(ty, false); // prevent recursive loops + let result = cx.tcx.infer_ctxt().enter(|infcx| { let cause = rustc_middle::traits::ObligationCause::dummy(); - infcx.at(&cause, param_env).normalize(ty).is_ok() - }) + if infcx.at(&cause, param_env).normalize(ty).is_err() { + false + } else { + match ty.kind() { + ty::Adt(def, substs) => !def.variants.iter().any(|variant| { + variant + .fields + .iter() + .any(|field| !is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache)) + }), + ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { + is_normalizable_helper(cx, param_env, pointee, cache) + }, + ty::Array(inner_ty, _) | ty::Slice(inner_ty) => is_normalizable_helper(cx, param_env, inner_ty, cache), + ty::Tuple(tys) => !tys.iter().any(|inner| match inner.unpack() { + GenericArgKind::Type(inner_ty) => !is_normalizable_helper(cx, param_env, inner_ty, cache), + _ => false, + }), + _ => true, + } + } + }); + cache.insert(ty, result); + result } pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool { diff --git a/tests/ui/crashes/ice-6840.rs b/tests/ui/crashes/ice-6840.rs new file mode 100644 index 0000000000000..a749eefb6355a --- /dev/null +++ b/tests/ui/crashes/ice-6840.rs @@ -0,0 +1,23 @@ +//! This is a reproducer for the ICE 6840: https://github.com/rust-lang/rust-clippy/issues/6840. +//! The ICE is caused by `TyCtxt::layout_of` and `is_normalizable` not being strict enough +#![allow(dead_code)] +use std::collections::HashMap; + +pub trait Rule { + type DependencyKey; +} + +pub struct RuleEdges { + dependencies: R::DependencyKey, +} + +type RuleDependencyEdges = HashMap>; + +// and additional potential variants +type RuleDependencyEdgesArray = HashMap; 8]>; +type RuleDependencyEdgesSlice = HashMap]>; +type RuleDependencyEdgesRef = HashMap>; +type RuleDependencyEdgesRaw = HashMap>; +type RuleDependencyEdgesTuple = HashMap, RuleEdges)>; + +fn main() {} From 2d07c33c86c2576326c97bf6641621bdd90e934a Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Mon, 8 Mar 2021 18:28:43 +0800 Subject: [PATCH 122/226] Rename `ClippyArgsCallbacks` to `RustcCallbacks` --- src/driver.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/driver.rs b/src/driver.rs index 081a2ddeb1648..0fba41775aaf3 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -73,11 +73,13 @@ fn track_clippy_args(sess: &Session, args_env_var: &Option) { struct DefaultCallbacks; impl rustc_driver::Callbacks for DefaultCallbacks {} -struct ClippyArgsCallbacks { +/// This is different from `DefaultCallbacks` that it will inform Cargo to track the value of +/// `CLIPPY_ARGS` environment variable. +struct RustcCallbacks { clippy_args_var: Option, } -impl rustc_driver::Callbacks for ClippyArgsCallbacks { +impl rustc_driver::Callbacks for RustcCallbacks { fn config(&mut self, config: &mut interface::Config) { let previous = config.register_lints.take(); let clippy_args_var = self.clippy_args_var.take(); @@ -351,7 +353,7 @@ pub fn main() { if clippy_enabled { rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run() } else { - rustc_driver::RunCompiler::new(&args, &mut ClippyArgsCallbacks { clippy_args_var }).run() + rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run() } })) } From 2d53b6b82412a18734478c0086090dc3a2b5c5cc Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Mon, 8 Mar 2021 18:29:36 +0800 Subject: [PATCH 123/226] Move `test_no_deps_ignores_path_deps_in_workspaces()` out of `dogfood_subprojects()` --- tests/dogfood.rs | 158 +++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 2505836a5ed89..296eeb4aabd99 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -46,28 +46,73 @@ fn dogfood_clippy() { assert!(output.status.success()); } -#[test] -fn dogfood_subprojects() { - fn test_no_deps_ignores_path_deps_in_workspaces() { - if cargo::is_rustc_test_suite() { - return; - } - let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let target_dir = root.join("target").join("dogfood"); - let cwd = root.join("clippy_workspace_tests"); - - // Make sure we start with a clean state - Command::new("cargo") +fn test_no_deps_ignores_path_deps_in_workspaces() { + if cargo::is_rustc_test_suite() { + return; + } + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let target_dir = root.join("target").join("dogfood"); + let cwd = root.join("clippy_workspace_tests"); + + // Make sure we start with a clean state + Command::new("cargo") + .current_dir(&cwd) + .env("CARGO_TARGET_DIR", &target_dir) + .arg("clean") + .args(&["-p", "subcrate"]) + .args(&["-p", "path_dep"]) + .output() + .unwrap(); + + // `path_dep` is a path dependency of `subcrate` that would trigger a denied lint. + // Make sure that with the `--no-deps` argument Clippy does not run on `path_dep`. + let output = Command::new(&*CLIPPY_PATH) + .current_dir(&cwd) + .env("CLIPPY_DOGFOOD", "1") + .env("CARGO_INCREMENTAL", "0") + .arg("clippy") + .args(&["-p", "subcrate"]) + .arg("--") + .arg("--no-deps") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .args(&["--cfg", r#"feature="primary_package_test""#]) + .output() + .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + + assert!(output.status.success()); + + let lint_path_dep = || { + // Test that without the `--no-deps` argument, `path_dep` is linted. + let output = Command::new(&*CLIPPY_PATH) .current_dir(&cwd) - .env("CARGO_TARGET_DIR", &target_dir) - .arg("clean") + .env("CLIPPY_DOGFOOD", "1") + .env("CARGO_INCREMENTAL", "0") + .arg("clippy") .args(&["-p", "subcrate"]) - .args(&["-p", "path_dep"]) + .arg("--") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .args(&["--cfg", r#"feature="primary_package_test""#]) .output() .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + + assert!(!output.status.success()); + assert!( + String::from_utf8(output.stderr) + .unwrap() + .contains("error: empty `loop {}` wastes CPU cycles") + ); + }; + + // Make sure Cargo is aware of the removal of `--no-deps`. + lint_path_dep(); - // `path_dep` is a path dependency of `subcrate` that would trigger a denied lint. - // Make sure that with the `--no-deps` argument Clippy does not run on `path_dep`. + let successful_build = || { let output = Command::new(&*CLIPPY_PATH) .current_dir(&cwd) .env("CLIPPY_DOGFOOD", "1") @@ -75,9 +120,7 @@ fn dogfood_subprojects() { .arg("clippy") .args(&["-p", "subcrate"]) .arg("--") - .arg("--no-deps") .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir - .args(&["--cfg", r#"feature="primary_package_test""#]) .output() .unwrap(); println!("status: {}", output.status); @@ -86,67 +129,24 @@ fn dogfood_subprojects() { assert!(output.status.success()); - let lint_path_dep = || { - // Test that without the `--no-deps` argument, `path_dep` is linted. - let output = Command::new(&*CLIPPY_PATH) - .current_dir(&cwd) - .env("CLIPPY_DOGFOOD", "1") - .env("CARGO_INCREMENTAL", "0") - .arg("clippy") - .args(&["-p", "subcrate"]) - .arg("--") - .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir - .args(&["--cfg", r#"feature="primary_package_test""#]) - .output() - .unwrap(); - println!("status: {}", output.status); - println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); - println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); - - assert!(!output.status.success()); - assert!( - String::from_utf8(output.stderr) - .unwrap() - .contains("error: empty `loop {}` wastes CPU cycles") - ); - }; - - // Make sure Cargo is aware of the removal of `--no-deps`. - lint_path_dep(); - - let successful_build = || { - let output = Command::new(&*CLIPPY_PATH) - .current_dir(&cwd) - .env("CLIPPY_DOGFOOD", "1") - .env("CARGO_INCREMENTAL", "0") - .arg("clippy") - .args(&["-p", "subcrate"]) - .arg("--") - .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir - .output() - .unwrap(); - println!("status: {}", output.status); - println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); - println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); - - assert!(output.status.success()); - - output - }; - - // Trigger a sucessful build, so Cargo would like to cache the build result. - successful_build(); - - // Make sure there's no spurious rebuild when nothing changes. - let stderr = String::from_utf8(successful_build().stderr).unwrap(); - assert!(!stderr.contains("Compiling")); - assert!(!stderr.contains("Checking")); - assert!(stderr.contains("Finished")); - - // Make sure Cargo is aware of the new `--cfg` flag. - lint_path_dep(); - } + output + }; + + // Trigger a sucessful build, so Cargo would like to cache the build result. + successful_build(); + + // Make sure there's no spurious rebuild when nothing changes. + let stderr = String::from_utf8(successful_build().stderr).unwrap(); + assert!(!stderr.contains("Compiling")); + assert!(!stderr.contains("Checking")); + assert!(stderr.contains("Finished")); + // Make sure Cargo is aware of the new `--cfg` flag. + lint_path_dep(); +} + +#[test] +fn dogfood_subprojects() { // run clippy on remaining subprojects and fail the test if lint warnings are reported if cargo::is_rustc_test_suite() { return; From 3cd5f44ec463fa0c9376ad7e3d7b8e19e662bd8c Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Mon, 8 Mar 2021 18:49:41 +0800 Subject: [PATCH 124/226] Don't panic if `CLIPPY_ARGS` is not Unicode --- src/driver.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/driver.rs b/src/driver.rs index 0fba41775aaf3..82582db0b5ef8 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -20,7 +20,7 @@ use rustc_span::symbol::Symbol; use rustc_tools_util::VersionInfo; use std::borrow::Cow; -use std::env::{self, VarError}; +use std::env; use std::lazy::SyncLazy; use std::ops::Deref; use std::panic; @@ -314,13 +314,7 @@ pub fn main() { }; let mut no_deps = false; - let clippy_args_var = env::var("CLIPPY_ARGS").map_or_else( - |e| match e { - VarError::NotPresent => None, - VarError::NotUnicode(s) => panic!("CLIPPY_ARGS is not valid Unicode: {:?}", s), - }, - Some, - ); + let clippy_args_var = env::var("CLIPPY_ARGS").ok(); let clippy_args = clippy_args_var .as_deref() .unwrap_or_default() From 714a826439b4e61485e3afdfae8c08924120960a Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Thu, 11 Feb 2021 13:54:35 +0900 Subject: [PATCH 125/226] Create types dir and move old module under it --- clippy_lints/src/{types.rs => types/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clippy_lints/src/{types.rs => types/mod.rs} (100%) diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types/mod.rs similarity index 100% rename from clippy_lints/src/types.rs rename to clippy_lints/src/types/mod.rs From df307c0ce73552045e81ee8237d3cb582af0e7e7 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Thu, 11 Feb 2021 17:32:46 +0900 Subject: [PATCH 126/226] Move box_vec to its own module --- clippy_lints/src/types/box_vec.rs | 22 ++++++++++++++++++++++ clippy_lints/src/types/mod.rs | 14 +++----------- 2 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 clippy_lints/src/types/box_vec.rs diff --git a/clippy_lints/src/types/box_vec.rs b/clippy_lints/src/types/box_vec.rs new file mode 100644 index 0000000000000..14f09ab837f34 --- /dev/null +++ b/clippy_lints/src/types/box_vec.rs @@ -0,0 +1,22 @@ +use rustc_hir::{self as hir, def_id::DefId, QPath}; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +use crate::utils::{is_ty_param_diagnostic_item, span_lint_and_help}; + +use super::BOX_VEC; + +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) { + if Some(def_id) == cx.tcx.lang_items().owned_box() { + if is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() { + span_lint_and_help( + cx, + BOX_VEC, + hir_ty.span, + "you seem to be trying to use `Box>`. Consider using just `Vec`", + None, + "`Vec` is already on the heap, `Box>` makes an extra allocation", + ); + } + } +} diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index ce201b956d83d..b5ba2c58a81c3 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -1,5 +1,7 @@ #![allow(rustc::default_hash_types)] +mod box_vec; + use std::borrow::Cow; use std::cmp::Ordering; use std::collections::BTreeMap; @@ -346,6 +348,7 @@ impl Types { let hir_id = hir_ty.hir_id; let res = cx.qpath_res(qpath, hir_id); if let Some(def_id) = res.opt_def_id() { + box_vec::check(cx, hir_ty, qpath, def_id); if Some(def_id) == cx.tcx.lang_items().owned_box() { if let Some(span) = match_borrows_parameter(cx, qpath) { let mut applicability = Applicability::MachineApplicable; @@ -360,17 +363,6 @@ impl Types { ); return; // don't recurse into the type } - if is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() { - span_lint_and_help( - cx, - BOX_VEC, - hir_ty.span, - "you seem to be trying to use `Box>`. Consider using just `Vec`", - None, - "`Vec` is already on the heap, `Box>` makes an extra allocation", - ); - return; // don't recurse into the type - } } else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) { let mut applicability = Applicability::MachineApplicable; From 128f1f5e2eb717fd5d8c68b6ec772fe4b808cd20 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Thu, 11 Feb 2021 17:41:14 +0900 Subject: [PATCH 127/226] Move redundant_allocation to its own module --- clippy_lints/src/types/mod.rs | 98 ++----------------- .../src/types/redundant_allocation.rs | 78 +++++++++++++++ clippy_lints/src/types/utils.rs | 24 +++++ 3 files changed, 112 insertions(+), 88 deletions(-) create mode 100644 clippy_lints/src/types/redundant_allocation.rs create mode 100644 clippy_lints/src/types/utils.rs diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index b5ba2c58a81c3..cc6ff731ffcd3 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -1,6 +1,8 @@ #![allow(rustc::default_hash_types)] mod box_vec; +mod redundant_allocation; +mod utils; use std::borrow::Cow; use std::cmp::Ordering; @@ -13,8 +15,8 @@ use rustc_hir as hir; use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; use rustc_hir::{ BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericBounds, GenericParamKind, HirId, - ImplItem, ImplItemKind, Item, ItemKind, LangItem, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node, - QPath, Stmt, StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp, + ImplItem, ImplItemKind, Item, ItemKind, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt, + StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -35,10 +37,10 @@ use crate::utils::paths; use crate::utils::sugg::Sugg; use crate::utils::{ clip, comparisons, differing_macro_contexts, get_qpath_generic_tys, higher, in_constant, indent_of, int_bits, - is_hir_ty_cfg_dependant, is_ty_param_diagnostic_item, is_ty_param_lang_item, is_type_diagnostic_item, - last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args, multispan_sugg, - numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, - snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext, + is_hir_ty_cfg_dependant, is_ty_param_diagnostic_item, is_type_diagnostic_item, last_path_segment, match_def_path, + match_path, meets_msrv, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, + sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, + span_lint_and_sugg, span_lint_and_then, unsext, }; declare_clippy_lint! { @@ -301,23 +303,6 @@ fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static } } -fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option { - let last = last_path_segment(qpath); - if_chain! { - if let Some(ref params) = last.args; - if !params.parenthesized; - if let Some(ty) = params.args.iter().find_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty), - _ => None, - }); - if let TyKind::Rptr(..) = ty.kind; - then { - return Some(ty.span); - } - } - None -} - impl Types { pub fn new(vec_box_size_threshold: u64) -> Self { Self { vec_box_size_threshold } @@ -349,58 +334,8 @@ impl Types { let res = cx.qpath_res(qpath, hir_id); if let Some(def_id) = res.opt_def_id() { box_vec::check(cx, hir_ty, qpath, def_id); - if Some(def_id) == cx.tcx.lang_items().owned_box() { - if let Some(span) = match_borrows_parameter(cx, qpath) { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Box<&T>`", - "try", - snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), - applicability, - ); - return; // don't recurse into the type - } - } else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { - if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Rc>`", - "try", - snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(), - applicability, - ); - return; // don't recurse into the type - } - if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) { - let qpath = match &ty.kind { - TyKind::Path(qpath) => qpath, - _ => return, - }; - let inner_span = match get_qpath_generic_tys(qpath).next() { - Some(ty) => ty.span, - None => return, - }; - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Rc>`", - "try", - format!( - "Rc<{}>", - snippet_with_applicability(cx, inner_span, "..", &mut applicability) - ), - applicability, - ); - return; // don't recurse into the type - } + redundant_allocation::check(cx, hir_ty, qpath, def_id); + if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { if let Some(alternate) = match_buffer_type(cx, qpath) { span_lint_and_sugg( cx, @@ -437,19 +372,6 @@ impl Types { ); return; // don't recurse into the type } - if let Some(span) = match_borrows_parameter(cx, qpath) { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Rc<&T>`", - "try", - snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), - applicability, - ); - return; // don't recurse into the type - } } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) { if let Some(alternate) = match_buffer_type(cx, qpath) { span_lint_and_sugg( diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs new file mode 100644 index 0000000000000..8280b2c5629cf --- /dev/null +++ b/clippy_lints/src/types/redundant_allocation.rs @@ -0,0 +1,78 @@ +use rustc_errors::Applicability; +use rustc_hir::{self as hir, def_id::DefId, LangItem, QPath, TyKind}; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +use crate::utils::{ + get_qpath_generic_tys, is_ty_param_diagnostic_item, is_ty_param_lang_item, snippet_with_applicability, + span_lint_and_sugg, +}; + +use super::{utils, REDUNDANT_ALLOCATION}; + +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) { + if Some(def_id) == cx.tcx.lang_items().owned_box() { + if let Some(span) = utils::match_borrows_parameter(cx, qpath) { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + REDUNDANT_ALLOCATION, + hir_ty.span, + "usage of `Box<&T>`", + "try", + snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), + applicability, + ); + return; + } + } + + if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { + if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + REDUNDANT_ALLOCATION, + hir_ty.span, + "usage of `Rc>`", + "try", + snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(), + applicability, + ); + } else if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) { + let qpath = match &ty.kind { + TyKind::Path(qpath) => qpath, + _ => return, + }; + let inner_span = match get_qpath_generic_tys(qpath).next() { + Some(ty) => ty.span, + None => return, + }; + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + REDUNDANT_ALLOCATION, + hir_ty.span, + "usage of `Rc>`", + "try", + format!( + "Rc<{}>", + snippet_with_applicability(cx, inner_span, "..", &mut applicability) + ), + applicability, + ); + } else if let Some(span) = utils::match_borrows_parameter(cx, qpath) { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + REDUNDANT_ALLOCATION, + hir_ty.span, + "usage of `Rc<&T>`", + "try", + snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), + applicability, + ); + return; // don't recurse into the type + } + } +} diff --git a/clippy_lints/src/types/utils.rs b/clippy_lints/src/types/utils.rs new file mode 100644 index 0000000000000..4d64748f998a4 --- /dev/null +++ b/clippy_lints/src/types/utils.rs @@ -0,0 +1,24 @@ +use rustc_hir::{GenericArg, QPath, TyKind}; +use rustc_lint::LateContext; +use rustc_span::source_map::Span; + +use crate::utils::last_path_segment; + +use if_chain::if_chain; + +pub(super) fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option { + let last = last_path_segment(qpath); + if_chain! { + if let Some(ref params) = last.args; + if !params.parenthesized; + if let Some(ty) = params.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + _ => None, + }); + if let TyKind::Rptr(..) = ty.kind; + then { + return Some(ty.span); + } + } + None +} From f110c5e6f51eea87e37503819addbd1bd054416a Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 12 Feb 2021 12:09:36 +0900 Subject: [PATCH 128/226] Move rc_buffer to its own module --- clippy_lints/src/types/mod.rs | 100 +++------------------------- clippy_lints/src/types/rc_buffer.rs | 94 ++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 92 deletions(-) create mode 100644 clippy_lints/src/types/rc_buffer.rs diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index cc6ff731ffcd3..6c6e204257f62 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -1,6 +1,7 @@ #![allow(rustc::default_hash_types)] mod box_vec; +mod rc_buffer; mod redundant_allocation; mod utils; @@ -36,11 +37,11 @@ use crate::consts::{constant, Constant}; use crate::utils::paths; use crate::utils::sugg::Sugg; use crate::utils::{ - clip, comparisons, differing_macro_contexts, get_qpath_generic_tys, higher, in_constant, indent_of, int_bits, - is_hir_ty_cfg_dependant, is_ty_param_diagnostic_item, is_type_diagnostic_item, last_path_segment, match_def_path, - match_path, meets_msrv, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, - sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, - span_lint_and_sugg, span_lint_and_then, unsext, + clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant, + is_ty_param_diagnostic_item, is_type_diagnostic_item, last_path_segment, match_def_path, match_path, meets_msrv, + method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, + snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, + span_lint_and_then, unsext, }; declare_clippy_lint! { @@ -291,18 +292,6 @@ impl<'tcx> LateLintPass<'tcx> for Types { } } -fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { - if is_ty_param_diagnostic_item(cx, qpath, sym::string_type).is_some() { - Some("str") - } else if is_ty_param_diagnostic_item(cx, qpath, sym::OsString).is_some() { - Some("std::ffi::OsStr") - } else if is_ty_param_diagnostic_item(cx, qpath, sym::PathBuf).is_some() { - Some("std::path::Path") - } else { - None - } -} - impl Types { pub fn new(vec_box_size_threshold: u64) -> Self { Self { vec_box_size_threshold } @@ -335,81 +324,8 @@ impl Types { if let Some(def_id) = res.opt_def_id() { box_vec::check(cx, hir_ty, qpath, def_id); redundant_allocation::check(cx, hir_ty, qpath, def_id); - if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { - if let Some(alternate) = match_buffer_type(cx, qpath) { - span_lint_and_sugg( - cx, - RC_BUFFER, - hir_ty.span, - "usage of `Rc` when T is a buffer type", - "try", - format!("Rc<{}>", alternate), - Applicability::MachineApplicable, - ); - return; // don't recurse into the type - } - if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { - let qpath = match &ty.kind { - TyKind::Path(qpath) => qpath, - _ => return, - }; - let inner_span = match get_qpath_generic_tys(qpath).next() { - Some(ty) => ty.span, - None => return, - }; - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - RC_BUFFER, - hir_ty.span, - "usage of `Rc` when T is a buffer type", - "try", - format!( - "Rc<[{}]>", - snippet_with_applicability(cx, inner_span, "..", &mut applicability) - ), - Applicability::MachineApplicable, - ); - return; // don't recurse into the type - } - } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) { - if let Some(alternate) = match_buffer_type(cx, qpath) { - span_lint_and_sugg( - cx, - RC_BUFFER, - hir_ty.span, - "usage of `Arc` when T is a buffer type", - "try", - format!("Arc<{}>", alternate), - Applicability::MachineApplicable, - ); - return; // don't recurse into the type - } - if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { - let qpath = match &ty.kind { - TyKind::Path(qpath) => qpath, - _ => return, - }; - let inner_span = match get_qpath_generic_tys(qpath).next() { - Some(ty) => ty.span, - None => return, - }; - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - RC_BUFFER, - hir_ty.span, - "usage of `Arc` when T is a buffer type", - "try", - format!( - "Arc<[{}]>", - snippet_with_applicability(cx, inner_span, "..", &mut applicability) - ), - Applicability::MachineApplicable, - ); - return; // don't recurse into the type - } - } else if cx.tcx.is_diagnostic_item(sym::vec_type, def_id) { + rc_buffer::check(cx, hir_ty, qpath, def_id); + if cx.tcx.is_diagnostic_item(sym::vec_type, def_id) { if_chain! { // Get the _ part of Vec<_> if let Some(ref last) = last_path_segment(qpath).args; diff --git a/clippy_lints/src/types/rc_buffer.rs b/clippy_lints/src/types/rc_buffer.rs new file mode 100644 index 0000000000000..11e25c8bdcb0d --- /dev/null +++ b/clippy_lints/src/types/rc_buffer.rs @@ -0,0 +1,94 @@ +use rustc_errors::Applicability; +use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind}; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +use crate::utils::{ + get_qpath_generic_tys, is_ty_param_diagnostic_item, snippet_with_applicability, span_lint_and_sugg, +}; + +use super::RC_BUFFER; + +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) { + if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { + if let Some(alternate) = match_buffer_type(cx, qpath) { + span_lint_and_sugg( + cx, + RC_BUFFER, + hir_ty.span, + "usage of `Rc` when T is a buffer type", + "try", + format!("Rc<{}>", alternate), + Applicability::MachineApplicable, + ); + } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { + let qpath = match &ty.kind { + TyKind::Path(qpath) => qpath, + _ => return, + }; + let inner_span = match get_qpath_generic_tys(qpath).next() { + Some(ty) => ty.span, + None => return, + }; + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + RC_BUFFER, + hir_ty.span, + "usage of `Rc` when T is a buffer type", + "try", + format!( + "Rc<[{}]>", + snippet_with_applicability(cx, inner_span, "..", &mut applicability) + ), + Applicability::MachineApplicable, + ); + } + } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) { + if let Some(alternate) = match_buffer_type(cx, qpath) { + span_lint_and_sugg( + cx, + RC_BUFFER, + hir_ty.span, + "usage of `Arc` when T is a buffer type", + "try", + format!("Arc<{}>", alternate), + Applicability::MachineApplicable, + ); + } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { + let qpath = match &ty.kind { + TyKind::Path(qpath) => qpath, + _ => return, + }; + let inner_span = match get_qpath_generic_tys(qpath).next() { + Some(ty) => ty.span, + None => return, + }; + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + RC_BUFFER, + hir_ty.span, + "usage of `Arc` when T is a buffer type", + "try", + format!( + "Arc<[{}]>", + snippet_with_applicability(cx, inner_span, "..", &mut applicability) + ), + Applicability::MachineApplicable, + ); + } + } +} + +fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { + if is_ty_param_diagnostic_item(cx, qpath, sym::string_type).is_some() { + Some("str") + } else if is_ty_param_diagnostic_item(cx, qpath, sym::OsString).is_some() { + Some("std::ffi::OsStr") + } else if is_ty_param_diagnostic_item(cx, qpath, sym::PathBuf).is_some() { + Some("std::path::Path") + } else { + None + } +} From 2c2fb3996f8b0db6537a2a9d193af89304cd62ed Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 12 Feb 2021 14:00:17 +0900 Subject: [PATCH 129/226] Move vec_box to its own module --- clippy_lints/src/types/mod.rs | 47 ++++-------------------- clippy_lints/src/types/vec_box.rs | 59 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 41 deletions(-) create mode 100644 clippy_lints/src/types/vec_box.rs diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 6c6e204257f62..8d866568df938 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -4,6 +4,7 @@ mod box_vec; mod rc_buffer; mod redundant_allocation; mod utils; +mod vec_box; use std::borrow::Cow; use std::cmp::Ordering; @@ -22,7 +23,6 @@ use rustc_hir::{ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TyS, TypeAndMut, TypeckResults, UintTy}; use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; @@ -38,8 +38,8 @@ use crate::utils::paths; use crate::utils::sugg::Sugg; use crate::utils::{ clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant, - is_ty_param_diagnostic_item, is_type_diagnostic_item, last_path_segment, match_def_path, match_path, meets_msrv, - method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, + is_ty_param_diagnostic_item, is_type_diagnostic_item, match_def_path, match_path, meets_msrv, method_chain_args, + multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext, }; @@ -325,44 +325,9 @@ impl Types { box_vec::check(cx, hir_ty, qpath, def_id); redundant_allocation::check(cx, hir_ty, qpath, def_id); rc_buffer::check(cx, hir_ty, qpath, def_id); - if cx.tcx.is_diagnostic_item(sym::vec_type, def_id) { - if_chain! { - // Get the _ part of Vec<_> - if let Some(ref last) = last_path_segment(qpath).args; - if let Some(ty) = last.args.iter().find_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty), - _ => None, - }); - // ty is now _ at this point - if let TyKind::Path(ref ty_qpath) = ty.kind; - let res = cx.qpath_res(ty_qpath, ty.hir_id); - if let Some(def_id) = res.opt_def_id(); - if Some(def_id) == cx.tcx.lang_items().owned_box(); - // At this point, we know ty is Box, now get T - if let Some(ref last) = last_path_segment(ty_qpath).args; - if let Some(boxed_ty) = last.args.iter().find_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty), - _ => None, - }); - let ty_ty = hir_ty_to_ty(cx.tcx, boxed_ty); - if !ty_ty.has_escaping_bound_vars(); - if ty_ty.is_sized(cx.tcx.at(ty.span), cx.param_env); - if let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes()); - if ty_ty_size <= self.vec_box_size_threshold; - then { - span_lint_and_sugg( - cx, - VEC_BOX, - hir_ty.span, - "`Vec` is already on the heap, the boxing is unnecessary", - "try", - format!("Vec<{}>", snippet(cx, boxed_ty.span, "..")), - Applicability::MachineApplicable, - ); - return; // don't recurse into the type - } - } - } else if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { + vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold); + + if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { span_lint( cx, diff --git a/clippy_lints/src/types/vec_box.rs b/clippy_lints/src/types/vec_box.rs new file mode 100644 index 0000000000000..2964abf3492eb --- /dev/null +++ b/clippy_lints/src/types/vec_box.rs @@ -0,0 +1,59 @@ +use rustc_errors::Applicability; +use rustc_hir::{self as hir, def_id::DefId, GenericArg, QPath, TyKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::TypeFoldable; +use rustc_span::symbol::sym; +use rustc_target::abi::LayoutOf; +use rustc_typeck::hir_ty_to_ty; + +use if_chain::if_chain; + +use crate::utils::{last_path_segment, snippet, span_lint_and_sugg}; + +use super::VEC_BOX; + +pub(super) fn check( + cx: &LateContext<'_>, + hir_ty: &hir::Ty<'_>, + qpath: &QPath<'_>, + def_id: DefId, + box_size_threshold: u64, +) { + if cx.tcx.is_diagnostic_item(sym::vec_type, def_id) { + if_chain! { + // Get the _ part of Vec<_> + if let Some(ref last) = last_path_segment(qpath).args; + if let Some(ty) = last.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + _ => None, + }); + // ty is now _ at this point + if let TyKind::Path(ref ty_qpath) = ty.kind; + let res = cx.qpath_res(ty_qpath, ty.hir_id); + if let Some(def_id) = res.opt_def_id(); + if Some(def_id) == cx.tcx.lang_items().owned_box(); + // At this point, we know ty is Box, now get T + if let Some(ref last) = last_path_segment(ty_qpath).args; + if let Some(boxed_ty) = last.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + _ => None, + }); + let ty_ty = hir_ty_to_ty(cx.tcx, boxed_ty); + if !ty_ty.has_escaping_bound_vars(); + if ty_ty.is_sized(cx.tcx.at(ty.span), cx.param_env); + if let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes()); + if ty_ty_size <= box_size_threshold; + then { + span_lint_and_sugg( + cx, + VEC_BOX, + hir_ty.span, + "`Vec` is already on the heap, the boxing is unnecessary", + "try", + format!("Vec<{}>", snippet(cx, boxed_ty.span, "..")), + Applicability::MachineApplicable, + ); + } + } + } +} From fbd25e93a4ab7b7d357452f7c59f846e984b5d74 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 12 Feb 2021 14:11:04 +0900 Subject: [PATCH 130/226] Add flags to detect lints are triggered --- clippy_lints/src/types/box_vec.rs | 4 +++- clippy_lints/src/types/mod.rs | 13 +++++++++---- clippy_lints/src/types/rc_buffer.rs | 14 +++++++++----- clippy_lints/src/types/redundant_allocation.rs | 16 +++++++++++----- clippy_lints/src/types/vec_box.rs | 7 ++++++- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/types/box_vec.rs b/clippy_lints/src/types/box_vec.rs index 14f09ab837f34..4eb032cae6b1a 100644 --- a/clippy_lints/src/types/box_vec.rs +++ b/clippy_lints/src/types/box_vec.rs @@ -6,7 +6,7 @@ use crate::utils::{is_ty_param_diagnostic_item, span_lint_and_help}; use super::BOX_VEC; -pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) { +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { if Some(def_id) == cx.tcx.lang_items().owned_box() { if is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() { span_lint_and_help( @@ -17,6 +17,8 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ None, "`Vec` is already on the heap, `Box>` makes an extra allocation", ); + return true; } } + false } diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 8d866568df938..8506f362517aa 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -322,10 +322,11 @@ impl Types { let hir_id = hir_ty.hir_id; let res = cx.qpath_res(qpath, hir_id); if let Some(def_id) = res.opt_def_id() { - box_vec::check(cx, hir_ty, qpath, def_id); - redundant_allocation::check(cx, hir_ty, qpath, def_id); - rc_buffer::check(cx, hir_ty, qpath, def_id); - vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold); + let mut triggered = false; + triggered |= box_vec::check(cx, hir_ty, qpath, def_id); + triggered |= redundant_allocation::check(cx, hir_ty, qpath, def_id); + triggered |= rc_buffer::check(cx, hir_ty, qpath, def_id); + triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold); if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { @@ -349,6 +350,10 @@ impl Types { ); return; // don't recurse into the type } + + if triggered { + return; + } } match *qpath { QPath::Resolved(Some(ref ty), ref p) => { diff --git a/clippy_lints/src/types/rc_buffer.rs b/clippy_lints/src/types/rc_buffer.rs index 11e25c8bdcb0d..e34b95147e10a 100644 --- a/clippy_lints/src/types/rc_buffer.rs +++ b/clippy_lints/src/types/rc_buffer.rs @@ -9,7 +9,7 @@ use crate::utils::{ use super::RC_BUFFER; -pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) { +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { if let Some(alternate) = match_buffer_type(cx, qpath) { span_lint_and_sugg( @@ -24,11 +24,11 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { let qpath = match &ty.kind { TyKind::Path(qpath) => qpath, - _ => return, + _ => return false, }; let inner_span = match get_qpath_generic_tys(qpath).next() { Some(ty) => ty.span, - None => return, + None => return false, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -43,6 +43,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ ), Applicability::MachineApplicable, ); + return true; } } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) { if let Some(alternate) = match_buffer_type(cx, qpath) { @@ -58,11 +59,11 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::vec_type) { let qpath = match &ty.kind { TyKind::Path(qpath) => qpath, - _ => return, + _ => return false, }; let inner_span = match get_qpath_generic_tys(qpath).next() { Some(ty) => ty.span, - None => return, + None => return false, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -77,8 +78,11 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ ), Applicability::MachineApplicable, ); + return true; } } + + false } fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> { diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs index 8280b2c5629cf..ea5a675827ab0 100644 --- a/clippy_lints/src/types/redundant_allocation.rs +++ b/clippy_lints/src/types/redundant_allocation.rs @@ -10,7 +10,7 @@ use crate::utils::{ use super::{utils, REDUNDANT_ALLOCATION}; -pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) { +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { if Some(def_id) == cx.tcx.lang_items().owned_box() { if let Some(span) = utils::match_borrows_parameter(cx, qpath) { let mut applicability = Applicability::MachineApplicable; @@ -23,7 +23,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), applicability, ); - return; + return true; } } @@ -39,14 +39,15 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(), applicability, ); + true } else if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) { let qpath = match &ty.kind { TyKind::Path(qpath) => qpath, - _ => return, + _ => return false, }; let inner_span = match get_qpath_generic_tys(qpath).next() { Some(ty) => ty.span, - None => return, + None => return false, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -61,6 +62,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ ), applicability, ); + true } else if let Some(span) = utils::match_borrows_parameter(cx, qpath) { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -72,7 +74,11 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), applicability, ); - return; // don't recurse into the type + true + } else { + false } + } else { + false } } diff --git a/clippy_lints/src/types/vec_box.rs b/clippy_lints/src/types/vec_box.rs index 2964abf3492eb..2530cc133c678 100644 --- a/clippy_lints/src/types/vec_box.rs +++ b/clippy_lints/src/types/vec_box.rs @@ -18,7 +18,7 @@ pub(super) fn check( qpath: &QPath<'_>, def_id: DefId, box_size_threshold: u64, -) { +) -> bool { if cx.tcx.is_diagnostic_item(sym::vec_type, def_id) { if_chain! { // Get the _ part of Vec<_> @@ -53,7 +53,12 @@ pub(super) fn check( format!("Vec<{}>", snippet(cx, boxed_ty.span, "..")), Applicability::MachineApplicable, ); + true + } else { + false } } + } else { + false } } From b59c879fc9e508b4e9a08babf2e4004f396833bb Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 12 Feb 2021 14:24:02 +0900 Subject: [PATCH 131/226] Move option_option to its own module --- clippy_lints/src/types/mod.rs | 15 +++------------ clippy_lints/src/types/option_option.rs | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 clippy_lints/src/types/option_option.rs diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 8506f362517aa..55f1d86bc56b6 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -1,6 +1,7 @@ #![allow(rustc::default_hash_types)] mod box_vec; +mod option_option; mod rc_buffer; mod redundant_allocation; mod utils; @@ -327,19 +328,9 @@ impl Types { triggered |= redundant_allocation::check(cx, hir_ty, qpath, def_id); triggered |= rc_buffer::check(cx, hir_ty, qpath, def_id); triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold); + triggered |= option_option::check(cx, hir_ty, qpath, def_id); - if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { - if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { - span_lint( - cx, - OPTION_OPTION, - hir_ty.span, - "consider using `Option` instead of `Option>` or a custom \ - enum if you need to distinguish all 3 cases", - ); - return; // don't recurse into the type - } - } else if match_def_path(cx, def_id, &paths::LINKED_LIST) { + if match_def_path(cx, def_id, &paths::LINKED_LIST) { span_lint_and_help( cx, LINKEDLIST, diff --git a/clippy_lints/src/types/option_option.rs b/clippy_lints/src/types/option_option.rs new file mode 100644 index 0000000000000..42aad70438b5f --- /dev/null +++ b/clippy_lints/src/types/option_option.rs @@ -0,0 +1,23 @@ +use rustc_hir::{self as hir, def_id::DefId, QPath}; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +use crate::utils::span_lint; + +use super::utils; + +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { + if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { + if utils::is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { + span_lint( + cx, + super::OPTION_OPTION, + hir_ty.span, + "consider using `Option` instead of `Option>` or a custom \ + enum if you need to distinguish all 3 cases", + ); + return true; + } + } + false +} From cc3ab1c0ec8c94920fea7aab6c912297f489ff49 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 12 Feb 2021 14:28:17 +0900 Subject: [PATCH 132/226] Move linked_list to its own module --- clippy_lints/src/types/linked_list.rs | 20 ++++++++++++++++++++ clippy_lints/src/types/mod.rs | 23 +++++------------------ clippy_lints/src/types/option_option.rs | 6 ++---- 3 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 clippy_lints/src/types/linked_list.rs diff --git a/clippy_lints/src/types/linked_list.rs b/clippy_lints/src/types/linked_list.rs new file mode 100644 index 0000000000000..74be8959fa498 --- /dev/null +++ b/clippy_lints/src/types/linked_list.rs @@ -0,0 +1,20 @@ +use rustc_hir::{self as hir, def_id::DefId}; +use rustc_lint::LateContext; + +use crate::utils::{match_def_path, paths, span_lint_and_help}; + +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, def_id: DefId) -> bool { + if match_def_path(cx, def_id, &paths::LINKED_LIST) { + span_lint_and_help( + cx, + super::LINKEDLIST, + hir_ty.span, + "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?", + None, + "a `VecDeque` might work", + ); + true + } else { + false + } +} diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 55f1d86bc56b6..86a12b8ffa984 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -1,6 +1,7 @@ #![allow(rustc::default_hash_types)] mod box_vec; +mod linked_list; mod option_option; mod rc_buffer; mod redundant_allocation; @@ -39,10 +40,9 @@ use crate::utils::paths; use crate::utils::sugg::Sugg; use crate::utils::{ clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant, - is_ty_param_diagnostic_item, is_type_diagnostic_item, match_def_path, match_path, meets_msrv, method_chain_args, - multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, - snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, - span_lint_and_then, unsext, + is_type_diagnostic_item, match_path, meets_msrv, method_chain_args, multispan_sugg, + numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, + snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext, }; declare_clippy_lint! { @@ -313,7 +313,6 @@ impl Types { /// /// The parameter `is_local` distinguishes the context of the type; types from /// local bindings should only be checked for the `BORROWED_BOX` lint. - #[allow(clippy::too_many_lines)] fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: bool) { if hir_ty.span.from_expansion() { return; @@ -329,18 +328,7 @@ impl Types { triggered |= rc_buffer::check(cx, hir_ty, qpath, def_id); triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold); triggered |= option_option::check(cx, hir_ty, qpath, def_id); - - if match_def_path(cx, def_id, &paths::LINKED_LIST) { - span_lint_and_help( - cx, - LINKEDLIST, - hir_ty.span, - "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?", - None, - "a `VecDeque` might work", - ); - return; // don't recurse into the type - } + triggered |= linked_list::check(cx, hir_ty, def_id); if triggered { return; @@ -389,7 +377,6 @@ impl Types { } }, TyKind::Rptr(ref lt, ref mut_ty) => self.check_ty_rptr(cx, hir_ty, is_local, lt, mut_ty), - // recurse TyKind::Slice(ref ty) | TyKind::Array(ref ty, _) | TyKind::Ptr(MutTy { ref ty, .. }) => { self.check_ty(cx, ty, is_local) }, diff --git a/clippy_lints/src/types/option_option.rs b/clippy_lints/src/types/option_option.rs index 42aad70438b5f..d91132aaeb2bd 100644 --- a/clippy_lints/src/types/option_option.rs +++ b/clippy_lints/src/types/option_option.rs @@ -2,13 +2,11 @@ use rustc_hir::{self as hir, def_id::DefId, QPath}; use rustc_lint::LateContext; use rustc_span::symbol::sym; -use crate::utils::span_lint; - -use super::utils; +use crate::utils::{is_ty_param_diagnostic_item, span_lint}; pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { - if utils::is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { + if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { span_lint( cx, super::OPTION_OPTION, From 53d3ffe5395da729bbfed53dee826ad4ad1feb63 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 12 Feb 2021 15:22:07 +0900 Subject: [PATCH 133/226] Move borrowed_box to its own module --- clippy_lints/src/types/borrowed_box.rs | 118 ++++++++++++++++++++++++ clippy_lints/src/types/mod.rs | 122 ++----------------------- 2 files changed, 127 insertions(+), 113 deletions(-) create mode 100644 clippy_lints/src/types/borrowed_box.rs diff --git a/clippy_lints/src/types/borrowed_box.rs b/clippy_lints/src/types/borrowed_box.rs new file mode 100644 index 0000000000000..4c2cad0ee94dd --- /dev/null +++ b/clippy_lints/src/types/borrowed_box.rs @@ -0,0 +1,118 @@ +use rustc_errors::Applicability; +use rustc_hir::{ + self as hir, GenericArg, GenericBounds, GenericParamKind, HirId, Lifetime, MutTy, Mutability, Node, QPath, + SyntheticTyParamKind, TyKind, +}; +use rustc_lint::LateContext; + +use if_chain::if_chain; + +use crate::utils::{match_path, paths, snippet, span_lint_and_sugg}; + +pub(super) fn check( + cx: &LateContext<'_>, + hir_ty: &hir::Ty<'_>, + is_local: bool, + lt: &Lifetime, + mut_ty: &MutTy<'_>, +) -> bool { + match mut_ty.ty.kind { + TyKind::Path(ref qpath) => { + let hir_id = mut_ty.ty.hir_id; + let def = cx.qpath_res(qpath, hir_id); + if_chain! { + if let Some(def_id) = def.opt_def_id(); + if Some(def_id) == cx.tcx.lang_items().owned_box(); + if let QPath::Resolved(None, ref path) = *qpath; + if let [ref bx] = *path.segments; + if let Some(ref params) = bx.args; + if !params.parenthesized; + if let Some(inner) = params.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + _ => None, + }); + then { + if is_any_trait(inner) { + // Ignore `Box` types; see issue #1884 for details. + return false; + } + + let ltopt = if lt.is_elided() { + String::new() + } else { + format!("{} ", lt.name.ident().as_str()) + }; + + if mut_ty.mutbl == Mutability::Mut { + // Ignore `&mut Box` types; see issue #2907 for + // details. + return false; + } + + // When trait objects or opaque types have lifetime or auto-trait bounds, + // we need to add parentheses to avoid a syntax error due to its ambiguity. + // Originally reported as the issue #3128. + let inner_snippet = snippet(cx, inner.span, ".."); + let suggestion = match &inner.kind { + TyKind::TraitObject(bounds, lt_bound) if bounds.len() > 1 || !lt_bound.is_elided() => { + format!("&{}({})", ltopt, &inner_snippet) + }, + TyKind::Path(qpath) + if get_bounds_if_impl_trait(cx, qpath, inner.hir_id) + .map_or(false, |bounds| bounds.len() > 1) => + { + format!("&{}({})", ltopt, &inner_snippet) + }, + _ => format!("&{}{}", ltopt, &inner_snippet), + }; + span_lint_and_sugg( + cx, + super::BORROWED_BOX, + hir_ty.span, + "you seem to be trying to use `&Box`. Consider using just `&T`", + "try", + suggestion, + // To make this `MachineApplicable`, at least one needs to check if it isn't a trait item + // because the trait impls of it will break otherwise; + // and there may be other cases that result in invalid code. + // For example, type coercion doesn't work nicely. + Applicability::Unspecified, + ); + return true; + } + }; + false + }, + _ => false, + } +} + +// Returns true if given type is `Any` trait. +fn is_any_trait(t: &hir::Ty<'_>) -> bool { + if_chain! { + if let TyKind::TraitObject(ref traits, _) = t.kind; + if !traits.is_empty(); + // Only Send/Sync can be used as additional traits, so it is enough to + // check only the first trait. + if match_path(&traits[0].trait_ref.path, &paths::ANY_TRAIT); + then { + return true; + } + } + + false +} + +fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id: HirId) -> Option> { + if_chain! { + if let Some(did) = cx.qpath_res(qpath, id).opt_def_id(); + if let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did); + if let GenericParamKind::Type { synthetic, .. } = generic_param.kind; + if synthetic == Some(SyntheticTyParamKind::ImplTrait); + then { + Some(generic_param.bounds) + } else { + None + } + } +} diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 86a12b8ffa984..8c2fc55308568 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -1,5 +1,6 @@ #![allow(rustc::default_hash_types)] +mod borrowed_box; mod box_vec; mod linked_list; mod option_option; @@ -18,9 +19,9 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; use rustc_hir::{ - BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericBounds, GenericParamKind, HirId, - ImplItem, ImplItemKind, Item, ItemKind, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt, - StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp, + BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericParamKind, HirId, ImplItem, + ImplItemKind, Item, ItemKind, Lit, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt, StmtKind, TraitFn, + TraitItem, TraitItemKind, TyKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -376,7 +377,11 @@ impl Types { QPath::LangItem(..) => {}, } }, - TyKind::Rptr(ref lt, ref mut_ty) => self.check_ty_rptr(cx, hir_ty, is_local, lt, mut_ty), + TyKind::Rptr(ref lt, ref mut_ty) => { + if !borrowed_box::check(cx, hir_ty, is_local, lt, mut_ty) { + self.check_ty(cx, &mut_ty.ty, is_local); + } + }, TyKind::Slice(ref ty) | TyKind::Array(ref ty, _) | TyKind::Ptr(MutTy { ref ty, .. }) => { self.check_ty(cx, ty, is_local) }, @@ -388,115 +393,6 @@ impl Types { _ => {}, } } - - fn check_ty_rptr( - &mut self, - cx: &LateContext<'_>, - hir_ty: &hir::Ty<'_>, - is_local: bool, - lt: &Lifetime, - mut_ty: &MutTy<'_>, - ) { - match mut_ty.ty.kind { - TyKind::Path(ref qpath) => { - let hir_id = mut_ty.ty.hir_id; - let def = cx.qpath_res(qpath, hir_id); - if_chain! { - if let Some(def_id) = def.opt_def_id(); - if Some(def_id) == cx.tcx.lang_items().owned_box(); - if let QPath::Resolved(None, ref path) = *qpath; - if let [ref bx] = *path.segments; - if let Some(ref params) = bx.args; - if !params.parenthesized; - if let Some(inner) = params.args.iter().find_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty), - _ => None, - }); - then { - if is_any_trait(inner) { - // Ignore `Box` types; see issue #1884 for details. - return; - } - - let ltopt = if lt.is_elided() { - String::new() - } else { - format!("{} ", lt.name.ident().as_str()) - }; - - if mut_ty.mutbl == Mutability::Mut { - // Ignore `&mut Box` types; see issue #2907 for - // details. - return; - } - - // When trait objects or opaque types have lifetime or auto-trait bounds, - // we need to add parentheses to avoid a syntax error due to its ambiguity. - // Originally reported as the issue #3128. - let inner_snippet = snippet(cx, inner.span, ".."); - let suggestion = match &inner.kind { - TyKind::TraitObject(bounds, lt_bound) if bounds.len() > 1 || !lt_bound.is_elided() => { - format!("&{}({})", ltopt, &inner_snippet) - }, - TyKind::Path(qpath) - if get_bounds_if_impl_trait(cx, qpath, inner.hir_id) - .map_or(false, |bounds| bounds.len() > 1) => - { - format!("&{}({})", ltopt, &inner_snippet) - }, - _ => format!("&{}{}", ltopt, &inner_snippet), - }; - span_lint_and_sugg( - cx, - BORROWED_BOX, - hir_ty.span, - "you seem to be trying to use `&Box`. Consider using just `&T`", - "try", - suggestion, - // To make this `MachineApplicable`, at least one needs to check if it isn't a trait item - // because the trait impls of it will break otherwise; - // and there may be other cases that result in invalid code. - // For example, type coercion doesn't work nicely. - Applicability::Unspecified, - ); - return; // don't recurse into the type - } - }; - self.check_ty(cx, &mut_ty.ty, is_local); - }, - _ => self.check_ty(cx, &mut_ty.ty, is_local), - } - } -} - -// Returns true if given type is `Any` trait. -fn is_any_trait(t: &hir::Ty<'_>) -> bool { - if_chain! { - if let TyKind::TraitObject(ref traits, _) = t.kind; - if !traits.is_empty(); - // Only Send/Sync can be used as additional traits, so it is enough to - // check only the first trait. - if match_path(&traits[0].trait_ref.path, &paths::ANY_TRAIT); - then { - return true; - } - } - - false -} - -fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id: HirId) -> Option> { - if_chain! { - if let Some(did) = cx.qpath_res(qpath, id).opt_def_id(); - if let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did); - if let GenericParamKind::Type { synthetic, .. } = generic_param.kind; - if synthetic == Some(SyntheticTyParamKind::ImplTrait); - then { - Some(generic_param.bounds) - } else { - None - } - } } declare_clippy_lint! { From 2afa7df564e6b6d2126578fd9b997d6c2abc4935 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 12 Feb 2021 15:26:36 +0900 Subject: [PATCH 134/226] Remove unused is_local from borrowed_box --- clippy_lints/src/types/borrowed_box.rs | 8 +------- clippy_lints/src/types/mod.rs | 5 ++--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/types/borrowed_box.rs b/clippy_lints/src/types/borrowed_box.rs index 4c2cad0ee94dd..c9b96a7d3258d 100644 --- a/clippy_lints/src/types/borrowed_box.rs +++ b/clippy_lints/src/types/borrowed_box.rs @@ -9,13 +9,7 @@ use if_chain::if_chain; use crate::utils::{match_path, paths, snippet, span_lint_and_sugg}; -pub(super) fn check( - cx: &LateContext<'_>, - hir_ty: &hir::Ty<'_>, - is_local: bool, - lt: &Lifetime, - mut_ty: &MutTy<'_>, -) -> bool { +pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, mut_ty: &MutTy<'_>) -> bool { match mut_ty.ty.kind { TyKind::Path(ref qpath) => { let hir_id = mut_ty.ty.hir_id; diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 8c2fc55308568..25cc40917c301 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -312,8 +312,7 @@ impl Types { /// Recursively check for `TypePass` lints in the given type. Stop at the first /// lint found. /// - /// The parameter `is_local` distinguishes the context of the type; types from - /// local bindings should only be checked for the `BORROWED_BOX` lint. + /// The parameter `is_local` distinguishes the context of the type. fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: bool) { if hir_ty.span.from_expansion() { return; @@ -378,7 +377,7 @@ impl Types { } }, TyKind::Rptr(ref lt, ref mut_ty) => { - if !borrowed_box::check(cx, hir_ty, is_local, lt, mut_ty) { + if !borrowed_box::check(cx, hir_ty, lt, mut_ty) { self.check_ty(cx, &mut_ty.ty, is_local); } }, From bb8208da2beba7782d741edfc2b1027ffa823ba5 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 16 Feb 2021 22:18:53 +0900 Subject: [PATCH 135/226] Import declared lints at the top of the file --- clippy_lints/src/types/borrowed_box.rs | 4 +++- clippy_lints/src/types/linked_list.rs | 4 +++- clippy_lints/src/types/option_option.rs | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/types/borrowed_box.rs b/clippy_lints/src/types/borrowed_box.rs index c9b96a7d3258d..a7a511b21cf59 100644 --- a/clippy_lints/src/types/borrowed_box.rs +++ b/clippy_lints/src/types/borrowed_box.rs @@ -9,6 +9,8 @@ use if_chain::if_chain; use crate::utils::{match_path, paths, snippet, span_lint_and_sugg}; +use super::BORROWED_BOX; + pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, mut_ty: &MutTy<'_>) -> bool { match mut_ty.ty.kind { TyKind::Path(ref qpath) => { @@ -61,7 +63,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m }; span_lint_and_sugg( cx, - super::BORROWED_BOX, + BORROWED_BOX, hir_ty.span, "you seem to be trying to use `&Box`. Consider using just `&T`", "try", diff --git a/clippy_lints/src/types/linked_list.rs b/clippy_lints/src/types/linked_list.rs index 74be8959fa498..47eb4ede4e422 100644 --- a/clippy_lints/src/types/linked_list.rs +++ b/clippy_lints/src/types/linked_list.rs @@ -3,11 +3,13 @@ use rustc_lint::LateContext; use crate::utils::{match_def_path, paths, span_lint_and_help}; +use super::LINKEDLIST; + pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, def_id: DefId) -> bool { if match_def_path(cx, def_id, &paths::LINKED_LIST) { span_lint_and_help( cx, - super::LINKEDLIST, + LINKEDLIST, hir_ty.span, "you seem to be using a `LinkedList`! Perhaps you meant some other data structure?", None, diff --git a/clippy_lints/src/types/option_option.rs b/clippy_lints/src/types/option_option.rs index d91132aaeb2bd..a1fc26f7865e7 100644 --- a/clippy_lints/src/types/option_option.rs +++ b/clippy_lints/src/types/option_option.rs @@ -4,12 +4,14 @@ use rustc_span::symbol::sym; use crate::utils::{is_ty_param_diagnostic_item, span_lint}; +use super::OPTION_OPTION; + pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { span_lint( cx, - super::OPTION_OPTION, + OPTION_OPTION, hir_ty.span, "consider using `Option` instead of `Option>` or a custom \ enum if you need to distinguish all 3 cases", From db59c35b7eb6cebe7e392fad3f223eb458d80a5d Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Fri, 26 Feb 2021 01:06:15 +0900 Subject: [PATCH 136/226] Fix some lints in types that fail dogfood --- clippy_lints/src/types/box_vec.rs | 27 ++++++++++--------- clippy_lints/src/types/option_option.rs | 23 ++++++++-------- .../src/types/redundant_allocation.rs | 26 +++++++++--------- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/clippy_lints/src/types/box_vec.rs b/clippy_lints/src/types/box_vec.rs index 4eb032cae6b1a..6aa98e435e160 100644 --- a/clippy_lints/src/types/box_vec.rs +++ b/clippy_lints/src/types/box_vec.rs @@ -7,18 +7,19 @@ use crate::utils::{is_ty_param_diagnostic_item, span_lint_and_help}; use super::BOX_VEC; pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { - if Some(def_id) == cx.tcx.lang_items().owned_box() { - if is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() { - span_lint_and_help( - cx, - BOX_VEC, - hir_ty.span, - "you seem to be trying to use `Box>`. Consider using just `Vec`", - None, - "`Vec` is already on the heap, `Box>` makes an extra allocation", - ); - return true; - } + if Some(def_id) == cx.tcx.lang_items().owned_box() + && is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() + { + span_lint_and_help( + cx, + BOX_VEC, + hir_ty.span, + "you seem to be trying to use `Box>`. Consider using just `Vec`", + None, + "`Vec` is already on the heap, `Box>` makes an extra allocation", + ); + true + } else { + false } - false } diff --git a/clippy_lints/src/types/option_option.rs b/clippy_lints/src/types/option_option.rs index a1fc26f7865e7..dc5db963b4e98 100644 --- a/clippy_lints/src/types/option_option.rs +++ b/clippy_lints/src/types/option_option.rs @@ -7,17 +7,18 @@ use crate::utils::{is_ty_param_diagnostic_item, span_lint}; use super::OPTION_OPTION; pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { - if cx.tcx.is_diagnostic_item(sym::option_type, def_id) { - if is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() { - span_lint( - cx, - OPTION_OPTION, - hir_ty.span, - "consider using `Option` instead of `Option>` or a custom \ + if cx.tcx.is_diagnostic_item(sym::option_type, def_id) + && is_ty_param_diagnostic_item(cx, qpath, sym::option_type).is_some() + { + span_lint( + cx, + OPTION_OPTION, + hir_ty.span, + "consider using `Option` instead of `Option>` or a custom \ enum if you need to distinguish all 3 cases", - ); - return true; - } + ); + true + } else { + false } - false } diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs index ea5a675827ab0..5da6db179c46e 100644 --- a/clippy_lints/src/types/redundant_allocation.rs +++ b/clippy_lints/src/types/redundant_allocation.rs @@ -63,20 +63,20 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ applicability, ); true - } else if let Some(span) = utils::match_borrows_parameter(cx, qpath) { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Rc<&T>`", - "try", - snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), - applicability, - ); - true } else { - false + utils::match_borrows_parameter(cx, qpath).map_or(false, |span| { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + REDUNDANT_ALLOCATION, + hir_ty.span, + "usage of `Rc<&T>`", + "try", + snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), + applicability, + ); + true + }) } } else { false From f2d917e3b1e6c91fe005e2dabc7cb5627de6d813 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 8 Mar 2021 11:08:52 -0500 Subject: [PATCH 137/226] Don't assume lang items will exist. --- clippy_lints/src/derive.rs | 7 ++++++- clippy_lints/src/lifetimes.rs | 11 +++++++---- clippy_lints/src/map_clone.rs | 2 +- clippy_utils/src/lib.rs | 8 ++++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 382a045a3f7cc..594c370f6608f 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -293,7 +293,12 @@ fn check_ord_partial_ord<'tcx>( /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>) { - if cx.tcx.lang_items().clone_trait() == trait_ref.trait_def_id() { + if cx + .tcx + .lang_items() + .clone_trait() + .map_or(false, |id| Some(id) == trait_ref.trait_def_id()) + { if !is_copy(cx, ty) { return; } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 3807d346f6816..33ff01a30e881 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -358,10 +358,13 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>, tbm: TraitBoundModifier) { let trait_ref = &poly_tref.trait_ref; - if CLOSURE_TRAIT_BOUNDS - .iter() - .any(|&item| trait_ref.trait_def_id() == self.cx.tcx.lang_items().require(item).ok()) - { + if CLOSURE_TRAIT_BOUNDS.iter().any(|&item| { + self.cx + .tcx + .lang_items() + .require(item) + .map_or(false, |id| Some(id) == trait_ref.trait_def_id()) + }) { let mut sub_visitor = RefVisitor::new(self.cx); sub_visitor.visit_trait_ref(trait_ref); self.nested_elision_site_lts.append(&mut sub_visitor.all_lts()); diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 0c358e2e538b1..4b685c09a0548 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for MapClone { if ident_eq(name, obj) && method.ident.name == sym::clone; if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id); if let Some(trait_id) = cx.tcx.trait_of_item(fn_id); - if Some(trait_id) == cx.tcx.lang_items().clone_trait(); + if cx.tcx.lang_items().clone_trait().map_or(false, |id| id == trait_id); // no autoderefs if !cx.typeck_results().expr_adjustments(obj).iter() .any(|a| matches!(a.kind, Adjust::Deref(Some(..)))); diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 3845667802d80..1f62cf5ae7fcf 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -239,7 +239,10 @@ pub fn is_ty_param_lang_item(cx: &LateContext<'_>, qpath: &QPath<'tcx>, item: La if let TyKind::Path(qpath) = &ty.kind { cx.qpath_res(qpath, ty.hir_id) .opt_def_id() - .and_then(|id| (cx.tcx.lang_items().require(item) == Ok(id)).then(|| ty)) + .map_or(false, |id| { + cx.tcx.lang_items().require(item).map_or(false, |lang_id| id == lang_id) + }) + .then(|| ty) } else { None } @@ -256,7 +259,8 @@ pub fn is_ty_param_diagnostic_item( if let TyKind::Path(qpath) = &ty.kind { cx.qpath_res(qpath, ty.hir_id) .opt_def_id() - .and_then(|id| cx.tcx.is_diagnostic_item(item, id).then(|| ty)) + .map_or(false, |id| cx.tcx.is_diagnostic_item(item, id)) + .then(|| ty) } else { None } From c4e2cf9601d35646054b48b2503d6ddad7412b8f Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 8 Mar 2021 17:39:51 +0000 Subject: [PATCH 138/226] Opt-in to rustc_private for `rust-analyzer` rust-analyzer/rust-analyzer#7891 --- Cargo.toml | 4 ++++ clippy_lints/Cargo.toml | 10 +++++++--- clippy_utils/Cargo.toml | 4 ++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 98a5be2898dcf..a6d0c16fd3ae8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,3 +56,7 @@ rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util" } deny-warnings = [] integration = ["tempfile"] internal-lints = ["clippy_lints/internal-lints"] + +[package.metadata.rust-analyzer] +# This package uses #[feature(rustc_private)] +rustc_private = true diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index d5ec8597044c8..ff4cf527ec482 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -7,7 +7,7 @@ authors = [ "Manish Goregaokar ", "Andre Bogus ", "Georg Brandl ", - "Martin Carton " + "Martin Carton ", ] description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" @@ -29,10 +29,10 @@ smallvec = { version = "1", features = ["union"] } toml = "0.5.3" unicode-normalization = "0.1" semver = "0.11" -rustc-semver="1.1.0" +rustc-semver = "1.1.0" # NOTE: cargo requires serde feat in its url dep # see -url = { version = "2.1.0", features = ["serde"] } +url = { version = "2.1.0", features = ["serde"] } quote = "1" syn = { version = "1", features = ["full"] } @@ -40,3 +40,7 @@ syn = { version = "1", features = ["full"] } deny-warnings = [] # build clippy with internal lints enabled, off by default internal-lints = ["clippy_utils/internal-lints"] + +[package.metadata.rust-analyzer] +# This crate uses #[feature(rustc_private)] +rustc_private = true diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 9c01badb04cc9..9e07f140cf1be 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -17,3 +17,7 @@ rustc-semver="1.1.0" [features] internal-lints = [] + +[package.metadata.rust-analyzer] +# This crate uses #[feature(rustc_private)] +rustc_private = true From bf98aa6fb8e02db15ad18d517145f13a5bed2921 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 8 Mar 2021 12:59:58 -0600 Subject: [PATCH 139/226] Fix redundant closure with macros --- clippy_lints/src/eta_reduction.rs | 24 ++++++++++++++++++++++- tests/ui/eta.fixed | 15 +++++++++++++++ tests/ui/eta.rs | 15 +++++++++++++++ tests/ui/eta.stderr | 32 ++++++++++++++++++------------- 4 files changed, 72 insertions(+), 14 deletions(-) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 1a722d39f730b..ab385fc1f8a51 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -10,6 +10,8 @@ use crate::utils::{ implements_trait, is_adjusted, iter_input_pats, snippet_opt, span_lint_and_sugg, span_lint_and_then, type_is_unsafe_function, }; +use clippy_utils::higher; +use clippy_utils::higher::VecArgs; declare_clippy_lint! { /// **What it does:** Checks for closures which just call another function where @@ -74,7 +76,10 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { match expr.kind { ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) => { for arg in args { - check_closure(cx, arg) + // skip `foo(macro!())` + if arg.span.ctxt() == expr.span.ctxt() { + check_closure(cx, arg) + } } }, _ => (), @@ -87,6 +92,23 @@ fn check_closure(cx: &LateContext<'_>, expr: &Expr<'_>) { let body = cx.tcx.hir().body(eid); let ex = &body.value; + if ex.span.ctxt() != expr.span.ctxt() { + if let Some(VecArgs::Vec(&[])) = higher::vec_macro(cx, ex) { + // replace `|| vec![]` with `Vec::new` + span_lint_and_sugg( + cx, + REDUNDANT_CLOSURE, + expr.span, + "redundant closure found", + "remove closure as shown", + "std::vec::Vec::new".into(), + Applicability::MachineApplicable, + ); + } + // skip `foo(|| macro!())` + return; + } + if_chain!( if let ExprKind::Call(ref caller, ref args) = ex.kind; diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index 1b34c2f74eba1..2be2283e3fdd2 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -16,10 +16,25 @@ use std::path::PathBuf; +macro_rules! mac { + () => { + foobar() + }; +} + +macro_rules! closure_mac { + () => { + |n| foo(n) + }; +} + fn main() { let a = Some(1u8).map(foo); meta(foo); let c = Some(1u8).map(|a| {1+2; foo}(a)); + true.then(|| mac!()); // don't lint function in macro expansion + Some(1).map(closure_mac!()); // don't lint closure in macro expansion + let _: Option> = true.then(std::vec::Vec::new); // special case vec! let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? all(&[1, 2, 3], &2, |x, y| below(x, y)); //is adjusted unsafe { diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index 4f050bd8479ae..f0373f9ccf673 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -16,10 +16,25 @@ use std::path::PathBuf; +macro_rules! mac { + () => { + foobar() + }; +} + +macro_rules! closure_mac { + () => { + |n| foo(n) + }; +} + fn main() { let a = Some(1u8).map(|a| foo(a)); meta(|a| foo(a)); let c = Some(1u8).map(|a| {1+2; foo}(a)); + true.then(|| mac!()); // don't lint function in macro expansion + Some(1).map(closure_mac!()); // don't lint closure in macro expansion + let _: Option> = true.then(|| vec![]); // special case vec! let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted unsafe { diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 16aa1b07733d5..34d6dd4631175 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -1,5 +1,5 @@ error: redundant closure found - --> $DIR/eta.rs:20:27 + --> $DIR/eta.rs:32:27 | LL | let a = Some(1u8).map(|a| foo(a)); | ^^^^^^^^^^ help: remove closure as shown: `foo` @@ -7,13 +7,19 @@ LL | let a = Some(1u8).map(|a| foo(a)); = note: `-D clippy::redundant-closure` implied by `-D warnings` error: redundant closure found - --> $DIR/eta.rs:21:10 + --> $DIR/eta.rs:33:10 | LL | meta(|a| foo(a)); | ^^^^^^^^^^ help: remove closure as shown: `foo` +error: redundant closure found + --> $DIR/eta.rs:37:40 + | +LL | let _: Option> = true.then(|| vec![]); // special case vec! + | ^^^^^^^^^ help: remove closure as shown: `std::vec::Vec::new` + error: this expression borrows a reference (`&u8`) that is immediately dereferenced by the compiler - --> $DIR/eta.rs:24:21 + --> $DIR/eta.rs:39:21 | LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted | ^^^ help: change this to: `&2` @@ -21,13 +27,13 @@ LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted = note: `-D clippy::needless-borrow` implied by `-D warnings` error: redundant closure found - --> $DIR/eta.rs:31:27 + --> $DIR/eta.rs:46:27 | LL | let e = Some(1u8).map(|a| generic(a)); | ^^^^^^^^^^^^^^ help: remove closure as shown: `generic` error: redundant closure found - --> $DIR/eta.rs:74:51 + --> $DIR/eta.rs:89:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); | ^^^^^^^^^^^ help: remove closure as shown: `TestStruct::foo` @@ -35,46 +41,46 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); = note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings` error: redundant closure found - --> $DIR/eta.rs:76:51 + --> $DIR/eta.rs:91:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo()); | ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `TestTrait::trait_foo` error: redundant closure found - --> $DIR/eta.rs:79:42 + --> $DIR/eta.rs:94:42 | LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear()); | ^^^^^^^^^^^^^ help: remove closure as shown: `std::vec::Vec::clear` error: redundant closure found - --> $DIR/eta.rs:84:29 + --> $DIR/eta.rs:99:29 | LL | let e = Some("str").map(|s| s.to_string()); | ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `std::string::ToString::to_string` error: redundant closure found - --> $DIR/eta.rs:86:27 + --> $DIR/eta.rs:101:27 | LL | let e = Some('a').map(|s| s.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_uppercase` error: redundant closure found - --> $DIR/eta.rs:89:65 + --> $DIR/eta.rs:104:65 | LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_ascii_uppercase` error: redundant closure found - --> $DIR/eta.rs:172:27 + --> $DIR/eta.rs:187:27 | LL | let a = Some(1u8).map(|a| foo_ptr(a)); | ^^^^^^^^^^^^^^ help: remove closure as shown: `foo_ptr` error: redundant closure found - --> $DIR/eta.rs:177:27 + --> $DIR/eta.rs:192:27 | LL | let a = Some(1u8).map(|a| closure(a)); | ^^^^^^^^^^^^^^ help: remove closure as shown: `closure` -error: aborting due to 12 previous errors +error: aborting due to 13 previous errors From 7e4f5ca38ee1ec1c7847b1f8a8eb9e116ddd25ad Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 8 Mar 2021 12:41:28 -0600 Subject: [PATCH 140/226] clippy: fix or-pattern in let binding --- clippy_lints/src/loops.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 1c9373a756c88..a87d5b9d37309 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -885,7 +885,9 @@ struct MinifyingSugg<'a>(Sugg<'a>); impl<'a> MinifyingSugg<'a> { fn as_str(&self) -> &str { - let Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) = &self.0; + let s = match &self.0 { + Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) => s, + }; s.as_ref() } From 8c540dcd2d1d240219c1a4aa28dd745ea010b501 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 8 Mar 2021 13:05:13 -0600 Subject: [PATCH 141/226] Improve the redundant_closure message --- clippy_lints/src/eta_reduction.rs | 12 ++++---- tests/ui/eta.stderr | 48 +++++++++++++++---------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index ab385fc1f8a51..c461732fd3693 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -99,8 +99,8 @@ fn check_closure(cx: &LateContext<'_>, expr: &Expr<'_>) { cx, REDUNDANT_CLOSURE, expr.span, - "redundant closure found", - "remove closure as shown", + "redundant closure", + "replace the closure with `Vec::new`", "std::vec::Vec::new".into(), Applicability::MachineApplicable, ); @@ -129,11 +129,11 @@ fn check_closure(cx: &LateContext<'_>, expr: &Expr<'_>) { if compare_inputs(&mut iter_input_pats(decl, body), &mut args.iter()); then { - span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |diag| { + span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { if let Some(snippet) = snippet_opt(cx, caller.span) { diag.span_suggestion( expr.span, - "remove closure as shown", + "replace the closure with the function itself", snippet, Applicability::MachineApplicable, ); @@ -163,8 +163,8 @@ fn check_closure(cx: &LateContext<'_>, expr: &Expr<'_>) { cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, - "redundant closure found", - "remove closure as shown", + "redundant closure", + "replace the closure with the method itself", format!("{}::{}", name, path.ident.name), Applicability::MachineApplicable, ); diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 34d6dd4631175..57ed65279666a 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -1,22 +1,22 @@ -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:32:27 | LL | let a = Some(1u8).map(|a| foo(a)); - | ^^^^^^^^^^ help: remove closure as shown: `foo` + | ^^^^^^^^^^ help: replace the closure with the function itself: `foo` | = note: `-D clippy::redundant-closure` implied by `-D warnings` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:33:10 | LL | meta(|a| foo(a)); - | ^^^^^^^^^^ help: remove closure as shown: `foo` + | ^^^^^^^^^^ help: replace the closure with the function itself: `foo` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:37:40 | LL | let _: Option> = true.then(|| vec![]); // special case vec! - | ^^^^^^^^^ help: remove closure as shown: `std::vec::Vec::new` + | ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new` error: this expression borrows a reference (`&u8`) that is immediately dereferenced by the compiler --> $DIR/eta.rs:39:21 @@ -26,61 +26,61 @@ LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted | = note: `-D clippy::needless-borrow` implied by `-D warnings` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:46:27 | LL | let e = Some(1u8).map(|a| generic(a)); - | ^^^^^^^^^^^^^^ help: remove closure as shown: `generic` + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:89:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); - | ^^^^^^^^^^^ help: remove closure as shown: `TestStruct::foo` + | ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo` | = note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:91:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo()); - | ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `TestTrait::trait_foo` + | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:94:42 | LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear()); - | ^^^^^^^^^^^^^ help: remove closure as shown: `std::vec::Vec::clear` + | ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:99:29 | LL | let e = Some("str").map(|s| s.to_string()); - | ^^^^^^^^^^^^^^^^^ help: remove closure as shown: `std::string::ToString::to_string` + | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:101:27 | LL | let e = Some('a').map(|s| s.to_uppercase()); - | ^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_uppercase` + | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:104:65 | LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `char::to_ascii_uppercase` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:187:27 | LL | let a = Some(1u8).map(|a| foo_ptr(a)); - | ^^^^^^^^^^^^^^ help: remove closure as shown: `foo_ptr` + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr` -error: redundant closure found +error: redundant closure --> $DIR/eta.rs:192:27 | LL | let a = Some(1u8).map(|a| closure(a)); - | ^^^^^^^^^^^^^^ help: remove closure as shown: `closure` + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure` error: aborting due to 13 previous errors From f098007caaebe660b06ee7c43cd30006807a2a8c Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 10:57:25 +0900 Subject: [PATCH 142/226] Separate lints of casts group from types group --- clippy_lints/src/casts/mod.rs | 973 ++++++++++++++++++++++++++++++++++ clippy_lints/src/lib.rs | 67 +-- clippy_lints/src/types/mod.rs | 969 +-------------------------------- 3 files changed, 1015 insertions(+), 994 deletions(-) create mode 100644 clippy_lints/src/casts/mod.rs diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs new file mode 100644 index 0000000000000..d8245a3b88f74 --- /dev/null +++ b/clippy_lints/src/casts/mod.rs @@ -0,0 +1,973 @@ +use std::borrow::Cow; + +use if_chain::if_chain; +use rustc_ast::{LitFloatType, LitIntType, LitKind}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, GenericArg, Lit, MutTy, Mutability, TyKind, UnOp}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TypeAndMut, UintTy}; +use rustc_semver::RustcVersion; +use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; +use rustc_span::symbol::sym; +use rustc_target::abi::LayoutOf; + +use crate::consts::{constant, Constant}; +use crate::utils::sugg::Sugg; +use crate::utils::{ + in_constant, is_hir_ty_cfg_dependant, meets_msrv, method_chain_args, numeric_literal::NumericLiteral, sext, + snippet_opt, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, +}; + +declare_clippy_lint! { + /// **What it does:** Checks for casts from any numerical to a float type where + /// the receiving type cannot store all values from the original type without + /// rounding errors. This possible rounding is to be expected, so this lint is + /// `Allow` by default. + /// + /// Basically, this warns on casting any integer with 32 or more bits to `f32` + /// or any 64-bit integer to `f64`. + /// + /// **Why is this bad?** It's not bad at all. But in some applications it can be + /// helpful to know where precision loss can take place. This lint can help find + /// those places in the code. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x = u64::MAX; + /// x as f64; + /// ``` + pub CAST_PRECISION_LOSS, + pedantic, + "casts that cause loss of precision, e.g., `x as f32` where `x: u64`" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts from a signed to an unsigned numerical + /// type. In this case, negative values wrap around to large positive values, + /// which can be quite surprising in practice. However, as the cast works as + /// defined, this lint is `Allow` by default. + /// + /// **Why is this bad?** Possibly surprising results. You can activate this lint + /// as a one-time check to see where numerical wrapping can arise. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let y: i8 = -1; + /// y as u128; // will return 18446744073709551615 + /// ``` + pub CAST_SIGN_LOSS, + pedantic, + "casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts between numerical types that may + /// truncate large values. This is expected behavior, so the cast is `Allow` by + /// default. + /// + /// **Why is this bad?** In some problem domains, it is good practice to avoid + /// truncation. This lint can be activated to help assess where additional + /// checks could be beneficial. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn as_u8(x: u64) -> u8 { + /// x as u8 + /// } + /// ``` + pub CAST_POSSIBLE_TRUNCATION, + pedantic, + "casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts from an unsigned type to a signed type of + /// the same size. Performing such a cast is a 'no-op' for the compiler, + /// i.e., nothing is changed at the bit level, and the binary representation of + /// the value is reinterpreted. This can cause wrapping if the value is too big + /// for the target signed type. However, the cast works as defined, so this lint + /// is `Allow` by default. + /// + /// **Why is this bad?** While such a cast is not bad in itself, the results can + /// be surprising when this is not the intended behavior, as demonstrated by the + /// example below. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// u32::MAX as i32; // will yield a value of `-1` + /// ``` + pub CAST_POSSIBLE_WRAP, + pedantic, + "casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts between numerical types that may + /// be replaced by safe conversion functions. + /// + /// **Why is this bad?** Rust's `as` keyword will perform many kinds of + /// conversions, including silently lossy conversions. Conversion functions such + /// as `i32::from` will only perform lossless conversions. Using the conversion + /// functions prevents conversions from turning into silent lossy conversions if + /// the types of the input expressions ever change, and make it easier for + /// people reading the code to know that the conversion is lossless. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn as_u64(x: u8) -> u64 { + /// x as u64 + /// } + /// ``` + /// + /// Using `::from` would look like this: + /// + /// ```rust + /// fn as_u64(x: u8) -> u64 { + /// u64::from(x) + /// } + /// ``` + pub CAST_LOSSLESS, + pedantic, + "casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts to the same type, casts of int literals to integer types + /// and casts of float literals to float types. + /// + /// **Why is this bad?** It's just unnecessary. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let _ = 2i32 as i32; + /// let _ = 0.5 as f32; + /// ``` + /// + /// Better: + /// + /// ```rust + /// let _ = 2_i32; + /// let _ = 0.5_f32; + /// ``` + pub UNNECESSARY_CAST, + complexity, + "cast to the same type, e.g., `x as i32` where `x: i32`" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts, using `as` or `pointer::cast`, + /// from a less-strictly-aligned pointer to a more-strictly-aligned pointer + /// + /// **Why is this bad?** Dereferencing the resulting pointer may be undefined + /// behavior. + /// + /// **Known problems:** Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar + /// on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like + /// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis. + /// + /// **Example:** + /// ```rust + /// let _ = (&1u8 as *const u8) as *const u16; + /// let _ = (&mut 1u8 as *mut u8) as *mut u16; + /// + /// (&1u8 as *const u8).cast::(); + /// (&mut 1u8 as *mut u8).cast::(); + /// ``` + pub CAST_PTR_ALIGNMENT, + pedantic, + "cast from a pointer to a more-strictly-aligned pointer" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts of function pointers to something other than usize + /// + /// **Why is this bad?** + /// Casting a function pointer to anything other than usize/isize is not portable across + /// architectures, because you end up losing bits if the target type is too small or end up with a + /// bunch of extra bits that waste space and add more instructions to the final binary than + /// strictly necessary for the problem + /// + /// Casting to isize also doesn't make sense since there are no signed addresses. + /// + /// **Example** + /// + /// ```rust + /// // Bad + /// fn fun() -> i32 { 1 } + /// let a = fun as i64; + /// + /// // Good + /// fn fun2() -> i32 { 1 } + /// let a = fun2 as usize; + /// ``` + pub FN_TO_NUMERIC_CAST, + style, + "casting a function pointer to a numeric type other than usize" +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts of a function pointer to a numeric type not wide enough to + /// store address. + /// + /// **Why is this bad?** + /// Such a cast discards some bits of the function's address. If this is intended, it would be more + /// clearly expressed by casting to usize first, then casting the usize to the intended type (with + /// a comment) to perform the truncation. + /// + /// **Example** + /// + /// ```rust + /// // Bad + /// fn fn1() -> i16 { + /// 1 + /// }; + /// let _ = fn1 as i32; + /// + /// // Better: Cast to usize first, then comment with the reason for the truncation + /// fn fn2() -> i16 { + /// 1 + /// }; + /// let fn_ptr = fn2 as usize; + /// let fn_ptr_truncated = fn_ptr as i32; + /// ``` + pub FN_TO_NUMERIC_CAST_WITH_TRUNCATION, + style, + "casting a function pointer to a numeric type not wide enough to store the address" +} + +/// Returns the size in bits of an integral type. +/// Will return 0 if the type is not an int or uint variant +fn int_ty_to_nbits(typ: Ty<'_>, tcx: TyCtxt<'_>) -> u64 { + match typ.kind() { + ty::Int(i) => match i { + IntTy::Isize => tcx.data_layout.pointer_size.bits(), + IntTy::I8 => 8, + IntTy::I16 => 16, + IntTy::I32 => 32, + IntTy::I64 => 64, + IntTy::I128 => 128, + }, + ty::Uint(i) => match i { + UintTy::Usize => tcx.data_layout.pointer_size.bits(), + UintTy::U8 => 8, + UintTy::U16 => 16, + UintTy::U32 => 32, + UintTy::U64 => 64, + UintTy::U128 => 128, + }, + _ => 0, + } +} + +fn span_precision_loss_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to_f64: bool) { + let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; + let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; + let arch_dependent_str = "on targets with 64-bit wide pointers "; + let from_nbits_str = if arch_dependent { + "64".to_owned() + } else if is_isize_or_usize(cast_from) { + "32 or 64".to_owned() + } else { + int_ty_to_nbits(cast_from, cx.tcx).to_string() + }; + span_lint( + cx, + CAST_PRECISION_LOSS, + expr.span, + &format!( + "casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \ + but `{1}`'s mantissa is only {4} bits wide)", + cast_from, + if cast_to_f64 { "f64" } else { "f32" }, + if arch_dependent { arch_dependent_str } else { "" }, + from_nbits_str, + mantissa_nbits + ), + ); +} + +fn should_strip_parens(op: &Expr<'_>, snip: &str) -> bool { + if let ExprKind::Binary(_, _, _) = op.kind { + if snip.starts_with('(') && snip.ends_with(')') { + return true; + } + } + false +} + +fn span_lossless_lint(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + // Do not suggest using From in consts/statics until it is valid to do so (see #2267). + if in_constant(cx, expr.hir_id) { + return; + } + // The suggestion is to use a function call, so if the original expression + // has parens on the outside, they are no longer needed. + let mut applicability = Applicability::MachineApplicable; + let opt = snippet_opt(cx, op.span); + let sugg = opt.as_ref().map_or_else( + || { + applicability = Applicability::HasPlaceholders; + ".." + }, + |snip| { + if should_strip_parens(op, snip) { + &snip[1..snip.len() - 1] + } else { + snip.as_str() + } + }, + ); + + span_lint_and_sugg( + cx, + CAST_LOSSLESS, + expr.span, + &format!( + "casting `{}` to `{}` may become silently lossy if you later change the type", + cast_from, cast_to + ), + "try", + format!("{}::from({})", cast_to, sugg), + applicability, + ); +} + +enum ArchSuffix { + _32, + _64, + None, +} + +fn check_loss_of_sign(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + if !cast_from.is_signed() || cast_to.is_signed() { + return; + } + + // don't lint for positive constants + let const_val = constant(cx, &cx.typeck_results(), op); + if_chain! { + if let Some((Constant::Int(n), _)) = const_val; + if let ty::Int(ity) = *cast_from.kind(); + if sext(cx.tcx, n, ity) >= 0; + then { + return + } + } + + // don't lint for the result of methods that always return non-negative values + if let ExprKind::MethodCall(ref path, _, _, _) = op.kind { + let mut method_name = path.ident.name.as_str(); + let allowed_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"]; + + if_chain! { + if method_name == "unwrap"; + if let Some(arglist) = method_chain_args(op, &["unwrap"]); + if let ExprKind::MethodCall(ref inner_path, _, _, _) = &arglist[0][0].kind; + then { + method_name = inner_path.ident.name.as_str(); + } + } + + if allowed_methods.iter().any(|&name| method_name == name) { + return; + } + } + + span_lint( + cx, + CAST_SIGN_LOSS, + expr.span, + &format!( + "casting `{}` to `{}` may lose the sign of the value", + cast_from, cast_to + ), + ); +} + +fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + let arch_64_suffix = " on targets with 64-bit wide pointers"; + let arch_32_suffix = " on targets with 32-bit wide pointers"; + let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); + let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); + let (span_truncation, suffix_truncation, span_wrap, suffix_wrap) = + match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { + (true, true) | (false, false) => ( + to_nbits < from_nbits, + ArchSuffix::None, + to_nbits == from_nbits && cast_unsigned_to_signed, + ArchSuffix::None, + ), + (true, false) => ( + to_nbits <= 32, + if to_nbits == 32 { + ArchSuffix::_64 + } else { + ArchSuffix::None + }, + to_nbits <= 32 && cast_unsigned_to_signed, + ArchSuffix::_32, + ), + (false, true) => ( + from_nbits == 64, + ArchSuffix::_32, + cast_unsigned_to_signed, + if from_nbits == 64 { + ArchSuffix::_64 + } else { + ArchSuffix::_32 + }, + ), + }; + if span_truncation { + span_lint( + cx, + CAST_POSSIBLE_TRUNCATION, + expr.span, + &format!( + "casting `{}` to `{}` may truncate the value{}", + cast_from, + cast_to, + match suffix_truncation { + ArchSuffix::_32 => arch_32_suffix, + ArchSuffix::_64 => arch_64_suffix, + ArchSuffix::None => "", + } + ), + ); + } + if span_wrap { + span_lint( + cx, + CAST_POSSIBLE_WRAP, + expr.span, + &format!( + "casting `{}` to `{}` may wrap around the value{}", + cast_from, + cast_to, + match suffix_wrap { + ArchSuffix::_32 => arch_32_suffix, + ArchSuffix::_64 => arch_64_suffix, + ArchSuffix::None => "", + } + ), + ); + } +} + +fn check_lossless(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed(); + let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); + if !is_isize_or_usize(cast_from) && !is_isize_or_usize(cast_to) && from_nbits < to_nbits && !cast_signed_to_unsigned + { + span_lossless_lint(cx, expr, op, cast_from, cast_to); + } +} + +declare_lint_pass!(Casts => [ + CAST_PRECISION_LOSS, + CAST_SIGN_LOSS, + CAST_POSSIBLE_TRUNCATION, + CAST_POSSIBLE_WRAP, + CAST_LOSSLESS, + UNNECESSARY_CAST, + CAST_PTR_ALIGNMENT, + FN_TO_NUMERIC_CAST, + FN_TO_NUMERIC_CAST_WITH_TRUNCATION, +]); + +/// Check if the given type is either `core::ffi::c_void` or +/// one of the platform specific `libc::::c_void` of libc. +fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { + if let ty::Adt(adt, _) = ty.kind() { + let names = cx.get_def_path(adt.did); + + if names.is_empty() { + return false; + } + if names[0] == sym::libc || names[0] == sym::core && *names.last().unwrap() == sym!(c_void) { + return true; + } + } + false +} + +/// Returns the mantissa bits wide of a fp type. +/// Will return 0 if the type is not a fp +fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { + match typ.kind() { + ty::Float(FloatTy::F32) => 23, + ty::Float(FloatTy::F64) | ty::Infer(InferTy::FloatVar(_)) => 52, + _ => 0, + } +} + +impl<'tcx> LateLintPass<'tcx> for Casts { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if expr.span.from_expansion() { + return; + } + if let ExprKind::Cast(ref ex, cast_to) = expr.kind { + if is_hir_ty_cfg_dependant(cx, cast_to) { + return; + } + let (cast_from, cast_to) = (cx.typeck_results().expr_ty(ex), cx.typeck_results().expr_ty(expr)); + lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to); + if let Some(lit) = get_numeric_literal(ex) { + let literal_str = snippet_opt(cx, ex.span).unwrap_or_default(); + + if_chain! { + if let LitKind::Int(n, _) = lit.node; + if let Some(src) = snippet_opt(cx, lit.span); + if cast_to.is_floating_point(); + if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node); + let from_nbits = 128 - n.leading_zeros(); + let to_nbits = fp_ty_mantissa_nbits(cast_to); + if from_nbits != 0 && to_nbits != 0 && from_nbits <= to_nbits && num_lit.is_decimal(); + then { + let literal_str = if is_unary_neg(ex) { format!("-{}", num_lit.integer) } else { num_lit.integer.into() }; + show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); + return; + } + } + + match lit.node { + LitKind::Int(_, LitIntType::Unsuffixed) if cast_to.is_integral() => { + show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); + }, + LitKind::Float(_, LitFloatType::Unsuffixed) if cast_to.is_floating_point() => { + show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); + }, + LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) => {}, + _ => { + if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) { + span_lint( + cx, + UNNECESSARY_CAST, + expr.span, + &format!( + "casting to the same type is unnecessary (`{}` -> `{}`)", + cast_from, cast_to + ), + ); + } + }, + } + } + if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { + lint_numeric_casts(cx, expr, ex, cast_from, cast_to); + } + + lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); + } else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind { + if_chain! { + if method_path.ident.name == sym!(cast); + if let Some(generic_args) = method_path.args; + if let [GenericArg::Type(cast_to)] = generic_args.args; + // There probably is no obvious reason to do this, just to be consistent with `as` cases. + if !is_hir_ty_cfg_dependant(cx, cast_to); + then { + let (cast_from, cast_to) = + (cx.typeck_results().expr_ty(&args[0]), cx.typeck_results().expr_ty(expr)); + lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); + } + } + } + } +} + +fn is_unary_neg(expr: &Expr<'_>) -> bool { + matches!(expr.kind, ExprKind::Unary(UnOp::Neg, _)) +} + +fn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<&'e Lit> { + match expr.kind { + ExprKind::Lit(ref lit) => Some(lit), + ExprKind::Unary(UnOp::Neg, e) => { + if let ExprKind::Lit(ref lit) = e.kind { + Some(lit) + } else { + None + } + }, + _ => None, + } +} + +fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) { + let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" }; + span_lint_and_sugg( + cx, + UNNECESSARY_CAST, + expr.span, + &format!("casting {} literal to `{}` is unnecessary", literal_kind_name, cast_to), + "try", + format!("{}_{}", literal_str.trim_end_matches('.'), cast_to), + Applicability::MachineApplicable, + ); +} + +fn lint_numeric_casts<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'tcx>, + cast_expr: &Expr<'_>, + cast_from: Ty<'tcx>, + cast_to: Ty<'tcx>, +) { + match (cast_from.is_integral(), cast_to.is_integral()) { + (true, false) => { + let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() { + 32 + } else { + 64 + }; + if is_isize_or_usize(cast_from) || from_nbits >= to_nbits { + span_precision_loss_lint(cx, expr, cast_from, to_nbits == 64); + } + if from_nbits < to_nbits { + span_lossless_lint(cx, expr, cast_expr, cast_from, cast_to); + } + }, + (false, true) => { + span_lint( + cx, + CAST_POSSIBLE_TRUNCATION, + expr.span, + &format!("casting `{}` to `{}` may truncate the value", cast_from, cast_to), + ); + if !cast_to.is_signed() { + span_lint( + cx, + CAST_SIGN_LOSS, + expr.span, + &format!( + "casting `{}` to `{}` may lose the sign of the value", + cast_from, cast_to + ), + ); + } + }, + (true, true) => { + check_loss_of_sign(cx, expr, cast_expr, cast_from, cast_to); + check_truncation_and_wrapping(cx, expr, cast_from, cast_to); + check_lossless(cx, expr, cast_expr, cast_from, cast_to); + }, + (false, false) => { + if let (&ty::Float(FloatTy::F64), &ty::Float(FloatTy::F32)) = (&cast_from.kind(), &cast_to.kind()) { + span_lint( + cx, + CAST_POSSIBLE_TRUNCATION, + expr.span, + "casting `f64` to `f32` may truncate the value", + ); + } + if let (&ty::Float(FloatTy::F32), &ty::Float(FloatTy::F64)) = (&cast_from.kind(), &cast_to.kind()) { + span_lossless_lint(cx, expr, cast_expr, cast_from, cast_to); + } + }, + } +} + +fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { + if_chain! { + if let ty::RawPtr(from_ptr_ty) = &cast_from.kind(); + if let ty::RawPtr(to_ptr_ty) = &cast_to.kind(); + if let Ok(from_layout) = cx.layout_of(from_ptr_ty.ty); + if let Ok(to_layout) = cx.layout_of(to_ptr_ty.ty); + if from_layout.align.abi < to_layout.align.abi; + // with c_void, we inherently need to trust the user + if !is_c_void(cx, from_ptr_ty.ty); + // when casting from a ZST, we don't know enough to properly lint + if !from_layout.is_zst(); + then { + span_lint( + cx, + CAST_PTR_ALIGNMENT, + expr.span, + &format!( + "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)", + cast_from, + cast_to, + from_layout.align.abi.bytes(), + to_layout.align.abi.bytes(), + ), + ); + } + } +} + +fn lint_fn_to_numeric_cast( + cx: &LateContext<'_>, + expr: &Expr<'_>, + cast_expr: &Expr<'_>, + cast_from: Ty<'_>, + cast_to: Ty<'_>, +) { + // We only want to check casts to `ty::Uint` or `ty::Int` + match cast_to.kind() { + ty::Uint(_) | ty::Int(..) => { /* continue on */ }, + _ => return, + } + match cast_from.kind() { + ty::FnDef(..) | ty::FnPtr(_) => { + let mut applicability = Applicability::MaybeIncorrect; + let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability); + + let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); + if to_nbits < cx.tcx.data_layout.pointer_size.bits() { + span_lint_and_sugg( + cx, + FN_TO_NUMERIC_CAST_WITH_TRUNCATION, + expr.span, + &format!( + "casting function pointer `{}` to `{}`, which truncates the value", + from_snippet, cast_to + ), + "try", + format!("{} as usize", from_snippet), + applicability, + ); + } else if *cast_to.kind() != ty::Uint(UintTy::Usize) { + span_lint_and_sugg( + cx, + FN_TO_NUMERIC_CAST, + expr.span, + &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), + "try", + format!("{} as usize", from_snippet), + applicability, + ); + } + }, + _ => {}, + } +} + +declare_clippy_lint! { + /// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. + /// + /// **Why is this bad?** It’s basically guaranteed to be undefined behaviour. + /// `UnsafeCell` is the only way to obtain aliasable data that is considered + /// mutable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// fn x(r: &i32) { + /// unsafe { + /// *(r as *const _ as *mut _) += 1; + /// } + /// } + /// ``` + /// + /// Instead consider using interior mutability types. + /// + /// ```rust + /// use std::cell::UnsafeCell; + /// + /// fn x(r: &UnsafeCell) { + /// unsafe { + /// *r.get() += 1; + /// } + /// } + /// ``` + pub CAST_REF_TO_MUT, + correctness, + "a cast of reference to a mutable pointer" +} + +declare_lint_pass!(RefToMut => [CAST_REF_TO_MUT]); + +impl<'tcx> LateLintPass<'tcx> for RefToMut { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if_chain! { + if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind; + if let ExprKind::Cast(e, t) = &e.kind; + if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind; + if let ExprKind::Cast(e, t) = &e.kind; + if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind; + if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind(); + then { + span_lint( + cx, + CAST_REF_TO_MUT, + expr.span, + "casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`", + ); + } + } + } +} + +const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0); + +declare_clippy_lint! { + /// **What it does:** Checks for expressions where a character literal is cast + /// to `u8` and suggests using a byte literal instead. + /// + /// **Why is this bad?** In general, casting values to smaller types is + /// error-prone and should be avoided where possible. In the particular case of + /// converting a character literal to u8, it is easy to avoid by just using a + /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter + /// than `'a' as u8`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// 'x' as u8 + /// ``` + /// + /// A better version, using the byte literal: + /// + /// ```rust,ignore + /// b'x' + /// ``` + pub CHAR_LIT_AS_U8, + complexity, + "casting a character literal to `u8` truncates" +} + +declare_lint_pass!(CharLitAsU8 => [CHAR_LIT_AS_U8]); + +impl<'tcx> LateLintPass<'tcx> for CharLitAsU8 { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if_chain! { + if !expr.span.from_expansion(); + if let ExprKind::Cast(e, _) = &expr.kind; + if let ExprKind::Lit(l) = &e.kind; + if let LitKind::Char(c) = l.node; + if ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(expr).kind(); + then { + let mut applicability = Applicability::MachineApplicable; + let snippet = snippet_with_applicability(cx, e.span, "'x'", &mut applicability); + + span_lint_and_then( + cx, + CHAR_LIT_AS_U8, + expr.span, + "casting a character literal to `u8` truncates", + |diag| { + diag.note("`char` is four bytes wide, but `u8` is a single byte"); + + if c.is_ascii() { + diag.span_suggestion( + expr.span, + "use a byte literal instead", + format!("b{}", snippet), + applicability, + ); + } + }); + } + } + } +} + +declare_clippy_lint! { + /// **What it does:** + /// Checks for `as` casts between raw pointers without changing its mutability, + /// namely `*const T` to `*const U` and `*mut T` to `*mut U`. + /// + /// **Why is this bad?** + /// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because + /// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// let ptr: *const u32 = &42_u32; + /// let mut_ptr: *mut u32 = &mut 42_u32; + /// let _ = ptr as *const i32; + /// let _ = mut_ptr as *mut i32; + /// ``` + /// Use instead: + /// ```rust + /// let ptr: *const u32 = &42_u32; + /// let mut_ptr: *mut u32 = &mut 42_u32; + /// let _ = ptr.cast::(); + /// let _ = mut_ptr.cast::(); + /// ``` + pub PTR_AS_PTR, + pedantic, + "casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`" +} + +pub struct PtrAsPtr { + msrv: Option, +} + +impl PtrAsPtr { + #[must_use] + pub fn new(msrv: Option) -> Self { + Self { msrv } + } +} + +impl_lint_pass!(PtrAsPtr => [PTR_AS_PTR]); + +impl<'tcx> LateLintPass<'tcx> for PtrAsPtr { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if !meets_msrv(self.msrv.as_ref(), &PTR_AS_PTR_MSRV) { + return; + } + + if expr.span.from_expansion() { + return; + } + + if_chain! { + if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind; + let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr)); + if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind(); + if let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind(); + if matches!((from_mutbl, to_mutbl), + (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut)); + // The `U` in `pointer::cast` have to be `Sized` + // as explained here: https://github.com/rust-lang/rust/issues/60602. + if to_pointee_ty.is_sized(cx.tcx.at(expr.span), cx.param_env); + then { + let mut applicability = Applicability::MachineApplicable; + let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability); + let turbofish = match &cast_to_hir_ty.kind { + TyKind::Infer => Cow::Borrowed(""), + TyKind::Ptr(mut_ty) if matches!(mut_ty.ty.kind, TyKind::Infer) => Cow::Borrowed(""), + _ => Cow::Owned(format!("::<{}>", to_pointee_ty)), + }; + span_lint_and_sugg( + cx, + PTR_AS_PTR, + expr.span, + "`as` casting between raw pointers without changing its mutability", + "try `pointer::cast`, a safer alternative", + format!("{}.cast{}()", cast_expr_sugg.maybe_par(), turbofish), + applicability, + ); + } + } + } + + extract_msrv_attr!(LateContext); +} + +fn is_isize_or_usize(typ: Ty<'_>) -> bool { + matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 8259fd3c320be..a46c56a01d5d5 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -182,6 +182,7 @@ mod booleans; mod bytecount; mod cargo_common_metadata; mod case_sensitive_file_extension_comparisons; +mod casts; mod checked_conversions; mod cognitive_complexity; mod collapsible_if; @@ -586,6 +587,18 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &bytecount::NAIVE_BYTECOUNT, &cargo_common_metadata::CARGO_COMMON_METADATA, &case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS, + &casts::CAST_LOSSLESS, + &casts::CAST_POSSIBLE_TRUNCATION, + &casts::CAST_POSSIBLE_WRAP, + &casts::CAST_PRECISION_LOSS, + &casts::CAST_PTR_ALIGNMENT, + &casts::CAST_REF_TO_MUT, + &casts::CAST_SIGN_LOSS, + &casts::CHAR_LIT_AS_U8, + &casts::FN_TO_NUMERIC_CAST, + &casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION, + &casts::PTR_AS_PTR, + &casts::UNNECESSARY_CAST, &checked_conversions::CHECKED_CONVERSIONS, &cognitive_complexity::COGNITIVE_COMPLEXITY, &collapsible_if::COLLAPSIBLE_ELSE_IF, @@ -943,28 +956,16 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &types::ABSURD_EXTREME_COMPARISONS, &types::BORROWED_BOX, &types::BOX_VEC, - &types::CAST_LOSSLESS, - &types::CAST_POSSIBLE_TRUNCATION, - &types::CAST_POSSIBLE_WRAP, - &types::CAST_PRECISION_LOSS, - &types::CAST_PTR_ALIGNMENT, - &types::CAST_REF_TO_MUT, - &types::CAST_SIGN_LOSS, - &types::CHAR_LIT_AS_U8, - &types::FN_TO_NUMERIC_CAST, - &types::FN_TO_NUMERIC_CAST_WITH_TRUNCATION, &types::IMPLICIT_HASHER, &types::INVALID_UPCAST_COMPARISONS, &types::LET_UNIT_VALUE, &types::LINKEDLIST, &types::OPTION_OPTION, - &types::PTR_AS_PTR, &types::RC_BUFFER, &types::REDUNDANT_ALLOCATION, &types::TYPE_COMPLEXITY, &types::UNIT_ARG, &types::UNIT_CMP, - &types::UNNECESSARY_CAST, &types::VEC_BOX, &undropped_manually_drops::UNDROPPED_MANUALLY_DROPS, &unicode::INVISIBLE_CHARACTERS, @@ -1086,7 +1087,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box main_recursion::MainRecursion::default()); store.register_late_pass(|| box lifetimes::Lifetimes); store.register_late_pass(|| box entry::HashMapPass); - store.register_late_pass(|| box types::Casts); + store.register_late_pass(|| box casts::Casts); let type_complexity_threshold = conf.type_complexity_threshold; store.register_late_pass(move || box types::TypeComplexity::new(type_complexity_threshold)); store.register_late_pass(|| box minmax::MinMaxPass); @@ -1107,7 +1108,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box panic_unimplemented::PanicUnimplemented); store.register_late_pass(|| box strings::StringLitAsBytes); store.register_late_pass(|| box derive::Derive); - store.register_late_pass(|| box types::CharLitAsU8); + store.register_late_pass(|| box casts::CharLitAsU8); store.register_late_pass(|| box get_last_with_len::GetLastWithLen); store.register_late_pass(|| box drop_forget_ref::DropForgetRef); store.register_late_pass(|| box empty_enum::EmptyEnum); @@ -1175,7 +1176,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box slow_vector_initialization::SlowVectorInit); store.register_late_pass(|| box unnecessary_sort_by::UnnecessarySortBy); store.register_late_pass(|| box unnecessary_wraps::UnnecessaryWraps); - store.register_late_pass(|| box types::RefToMut); + store.register_late_pass(|| box casts::RefToMut); store.register_late_pass(|| box assertions_on_constants::AssertionsOnConstants); store.register_late_pass(|| box transmuting_null::TransmutingNull); store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite); @@ -1277,7 +1278,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box strings::StringToString); store.register_late_pass(|| box zero_sized_map_values::ZeroSizedMapValues); store.register_late_pass(|| box vec_init_then_push::VecInitThenPush::default()); - store.register_late_pass(move || box types::PtrAsPtr::new(msrv)); + store.register_late_pass(move || box casts::PtrAsPtr::new(msrv)); store.register_late_pass(|| box case_sensitive_file_extension_comparisons::CaseSensitiveFileExtensionComparisons); store.register_late_pass(|| box redundant_slicing::RedundantSlicing); store.register_late_pass(|| box from_str_radix_10::FromStrRadix10); @@ -1345,6 +1346,13 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&bit_mask::VERBOSE_BIT_MASK), LintId::of(&bytecount::NAIVE_BYTECOUNT), LintId::of(&case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS), + LintId::of(&casts::CAST_LOSSLESS), + LintId::of(&casts::CAST_POSSIBLE_TRUNCATION), + LintId::of(&casts::CAST_POSSIBLE_WRAP), + LintId::of(&casts::CAST_PRECISION_LOSS), + LintId::of(&casts::CAST_PTR_ALIGNMENT), + LintId::of(&casts::CAST_SIGN_LOSS), + LintId::of(&casts::PTR_AS_PTR), LintId::of(&checked_conversions::CHECKED_CONVERSIONS), LintId::of(&copies::SAME_FUNCTIONS_IN_IF_CONDITION), LintId::of(©_iterator::COPY_ITERATOR), @@ -1404,18 +1412,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&strings::STRING_ADD_ASSIGN), LintId::of(&trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS), LintId::of(&trait_bounds::TYPE_REPETITION_IN_BOUNDS), - LintId::of(&types::CAST_LOSSLESS), - LintId::of(&types::CAST_POSSIBLE_TRUNCATION), - LintId::of(&types::CAST_POSSIBLE_WRAP), - LintId::of(&types::CAST_PRECISION_LOSS), - LintId::of(&types::CAST_PTR_ALIGNMENT), - LintId::of(&types::CAST_SIGN_LOSS), LintId::of(&types::IMPLICIT_HASHER), LintId::of(&types::INVALID_UPCAST_COMPARISONS), LintId::of(&types::LET_UNIT_VALUE), LintId::of(&types::LINKEDLIST), LintId::of(&types::OPTION_OPTION), - LintId::of(&types::PTR_AS_PTR), LintId::of(&unicode::NON_ASCII_LITERAL), LintId::of(&unicode::UNICODE_NOT_NFC), LintId::of(&unnecessary_wraps::UNNECESSARY_WRAPS), @@ -1459,6 +1460,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS), LintId::of(&booleans::LOGIC_BUG), LintId::of(&booleans::NONMINIMAL_BOOL), + LintId::of(&casts::CAST_REF_TO_MUT), + LintId::of(&casts::CHAR_LIT_AS_U8), + LintId::of(&casts::FN_TO_NUMERIC_CAST), + LintId::of(&casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION), + LintId::of(&casts::UNNECESSARY_CAST), LintId::of(&collapsible_if::COLLAPSIBLE_ELSE_IF), LintId::of(&collapsible_if::COLLAPSIBLE_IF), LintId::of(&collapsible_match::COLLAPSIBLE_MATCH), @@ -1699,15 +1705,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&types::ABSURD_EXTREME_COMPARISONS), LintId::of(&types::BORROWED_BOX), LintId::of(&types::BOX_VEC), - LintId::of(&types::CAST_REF_TO_MUT), - LintId::of(&types::CHAR_LIT_AS_U8), - LintId::of(&types::FN_TO_NUMERIC_CAST), - LintId::of(&types::FN_TO_NUMERIC_CAST_WITH_TRUNCATION), LintId::of(&types::REDUNDANT_ALLOCATION), LintId::of(&types::TYPE_COMPLEXITY), LintId::of(&types::UNIT_ARG), LintId::of(&types::UNIT_CMP), - LintId::of(&types::UNNECESSARY_CAST), LintId::of(&types::VEC_BOX), LintId::of(&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS), LintId::of(&unicode::INVISIBLE_CHARACTERS), @@ -1740,6 +1741,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS), LintId::of(&blacklisted_name::BLACKLISTED_NAME), LintId::of(&blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS), + LintId::of(&casts::FN_TO_NUMERIC_CAST), + LintId::of(&casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION), LintId::of(&collapsible_if::COLLAPSIBLE_ELSE_IF), LintId::of(&collapsible_if::COLLAPSIBLE_IF), LintId::of(&collapsible_match::COLLAPSIBLE_MATCH), @@ -1836,8 +1839,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&tabs_in_doc_comments::TABS_IN_DOC_COMMENTS), LintId::of(&to_digit_is_some::TO_DIGIT_IS_SOME), LintId::of(&try_err::TRY_ERR), - LintId::of(&types::FN_TO_NUMERIC_CAST), - LintId::of(&types::FN_TO_NUMERIC_CAST_WITH_TRUNCATION), LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME), LintId::of(&unused_unit::UNUSED_UNIT), LintId::of(&upper_case_acronyms::UPPER_CASE_ACRONYMS), @@ -1853,6 +1854,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&assign_ops::MISREFACTORED_ASSIGN_OP), LintId::of(&attrs::DEPRECATED_CFG_ATTR), LintId::of(&booleans::NONMINIMAL_BOOL), + LintId::of(&casts::CHAR_LIT_AS_U8), + LintId::of(&casts::UNNECESSARY_CAST), LintId::of(&double_comparison::DOUBLE_COMPARISONS), LintId::of(&double_parens::DOUBLE_PARENS), LintId::of(&duration_subsec::DURATION_SUBSEC), @@ -1929,10 +1932,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&transmute::TRANSMUTE_PTR_TO_PTR), LintId::of(&transmute::TRANSMUTE_PTR_TO_REF), LintId::of(&types::BORROWED_BOX), - LintId::of(&types::CHAR_LIT_AS_U8), LintId::of(&types::TYPE_COMPLEXITY), LintId::of(&types::UNIT_ARG), - LintId::of(&types::UNNECESSARY_CAST), LintId::of(&types::VEC_BOX), LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY), LintId::of(&unwrap::UNNECESSARY_UNWRAP), @@ -1950,6 +1951,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&bit_mask::BAD_BIT_MASK), LintId::of(&bit_mask::INEFFECTIVE_BIT_MASK), LintId::of(&booleans::LOGIC_BUG), + LintId::of(&casts::CAST_REF_TO_MUT), LintId::of(&copies::IFS_SAME_COND), LintId::of(&copies::IF_SAME_THEN_ELSE), LintId::of(&derive::DERIVE_HASH_XOR_EQ), @@ -2002,7 +2004,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&transmute::WRONG_TRANSMUTE), LintId::of(&transmuting_null::TRANSMUTING_NULL), LintId::of(&types::ABSURD_EXTREME_COMPARISONS), - LintId::of(&types::CAST_REF_TO_MUT), LintId::of(&types::UNIT_CMP), LintId::of(&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS), LintId::of(&unicode::INVISIBLE_CHARACTERS), diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 25cc40917c301..3e7aa53d5bc9e 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -14,20 +14,18 @@ use std::cmp::Ordering; use std::collections::BTreeMap; use if_chain::if_chain; -use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; use rustc_hir::{ BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericParamKind, HirId, ImplItem, - ImplItemKind, Item, ItemKind, Lit, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt, StmtKind, TraitFn, - TraitItem, TraitItemKind, TyKind, UnOp, + ImplItemKind, Item, ItemKind, Local, MatchSource, MutTy, Node, QPath, Stmt, StmtKind, TraitFn, TraitItem, + TraitItemKind, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TyS, TypeAndMut, TypeckResults, UintTy}; -use rustc_semver::RustcVersion; +use rustc_middle::ty::{self, IntTy, Ty, TyS, TypeckResults, UintTy}; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::Span; @@ -38,12 +36,10 @@ use rustc_typeck::hir_ty_to_ty; use crate::consts::{constant, Constant}; use crate::utils::paths; -use crate::utils::sugg::Sugg; use crate::utils::{ - clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant, - is_type_diagnostic_item, match_path, meets_msrv, method_chain_args, multispan_sugg, - numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, - snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext, + clip, comparisons, differing_macro_contexts, higher, indent_of, int_bits, is_type_diagnostic_item, match_path, + multispan_sugg, reindent_multiline, sext, snippet, snippet_opt, snippet_with_macro_callsite, span_lint, + span_lint_and_help, span_lint_and_then, unsext, }; declare_clippy_lint! { @@ -778,749 +774,6 @@ fn is_unit_literal(expr: &Expr<'_>) -> bool { matches!(expr.kind, ExprKind::Tup(ref slice) if slice.is_empty()) } -declare_clippy_lint! { - /// **What it does:** Checks for casts from any numerical to a float type where - /// the receiving type cannot store all values from the original type without - /// rounding errors. This possible rounding is to be expected, so this lint is - /// `Allow` by default. - /// - /// Basically, this warns on casting any integer with 32 or more bits to `f32` - /// or any 64-bit integer to `f64`. - /// - /// **Why is this bad?** It's not bad at all. But in some applications it can be - /// helpful to know where precision loss can take place. This lint can help find - /// those places in the code. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// let x = u64::MAX; - /// x as f64; - /// ``` - pub CAST_PRECISION_LOSS, - pedantic, - "casts that cause loss of precision, e.g., `x as f32` where `x: u64`" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts from a signed to an unsigned numerical - /// type. In this case, negative values wrap around to large positive values, - /// which can be quite surprising in practice. However, as the cast works as - /// defined, this lint is `Allow` by default. - /// - /// **Why is this bad?** Possibly surprising results. You can activate this lint - /// as a one-time check to see where numerical wrapping can arise. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// let y: i8 = -1; - /// y as u128; // will return 18446744073709551615 - /// ``` - pub CAST_SIGN_LOSS, - pedantic, - "casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts between numerical types that may - /// truncate large values. This is expected behavior, so the cast is `Allow` by - /// default. - /// - /// **Why is this bad?** In some problem domains, it is good practice to avoid - /// truncation. This lint can be activated to help assess where additional - /// checks could be beneficial. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// fn as_u8(x: u64) -> u8 { - /// x as u8 - /// } - /// ``` - pub CAST_POSSIBLE_TRUNCATION, - pedantic, - "casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts from an unsigned type to a signed type of - /// the same size. Performing such a cast is a 'no-op' for the compiler, - /// i.e., nothing is changed at the bit level, and the binary representation of - /// the value is reinterpreted. This can cause wrapping if the value is too big - /// for the target signed type. However, the cast works as defined, so this lint - /// is `Allow` by default. - /// - /// **Why is this bad?** While such a cast is not bad in itself, the results can - /// be surprising when this is not the intended behavior, as demonstrated by the - /// example below. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// u32::MAX as i32; // will yield a value of `-1` - /// ``` - pub CAST_POSSIBLE_WRAP, - pedantic, - "casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts between numerical types that may - /// be replaced by safe conversion functions. - /// - /// **Why is this bad?** Rust's `as` keyword will perform many kinds of - /// conversions, including silently lossy conversions. Conversion functions such - /// as `i32::from` will only perform lossless conversions. Using the conversion - /// functions prevents conversions from turning into silent lossy conversions if - /// the types of the input expressions ever change, and make it easier for - /// people reading the code to know that the conversion is lossless. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// fn as_u64(x: u8) -> u64 { - /// x as u64 - /// } - /// ``` - /// - /// Using `::from` would look like this: - /// - /// ```rust - /// fn as_u64(x: u8) -> u64 { - /// u64::from(x) - /// } - /// ``` - pub CAST_LOSSLESS, - pedantic, - "casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts to the same type, casts of int literals to integer types - /// and casts of float literals to float types. - /// - /// **Why is this bad?** It's just unnecessary. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// let _ = 2i32 as i32; - /// let _ = 0.5 as f32; - /// ``` - /// - /// Better: - /// - /// ```rust - /// let _ = 2_i32; - /// let _ = 0.5_f32; - /// ``` - pub UNNECESSARY_CAST, - complexity, - "cast to the same type, e.g., `x as i32` where `x: i32`" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts, using `as` or `pointer::cast`, - /// from a less-strictly-aligned pointer to a more-strictly-aligned pointer - /// - /// **Why is this bad?** Dereferencing the resulting pointer may be undefined - /// behavior. - /// - /// **Known problems:** Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar - /// on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like - /// u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis. - /// - /// **Example:** - /// ```rust - /// let _ = (&1u8 as *const u8) as *const u16; - /// let _ = (&mut 1u8 as *mut u8) as *mut u16; - /// - /// (&1u8 as *const u8).cast::(); - /// (&mut 1u8 as *mut u8).cast::(); - /// ``` - pub CAST_PTR_ALIGNMENT, - pedantic, - "cast from a pointer to a more-strictly-aligned pointer" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts of function pointers to something other than usize - /// - /// **Why is this bad?** - /// Casting a function pointer to anything other than usize/isize is not portable across - /// architectures, because you end up losing bits if the target type is too small or end up with a - /// bunch of extra bits that waste space and add more instructions to the final binary than - /// strictly necessary for the problem - /// - /// Casting to isize also doesn't make sense since there are no signed addresses. - /// - /// **Example** - /// - /// ```rust - /// // Bad - /// fn fun() -> i32 { 1 } - /// let a = fun as i64; - /// - /// // Good - /// fn fun2() -> i32 { 1 } - /// let a = fun2 as usize; - /// ``` - pub FN_TO_NUMERIC_CAST, - style, - "casting a function pointer to a numeric type other than usize" -} - -declare_clippy_lint! { - /// **What it does:** Checks for casts of a function pointer to a numeric type not wide enough to - /// store address. - /// - /// **Why is this bad?** - /// Such a cast discards some bits of the function's address. If this is intended, it would be more - /// clearly expressed by casting to usize first, then casting the usize to the intended type (with - /// a comment) to perform the truncation. - /// - /// **Example** - /// - /// ```rust - /// // Bad - /// fn fn1() -> i16 { - /// 1 - /// }; - /// let _ = fn1 as i32; - /// - /// // Better: Cast to usize first, then comment with the reason for the truncation - /// fn fn2() -> i16 { - /// 1 - /// }; - /// let fn_ptr = fn2 as usize; - /// let fn_ptr_truncated = fn_ptr as i32; - /// ``` - pub FN_TO_NUMERIC_CAST_WITH_TRUNCATION, - style, - "casting a function pointer to a numeric type not wide enough to store the address" -} - -/// Returns the size in bits of an integral type. -/// Will return 0 if the type is not an int or uint variant -fn int_ty_to_nbits(typ: Ty<'_>, tcx: TyCtxt<'_>) -> u64 { - match typ.kind() { - ty::Int(i) => match i { - IntTy::Isize => tcx.data_layout.pointer_size.bits(), - IntTy::I8 => 8, - IntTy::I16 => 16, - IntTy::I32 => 32, - IntTy::I64 => 64, - IntTy::I128 => 128, - }, - ty::Uint(i) => match i { - UintTy::Usize => tcx.data_layout.pointer_size.bits(), - UintTy::U8 => 8, - UintTy::U16 => 16, - UintTy::U32 => 32, - UintTy::U64 => 64, - UintTy::U128 => 128, - }, - _ => 0, - } -} - -fn is_isize_or_usize(typ: Ty<'_>) -> bool { - matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) -} - -fn span_precision_loss_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to_f64: bool) { - let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; - let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; - let arch_dependent_str = "on targets with 64-bit wide pointers "; - let from_nbits_str = if arch_dependent { - "64".to_owned() - } else if is_isize_or_usize(cast_from) { - "32 or 64".to_owned() - } else { - int_ty_to_nbits(cast_from, cx.tcx).to_string() - }; - span_lint( - cx, - CAST_PRECISION_LOSS, - expr.span, - &format!( - "casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \ - but `{1}`'s mantissa is only {4} bits wide)", - cast_from, - if cast_to_f64 { "f64" } else { "f32" }, - if arch_dependent { arch_dependent_str } else { "" }, - from_nbits_str, - mantissa_nbits - ), - ); -} - -fn should_strip_parens(op: &Expr<'_>, snip: &str) -> bool { - if let ExprKind::Binary(_, _, _) = op.kind { - if snip.starts_with('(') && snip.ends_with(')') { - return true; - } - } - false -} - -fn span_lossless_lint(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - // Do not suggest using From in consts/statics until it is valid to do so (see #2267). - if in_constant(cx, expr.hir_id) { - return; - } - // The suggestion is to use a function call, so if the original expression - // has parens on the outside, they are no longer needed. - let mut applicability = Applicability::MachineApplicable; - let opt = snippet_opt(cx, op.span); - let sugg = opt.as_ref().map_or_else( - || { - applicability = Applicability::HasPlaceholders; - ".." - }, - |snip| { - if should_strip_parens(op, snip) { - &snip[1..snip.len() - 1] - } else { - snip.as_str() - } - }, - ); - - span_lint_and_sugg( - cx, - CAST_LOSSLESS, - expr.span, - &format!( - "casting `{}` to `{}` may become silently lossy if you later change the type", - cast_from, cast_to - ), - "try", - format!("{}::from({})", cast_to, sugg), - applicability, - ); -} - -enum ArchSuffix { - _32, - _64, - None, -} - -fn check_loss_of_sign(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - if !cast_from.is_signed() || cast_to.is_signed() { - return; - } - - // don't lint for positive constants - let const_val = constant(cx, &cx.typeck_results(), op); - if_chain! { - if let Some((Constant::Int(n), _)) = const_val; - if let ty::Int(ity) = *cast_from.kind(); - if sext(cx.tcx, n, ity) >= 0; - then { - return - } - } - - // don't lint for the result of methods that always return non-negative values - if let ExprKind::MethodCall(ref path, _, _, _) = op.kind { - let mut method_name = path.ident.name.as_str(); - let allowed_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"]; - - if_chain! { - if method_name == "unwrap"; - if let Some(arglist) = method_chain_args(op, &["unwrap"]); - if let ExprKind::MethodCall(ref inner_path, _, _, _) = &arglist[0][0].kind; - then { - method_name = inner_path.ident.name.as_str(); - } - } - - if allowed_methods.iter().any(|&name| method_name == name) { - return; - } - } - - span_lint( - cx, - CAST_SIGN_LOSS, - expr.span, - &format!( - "casting `{}` to `{}` may lose the sign of the value", - cast_from, cast_to - ), - ); -} - -fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - let arch_64_suffix = " on targets with 64-bit wide pointers"; - let arch_32_suffix = " on targets with 32-bit wide pointers"; - let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); - let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); - let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); - let (span_truncation, suffix_truncation, span_wrap, suffix_wrap) = - match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { - (true, true) | (false, false) => ( - to_nbits < from_nbits, - ArchSuffix::None, - to_nbits == from_nbits && cast_unsigned_to_signed, - ArchSuffix::None, - ), - (true, false) => ( - to_nbits <= 32, - if to_nbits == 32 { - ArchSuffix::_64 - } else { - ArchSuffix::None - }, - to_nbits <= 32 && cast_unsigned_to_signed, - ArchSuffix::_32, - ), - (false, true) => ( - from_nbits == 64, - ArchSuffix::_32, - cast_unsigned_to_signed, - if from_nbits == 64 { - ArchSuffix::_64 - } else { - ArchSuffix::_32 - }, - ), - }; - if span_truncation { - span_lint( - cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - &format!( - "casting `{}` to `{}` may truncate the value{}", - cast_from, - cast_to, - match suffix_truncation { - ArchSuffix::_32 => arch_32_suffix, - ArchSuffix::_64 => arch_64_suffix, - ArchSuffix::None => "", - } - ), - ); - } - if span_wrap { - span_lint( - cx, - CAST_POSSIBLE_WRAP, - expr.span, - &format!( - "casting `{}` to `{}` may wrap around the value{}", - cast_from, - cast_to, - match suffix_wrap { - ArchSuffix::_32 => arch_32_suffix, - ArchSuffix::_64 => arch_64_suffix, - ArchSuffix::None => "", - } - ), - ); - } -} - -fn check_lossless(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed(); - let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); - let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); - if !is_isize_or_usize(cast_from) && !is_isize_or_usize(cast_to) && from_nbits < to_nbits && !cast_signed_to_unsigned - { - span_lossless_lint(cx, expr, op, cast_from, cast_to); - } -} - -declare_lint_pass!(Casts => [ - CAST_PRECISION_LOSS, - CAST_SIGN_LOSS, - CAST_POSSIBLE_TRUNCATION, - CAST_POSSIBLE_WRAP, - CAST_LOSSLESS, - UNNECESSARY_CAST, - CAST_PTR_ALIGNMENT, - FN_TO_NUMERIC_CAST, - FN_TO_NUMERIC_CAST_WITH_TRUNCATION, -]); - -// Check if the given type is either `core::ffi::c_void` or -// one of the platform specific `libc::::c_void` of libc. -fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - if let ty::Adt(adt, _) = ty.kind() { - let names = cx.get_def_path(adt.did); - - if names.is_empty() { - return false; - } - if names[0] == sym::libc || names[0] == sym::core && *names.last().unwrap() == sym!(c_void) { - return true; - } - } - false -} - -/// Returns the mantissa bits wide of a fp type. -/// Will return 0 if the type is not a fp -fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { - match typ.kind() { - ty::Float(FloatTy::F32) => 23, - ty::Float(FloatTy::F64) | ty::Infer(InferTy::FloatVar(_)) => 52, - _ => 0, - } -} - -impl<'tcx> LateLintPass<'tcx> for Casts { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if expr.span.from_expansion() { - return; - } - if let ExprKind::Cast(ref ex, cast_to) = expr.kind { - if is_hir_ty_cfg_dependant(cx, cast_to) { - return; - } - let (cast_from, cast_to) = (cx.typeck_results().expr_ty(ex), cx.typeck_results().expr_ty(expr)); - lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to); - if let Some(lit) = get_numeric_literal(ex) { - let literal_str = snippet_opt(cx, ex.span).unwrap_or_default(); - - if_chain! { - if let LitKind::Int(n, _) = lit.node; - if let Some(src) = snippet_opt(cx, lit.span); - if cast_to.is_floating_point(); - if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node); - let from_nbits = 128 - n.leading_zeros(); - let to_nbits = fp_ty_mantissa_nbits(cast_to); - if from_nbits != 0 && to_nbits != 0 && from_nbits <= to_nbits && num_lit.is_decimal(); - then { - let literal_str = if is_unary_neg(ex) { format!("-{}", num_lit.integer) } else { num_lit.integer.into() }; - show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); - return; - } - } - - match lit.node { - LitKind::Int(_, LitIntType::Unsuffixed) if cast_to.is_integral() => { - show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); - }, - LitKind::Float(_, LitFloatType::Unsuffixed) if cast_to.is_floating_point() => { - show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); - }, - LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) => {}, - _ => { - if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) { - span_lint( - cx, - UNNECESSARY_CAST, - expr.span, - &format!( - "casting to the same type is unnecessary (`{}` -> `{}`)", - cast_from, cast_to - ), - ); - } - }, - } - } - if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { - lint_numeric_casts(cx, expr, ex, cast_from, cast_to); - } - - lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); - } else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind { - if_chain! { - if method_path.ident.name == sym!(cast); - if let Some(generic_args) = method_path.args; - if let [GenericArg::Type(cast_to)] = generic_args.args; - // There probably is no obvious reason to do this, just to be consistent with `as` cases. - if !is_hir_ty_cfg_dependant(cx, cast_to); - then { - let (cast_from, cast_to) = - (cx.typeck_results().expr_ty(&args[0]), cx.typeck_results().expr_ty(expr)); - lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); - } - } - } - } -} - -fn is_unary_neg(expr: &Expr<'_>) -> bool { - matches!(expr.kind, ExprKind::Unary(UnOp::Neg, _)) -} - -fn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<&'e Lit> { - match expr.kind { - ExprKind::Lit(ref lit) => Some(lit), - ExprKind::Unary(UnOp::Neg, e) => { - if let ExprKind::Lit(ref lit) = e.kind { - Some(lit) - } else { - None - } - }, - _ => None, - } -} - -fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) { - let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" }; - span_lint_and_sugg( - cx, - UNNECESSARY_CAST, - expr.span, - &format!("casting {} literal to `{}` is unnecessary", literal_kind_name, cast_to), - "try", - format!("{}_{}", literal_str.trim_end_matches('.'), cast_to), - Applicability::MachineApplicable, - ); -} - -fn lint_numeric_casts<'tcx>( - cx: &LateContext<'tcx>, - expr: &Expr<'tcx>, - cast_expr: &Expr<'_>, - cast_from: Ty<'tcx>, - cast_to: Ty<'tcx>, -) { - match (cast_from.is_integral(), cast_to.is_integral()) { - (true, false) => { - let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); - let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() { - 32 - } else { - 64 - }; - if is_isize_or_usize(cast_from) || from_nbits >= to_nbits { - span_precision_loss_lint(cx, expr, cast_from, to_nbits == 64); - } - if from_nbits < to_nbits { - span_lossless_lint(cx, expr, cast_expr, cast_from, cast_to); - } - }, - (false, true) => { - span_lint( - cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - &format!("casting `{}` to `{}` may truncate the value", cast_from, cast_to), - ); - if !cast_to.is_signed() { - span_lint( - cx, - CAST_SIGN_LOSS, - expr.span, - &format!( - "casting `{}` to `{}` may lose the sign of the value", - cast_from, cast_to - ), - ); - } - }, - (true, true) => { - check_loss_of_sign(cx, expr, cast_expr, cast_from, cast_to); - check_truncation_and_wrapping(cx, expr, cast_from, cast_to); - check_lossless(cx, expr, cast_expr, cast_from, cast_to); - }, - (false, false) => { - if let (&ty::Float(FloatTy::F64), &ty::Float(FloatTy::F32)) = (&cast_from.kind(), &cast_to.kind()) { - span_lint( - cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - "casting `f64` to `f32` may truncate the value", - ); - } - if let (&ty::Float(FloatTy::F32), &ty::Float(FloatTy::F64)) = (&cast_from.kind(), &cast_to.kind()) { - span_lossless_lint(cx, expr, cast_expr, cast_from, cast_to); - } - }, - } -} - -fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { - if_chain! { - if let ty::RawPtr(from_ptr_ty) = &cast_from.kind(); - if let ty::RawPtr(to_ptr_ty) = &cast_to.kind(); - if let Ok(from_layout) = cx.layout_of(from_ptr_ty.ty); - if let Ok(to_layout) = cx.layout_of(to_ptr_ty.ty); - if from_layout.align.abi < to_layout.align.abi; - // with c_void, we inherently need to trust the user - if !is_c_void(cx, from_ptr_ty.ty); - // when casting from a ZST, we don't know enough to properly lint - if !from_layout.is_zst(); - then { - span_lint( - cx, - CAST_PTR_ALIGNMENT, - expr.span, - &format!( - "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)", - cast_from, - cast_to, - from_layout.align.abi.bytes(), - to_layout.align.abi.bytes(), - ), - ); - } - } -} - -fn lint_fn_to_numeric_cast( - cx: &LateContext<'_>, - expr: &Expr<'_>, - cast_expr: &Expr<'_>, - cast_from: Ty<'_>, - cast_to: Ty<'_>, -) { - // We only want to check casts to `ty::Uint` or `ty::Int` - match cast_to.kind() { - ty::Uint(_) | ty::Int(..) => { /* continue on */ }, - _ => return, - } - match cast_from.kind() { - ty::FnDef(..) | ty::FnPtr(_) => { - let mut applicability = Applicability::MaybeIncorrect; - let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability); - - let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); - if to_nbits < cx.tcx.data_layout.pointer_size.bits() { - span_lint_and_sugg( - cx, - FN_TO_NUMERIC_CAST_WITH_TRUNCATION, - expr.span, - &format!( - "casting function pointer `{}` to `{}`, which truncates the value", - from_snippet, cast_to - ), - "try", - format!("{} as usize", from_snippet), - applicability, - ); - } else if *cast_to.kind() != ty::Uint(UintTy::Usize) { - span_lint_and_sugg( - cx, - FN_TO_NUMERIC_CAST, - expr.span, - &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), - "try", - format!("{} as usize", from_snippet), - applicability, - ); - } - }, - _ => {}, - } -} - declare_clippy_lint! { /// **What it does:** Checks for types used in structs, parameters and `let` /// declarations above a certain complexity threshold. @@ -1686,69 +939,6 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { } } -declare_clippy_lint! { - /// **What it does:** Checks for expressions where a character literal is cast - /// to `u8` and suggests using a byte literal instead. - /// - /// **Why is this bad?** In general, casting values to smaller types is - /// error-prone and should be avoided where possible. In the particular case of - /// converting a character literal to u8, it is easy to avoid by just using a - /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter - /// than `'a' as u8`. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust,ignore - /// 'x' as u8 - /// ``` - /// - /// A better version, using the byte literal: - /// - /// ```rust,ignore - /// b'x' - /// ``` - pub CHAR_LIT_AS_U8, - complexity, - "casting a character literal to `u8` truncates" -} - -declare_lint_pass!(CharLitAsU8 => [CHAR_LIT_AS_U8]); - -impl<'tcx> LateLintPass<'tcx> for CharLitAsU8 { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if_chain! { - if !expr.span.from_expansion(); - if let ExprKind::Cast(e, _) = &expr.kind; - if let ExprKind::Lit(l) = &e.kind; - if let LitKind::Char(c) = l.node; - if ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(expr).kind(); - then { - let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, e.span, "'x'", &mut applicability); - - span_lint_and_then( - cx, - CHAR_LIT_AS_U8, - expr.span, - "casting a character literal to `u8` truncates", - |diag| { - diag.note("`char` is four bytes wide, but `u8` is a single byte"); - - if c.is_ascii() { - diag.span_suggestion( - expr.span, - "use a byte literal instead", - format!("b{}", snippet), - applicability, - ); - } - }); - } - } - } -} - declare_clippy_lint! { /// **What it does:** Checks for comparisons where one side of the relation is /// either the minimum or maximum value for its type and warns if it involves a @@ -2477,149 +1667,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't } } -declare_clippy_lint! { - /// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. - /// - /// **Why is this bad?** It’s basically guaranteed to be undefined behaviour. - /// `UnsafeCell` is the only way to obtain aliasable data that is considered - /// mutable. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust,ignore - /// fn x(r: &i32) { - /// unsafe { - /// *(r as *const _ as *mut _) += 1; - /// } - /// } - /// ``` - /// - /// Instead consider using interior mutability types. - /// - /// ```rust - /// use std::cell::UnsafeCell; - /// - /// fn x(r: &UnsafeCell) { - /// unsafe { - /// *r.get() += 1; - /// } - /// } - /// ``` - pub CAST_REF_TO_MUT, - correctness, - "a cast of reference to a mutable pointer" -} - -declare_lint_pass!(RefToMut => [CAST_REF_TO_MUT]); - -impl<'tcx> LateLintPass<'tcx> for RefToMut { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if_chain! { - if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind; - if let ExprKind::Cast(e, t) = &e.kind; - if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind; - if let ExprKind::Cast(e, t) = &e.kind; - if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind; - if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind(); - then { - span_lint( - cx, - CAST_REF_TO_MUT, - expr.span, - "casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`", - ); - } - } - } -} - -const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0); - -declare_clippy_lint! { - /// **What it does:** - /// Checks for `as` casts between raw pointers without changing its mutability, - /// namely `*const T` to `*const U` and `*mut T` to `*mut U`. - /// - /// **Why is this bad?** - /// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because - /// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// - /// ```rust - /// let ptr: *const u32 = &42_u32; - /// let mut_ptr: *mut u32 = &mut 42_u32; - /// let _ = ptr as *const i32; - /// let _ = mut_ptr as *mut i32; - /// ``` - /// Use instead: - /// ```rust - /// let ptr: *const u32 = &42_u32; - /// let mut_ptr: *mut u32 = &mut 42_u32; - /// let _ = ptr.cast::(); - /// let _ = mut_ptr.cast::(); - /// ``` - pub PTR_AS_PTR, - pedantic, - "casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`" -} - -pub struct PtrAsPtr { - msrv: Option, -} - -impl PtrAsPtr { - #[must_use] - pub fn new(msrv: Option) -> Self { - Self { msrv } - } -} - -impl_lint_pass!(PtrAsPtr => [PTR_AS_PTR]); - -impl<'tcx> LateLintPass<'tcx> for PtrAsPtr { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if !meets_msrv(self.msrv.as_ref(), &PTR_AS_PTR_MSRV) { - return; - } - - if expr.span.from_expansion() { - return; - } - - if_chain! { - if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind; - let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr)); - if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind(); - if let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind(); - if matches!((from_mutbl, to_mutbl), - (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut)); - // The `U` in `pointer::cast` have to be `Sized` - // as explained here: https://github.com/rust-lang/rust/issues/60602. - if to_pointee_ty.is_sized(cx.tcx.at(expr.span), cx.param_env); - then { - let mut applicability = Applicability::MachineApplicable; - let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability); - let turbofish = match &cast_to_hir_ty.kind { - TyKind::Infer => Cow::Borrowed(""), - TyKind::Ptr(mut_ty) if matches!(mut_ty.ty.kind, TyKind::Infer) => Cow::Borrowed(""), - _ => Cow::Owned(format!("::<{}>", to_pointee_ty)), - }; - span_lint_and_sugg( - cx, - PTR_AS_PTR, - expr.span, - "`as` casting between raw pointers without changing its mutability", - "try `pointer::cast`, a safer alternative", - format!("{}.cast{}()", cast_expr_sugg.maybe_par(), turbofish), - applicability, - ); - } - } - } - - extract_msrv_attr!(LateContext); +fn is_isize_or_usize(typ: Ty<'_>) -> bool { + matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) } From 360f0654047ef45212440e0cc9dcfe77c970b1eb Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 11:08:26 +0900 Subject: [PATCH 143/226] Move 'is_isize_or_usize' to clippy_utils --- clippy_lints/src/casts/mod.rs | 9 +++------ clippy_lints/src/types/mod.rs | 10 +++------- clippy_utils/src/lib.rs | 7 ++++++- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index d8245a3b88f74..95e563fc3bab5 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -15,8 +15,9 @@ use rustc_target::abi::LayoutOf; use crate::consts::{constant, Constant}; use crate::utils::sugg::Sugg; use crate::utils::{ - in_constant, is_hir_ty_cfg_dependant, meets_msrv, method_chain_args, numeric_literal::NumericLiteral, sext, - snippet_opt, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, + in_constant, is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, method_chain_args, + numeric_literal::NumericLiteral, sext, snippet_opt, snippet_with_applicability, span_lint, span_lint_and_sugg, + span_lint_and_then, }; declare_clippy_lint! { @@ -967,7 +968,3 @@ impl<'tcx> LateLintPass<'tcx> for PtrAsPtr { extract_msrv_attr!(LateContext); } - -fn is_isize_or_usize(typ: Ty<'_>) -> bool { - matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) -} diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 3e7aa53d5bc9e..7be4ea0379318 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -37,9 +37,9 @@ use rustc_typeck::hir_ty_to_ty; use crate::consts::{constant, Constant}; use crate::utils::paths; use crate::utils::{ - clip, comparisons, differing_macro_contexts, higher, indent_of, int_bits, is_type_diagnostic_item, match_path, - multispan_sugg, reindent_multiline, sext, snippet, snippet_opt, snippet_with_macro_callsite, span_lint, - span_lint_and_help, span_lint_and_then, unsext, + clip, comparisons, differing_macro_contexts, higher, indent_of, int_bits, is_isize_or_usize, + is_type_diagnostic_item, match_path, multispan_sugg, reindent_multiline, sext, snippet, snippet_opt, + snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_then, unsext, }; declare_clippy_lint! { @@ -1666,7 +1666,3 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't NestedVisitorMap::OnlyBodies(self.cx.tcx.hir()) } } - -fn is_isize_or_usize(typ: Ty<'_>) -> bool { - matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) -} diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 3845667802d80..74429982759b2 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -72,7 +72,7 @@ use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::exports::Export; use rustc_middle::hir::map::Map; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, layout::IntegerExt, DefIdTree, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, layout::IntegerExt, DefIdTree, IntTy, Ty, TyCtxt, TypeFoldable, UintTy}; use rustc_semver::RustcVersion; use rustc_session::Session; use rustc_span::hygiene::{self, ExpnKind, MacroKind}; @@ -262,6 +262,11 @@ pub fn is_ty_param_diagnostic_item( } } +/// Return `true` if the passed `typ` is `isize` or `usize`. +pub fn is_isize_or_usize(typ: Ty<'_>) -> bool { + matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) +} + /// Checks if the method call given in `expr` belongs to the given trait. pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool { let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); From c2cbcd32299270487388442e3dc684619279ae6b Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 11:22:17 +0900 Subject: [PATCH 144/226] Move cast_precision_loss to its own module --- clippy_lints/src/casts/cast_precision_loss.rs | 51 +++++++++++++++ clippy_lints/src/casts/mod.rs | 62 +++---------------- clippy_lints/src/casts/utils.rs | 25 ++++++++ 3 files changed, 83 insertions(+), 55 deletions(-) create mode 100644 clippy_lints/src/casts/cast_precision_loss.rs create mode 100644 clippy_lints/src/casts/utils.rs diff --git a/clippy_lints/src/casts/cast_precision_loss.rs b/clippy_lints/src/casts/cast_precision_loss.rs new file mode 100644 index 0000000000000..a1c3900ce1f6c --- /dev/null +++ b/clippy_lints/src/casts/cast_precision_loss.rs @@ -0,0 +1,51 @@ +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, FloatTy, Ty}; + +use crate::utils::{is_isize_or_usize, span_lint}; + +use super::{utils, CAST_PRECISION_LOSS}; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + if !cast_from.is_integral() || cast_to.is_integral() { + return; + } + + let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() { + 32 + } else { + 64 + }; + + if !(is_isize_or_usize(cast_from) || from_nbits >= to_nbits) { + return; + } + + let cast_to_f64 = to_nbits == 64; + let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; + let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; + let arch_dependent_str = "on targets with 64-bit wide pointers "; + let from_nbits_str = if arch_dependent { + "64".to_owned() + } else if is_isize_or_usize(cast_from) { + "32 or 64".to_owned() + } else { + utils::int_ty_to_nbits(cast_from, cx.tcx).to_string() + }; + + span_lint( + cx, + CAST_PRECISION_LOSS, + expr.span, + &format!( + "casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \ + but `{1}`'s mantissa is only {4} bits wide)", + cast_from, + if cast_to_f64 { "f64" } else { "f32" }, + if arch_dependent { arch_dependent_str } else { "" }, + from_nbits_str, + mantissa_nbits + ), + ); +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 95e563fc3bab5..7eb35aa829087 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -1,3 +1,6 @@ +mod cast_precision_loss; +mod utils; + use std::borrow::Cow; use if_chain::if_chain; @@ -6,7 +9,7 @@ use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, GenericArg, Lit, MutTy, Mutability, TyKind, UnOp}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TypeAndMut, UintTy}; +use rustc_middle::ty::{self, FloatTy, InferTy, Ty, TypeAndMut, UintTy}; use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::sym; @@ -20,6 +23,8 @@ use crate::utils::{ span_lint_and_then, }; +use utils::int_ty_to_nbits; + declare_clippy_lint! { /// **What it does:** Checks for casts from any numerical to a float type where /// the receiving type cannot store all values from the original type without @@ -249,57 +254,6 @@ declare_clippy_lint! { "casting a function pointer to a numeric type not wide enough to store the address" } -/// Returns the size in bits of an integral type. -/// Will return 0 if the type is not an int or uint variant -fn int_ty_to_nbits(typ: Ty<'_>, tcx: TyCtxt<'_>) -> u64 { - match typ.kind() { - ty::Int(i) => match i { - IntTy::Isize => tcx.data_layout.pointer_size.bits(), - IntTy::I8 => 8, - IntTy::I16 => 16, - IntTy::I32 => 32, - IntTy::I64 => 64, - IntTy::I128 => 128, - }, - ty::Uint(i) => match i { - UintTy::Usize => tcx.data_layout.pointer_size.bits(), - UintTy::U8 => 8, - UintTy::U16 => 16, - UintTy::U32 => 32, - UintTy::U64 => 64, - UintTy::U128 => 128, - }, - _ => 0, - } -} - -fn span_precision_loss_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to_f64: bool) { - let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; - let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; - let arch_dependent_str = "on targets with 64-bit wide pointers "; - let from_nbits_str = if arch_dependent { - "64".to_owned() - } else if is_isize_or_usize(cast_from) { - "32 or 64".to_owned() - } else { - int_ty_to_nbits(cast_from, cx.tcx).to_string() - }; - span_lint( - cx, - CAST_PRECISION_LOSS, - expr.span, - &format!( - "casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \ - but `{1}`'s mantissa is only {4} bits wide)", - cast_from, - if cast_to_f64 { "f64" } else { "f32" }, - if arch_dependent { arch_dependent_str } else { "" }, - from_nbits_str, - mantissa_nbits - ), - ); -} - fn should_strip_parens(op: &Expr<'_>, snip: &str) -> bool { if let ExprKind::Binary(_, _, _) = op.kind { if snip.starts_with('(') && snip.ends_with(')') { @@ -629,6 +583,7 @@ fn lint_numeric_casts<'tcx>( cast_from: Ty<'tcx>, cast_to: Ty<'tcx>, ) { + cast_precision_loss::check(cx, expr, cast_from, cast_to); match (cast_from.is_integral(), cast_to.is_integral()) { (true, false) => { let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); @@ -637,9 +592,6 @@ fn lint_numeric_casts<'tcx>( } else { 64 }; - if is_isize_or_usize(cast_from) || from_nbits >= to_nbits { - span_precision_loss_lint(cx, expr, cast_from, to_nbits == 64); - } if from_nbits < to_nbits { span_lossless_lint(cx, expr, cast_expr, cast_from, cast_to); } diff --git a/clippy_lints/src/casts/utils.rs b/clippy_lints/src/casts/utils.rs new file mode 100644 index 0000000000000..00fd0b3473b44 --- /dev/null +++ b/clippy_lints/src/casts/utils.rs @@ -0,0 +1,25 @@ +use rustc_middle::ty::{self, IntTy, Ty, TyCtxt, UintTy}; + +/// Returns the size in bits of an integral type. +/// Will return 0 if the type is not an int or uint variant +pub(super) fn int_ty_to_nbits(typ: Ty<'_>, tcx: TyCtxt<'_>) -> u64 { + match typ.kind() { + ty::Int(i) => match i { + IntTy::Isize => tcx.data_layout.pointer_size.bits(), + IntTy::I8 => 8, + IntTy::I16 => 16, + IntTy::I32 => 32, + IntTy::I64 => 64, + IntTy::I128 => 128, + }, + ty::Uint(i) => match i { + UintTy::Usize => tcx.data_layout.pointer_size.bits(), + UintTy::U8 => 8, + UintTy::U16 => 16, + UintTy::U32 => 32, + UintTy::U64 => 64, + UintTy::U128 => 128, + }, + _ => 0, + } +} From b12d7515b1ee867b0ef23b489f5b3166bed31ae3 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 11:44:52 +0900 Subject: [PATCH 145/226] Move cast_lossless to its own module --- clippy_lints/src/casts/cast_lossless.rs | 87 +++++++++++++++++++++++++ clippy_lints/src/casts/mod.rs | 79 ++-------------------- 2 files changed, 92 insertions(+), 74 deletions(-) create mode 100644 clippy_lints/src/casts/cast_lossless.rs diff --git a/clippy_lints/src/casts/cast_lossless.rs b/clippy_lints/src/casts/cast_lossless.rs new file mode 100644 index 0000000000000..478832a5164a0 --- /dev/null +++ b/clippy_lints/src/casts/cast_lossless.rs @@ -0,0 +1,87 @@ +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, FloatTy, Ty}; + +use crate::utils::{in_constant, is_isize_or_usize, snippet_opt, span_lint_and_sugg}; + +use super::{utils, CAST_LOSSLESS}; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + if !should_lint(cx, expr, cast_from, cast_to) { + return; + } + + // The suggestion is to use a function call, so if the original expression + // has parens on the outside, they are no longer needed. + let mut applicability = Applicability::MachineApplicable; + let opt = snippet_opt(cx, cast_op.span); + let sugg = opt.as_ref().map_or_else( + || { + applicability = Applicability::HasPlaceholders; + ".." + }, + |snip| { + if should_strip_parens(cast_op, snip) { + &snip[1..snip.len() - 1] + } else { + snip.as_str() + } + }, + ); + + span_lint_and_sugg( + cx, + CAST_LOSSLESS, + expr.span, + &format!( + "casting `{}` to `{}` may become silently lossy if you later change the type", + cast_from, cast_to + ), + "try", + format!("{}::from({})", cast_to, sugg), + applicability, + ); +} + +fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) -> bool { + // Do not suggest using From in consts/statics until it is valid to do so (see #2267). + if in_constant(cx, expr.hir_id) { + return false; + } + + match (cast_from.is_integral(), cast_to.is_integral()) { + (true, true) => { + let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed(); + let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); + !is_isize_or_usize(cast_from) + && !is_isize_or_usize(cast_to) + && from_nbits < to_nbits + && !cast_signed_to_unsigned + }, + + (true, false) => { + let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() { + 32 + } else { + 64 + }; + from_nbits < to_nbits + }, + + (_, _) => { + matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64)) + }, + } +} + +fn should_strip_parens(cast_expr: &Expr<'_>, snip: &str) -> bool { + if let ExprKind::Binary(_, _, _) = cast_expr.kind { + if snip.starts_with('(') && snip.ends_with(')') { + return true; + } + } + false +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 7eb35aa829087..6c2464e0090b7 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -1,3 +1,4 @@ +mod cast_lossless; mod cast_precision_loss; mod utils; @@ -18,9 +19,8 @@ use rustc_target::abi::LayoutOf; use crate::consts::{constant, Constant}; use crate::utils::sugg::Sugg; use crate::utils::{ - in_constant, is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, method_chain_args, - numeric_literal::NumericLiteral, sext, snippet_opt, snippet_with_applicability, span_lint, span_lint_and_sugg, - span_lint_and_then, + is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, method_chain_args, numeric_literal::NumericLiteral, sext, + snippet_opt, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, }; use utils::int_ty_to_nbits; @@ -254,52 +254,6 @@ declare_clippy_lint! { "casting a function pointer to a numeric type not wide enough to store the address" } -fn should_strip_parens(op: &Expr<'_>, snip: &str) -> bool { - if let ExprKind::Binary(_, _, _) = op.kind { - if snip.starts_with('(') && snip.ends_with(')') { - return true; - } - } - false -} - -fn span_lossless_lint(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - // Do not suggest using From in consts/statics until it is valid to do so (see #2267). - if in_constant(cx, expr.hir_id) { - return; - } - // The suggestion is to use a function call, so if the original expression - // has parens on the outside, they are no longer needed. - let mut applicability = Applicability::MachineApplicable; - let opt = snippet_opt(cx, op.span); - let sugg = opt.as_ref().map_or_else( - || { - applicability = Applicability::HasPlaceholders; - ".." - }, - |snip| { - if should_strip_parens(op, snip) { - &snip[1..snip.len() - 1] - } else { - snip.as_str() - } - }, - ); - - span_lint_and_sugg( - cx, - CAST_LOSSLESS, - expr.span, - &format!( - "casting `{}` to `{}` may become silently lossy if you later change the type", - cast_from, cast_to - ), - "try", - format!("{}::from({})", cast_to, sugg), - applicability, - ); -} - enum ArchSuffix { _32, _64, @@ -423,16 +377,6 @@ fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_fro } } -fn check_lossless(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed(); - let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); - let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); - if !is_isize_or_usize(cast_from) && !is_isize_or_usize(cast_to) && from_nbits < to_nbits && !cast_signed_to_unsigned - { - span_lossless_lint(cx, expr, op, cast_from, cast_to); - } -} - declare_lint_pass!(Casts => [ CAST_PRECISION_LOSS, CAST_SIGN_LOSS, @@ -584,18 +528,8 @@ fn lint_numeric_casts<'tcx>( cast_to: Ty<'tcx>, ) { cast_precision_loss::check(cx, expr, cast_from, cast_to); + cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to); match (cast_from.is_integral(), cast_to.is_integral()) { - (true, false) => { - let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); - let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() { - 32 - } else { - 64 - }; - if from_nbits < to_nbits { - span_lossless_lint(cx, expr, cast_expr, cast_from, cast_to); - } - }, (false, true) => { span_lint( cx, @@ -618,7 +552,6 @@ fn lint_numeric_casts<'tcx>( (true, true) => { check_loss_of_sign(cx, expr, cast_expr, cast_from, cast_to); check_truncation_and_wrapping(cx, expr, cast_from, cast_to); - check_lossless(cx, expr, cast_expr, cast_from, cast_to); }, (false, false) => { if let (&ty::Float(FloatTy::F64), &ty::Float(FloatTy::F32)) = (&cast_from.kind(), &cast_to.kind()) { @@ -629,10 +562,8 @@ fn lint_numeric_casts<'tcx>( "casting `f64` to `f32` may truncate the value", ); } - if let (&ty::Float(FloatTy::F32), &ty::Float(FloatTy::F64)) = (&cast_from.kind(), &cast_to.kind()) { - span_lossless_lint(cx, expr, cast_expr, cast_from, cast_to); - } }, + (_, _) => {}, } } From e322c773e3db22aadd60ce9a1803076fcbfeef2d Mon Sep 17 00:00:00 2001 From: Andrea Nall Date: Mon, 8 Mar 2021 23:03:45 -0600 Subject: [PATCH 146/226] use TyS::walk --- clippy_utils/src/lib.rs | 19 ++++++++----------- tests/ui/crashes/ice-6840.rs | 10 +++++++++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 999b39852cd50..ac29a09ae0eef 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1504,9 +1504,7 @@ fn is_normalizable_helper<'tcx>( cache.insert(ty, false); // prevent recursive loops let result = cx.tcx.infer_ctxt().enter(|infcx| { let cause = rustc_middle::traits::ObligationCause::dummy(); - if infcx.at(&cause, param_env).normalize(ty).is_err() { - false - } else { + if infcx.at(&cause, param_env).normalize(ty).is_ok() { match ty.kind() { ty::Adt(def, substs) => !def.variants.iter().any(|variant| { variant @@ -1514,16 +1512,15 @@ fn is_normalizable_helper<'tcx>( .iter() .any(|field| !is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache)) }), - ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { - is_normalizable_helper(cx, param_env, pointee, cache) - }, - ty::Array(inner_ty, _) | ty::Slice(inner_ty) => is_normalizable_helper(cx, param_env, inner_ty, cache), - ty::Tuple(tys) => !tys.iter().any(|inner| match inner.unpack() { - GenericArgKind::Type(inner_ty) => !is_normalizable_helper(cx, param_env, inner_ty, cache), - _ => false, + _ => !ty.walk().any(|generic_arg| !match generic_arg.unpack() { + GenericArgKind::Type(inner_ty) if inner_ty != ty => { + is_normalizable_helper(cx, param_env, inner_ty, cache) + }, + _ => true, // if inner_ty == ty, we've already checked it }), - _ => true, } + } else { + false } }); cache.insert(ty, result); diff --git a/tests/ui/crashes/ice-6840.rs b/tests/ui/crashes/ice-6840.rs index a749eefb6355a..d789f60c5d5a0 100644 --- a/tests/ui/crashes/ice-6840.rs +++ b/tests/ui/crashes/ice-6840.rs @@ -13,11 +13,19 @@ pub struct RuleEdges { type RuleDependencyEdges = HashMap>; -// and additional potential variants +// reproducer from the GitHub issue ends here +// but check some additional variants type RuleDependencyEdgesArray = HashMap; 8]>; type RuleDependencyEdgesSlice = HashMap]>; type RuleDependencyEdgesRef = HashMap>; type RuleDependencyEdgesRaw = HashMap>; type RuleDependencyEdgesTuple = HashMap, RuleEdges)>; +// and an additional checks to make sure fix doesn't have stack-overflow issue +// on self-containing types +pub struct SelfContaining { + inner: Box, +} +type SelfContainingEdges = HashMap; + fn main() {} From e812a8abdebd6e4d03aad84b4f7d671a0cb49fdf Mon Sep 17 00:00:00 2001 From: Andrea Nall Date: Mon, 8 Mar 2021 23:08:52 -0600 Subject: [PATCH 147/226] use `.all` instead of negative use of `.any` --- clippy_utils/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index ac29a09ae0eef..c0722f37f4947 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1506,13 +1506,13 @@ fn is_normalizable_helper<'tcx>( let cause = rustc_middle::traits::ObligationCause::dummy(); if infcx.at(&cause, param_env).normalize(ty).is_ok() { match ty.kind() { - ty::Adt(def, substs) => !def.variants.iter().any(|variant| { + ty::Adt(def, substs) => def.variants.iter().all(|variant| { variant .fields .iter() - .any(|field| !is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache)) + .all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache)) }), - _ => !ty.walk().any(|generic_arg| !match generic_arg.unpack() { + _ => ty.walk().all(|generic_arg| match generic_arg.unpack() { GenericArgKind::Type(inner_ty) if inner_ty != ty => { is_normalizable_helper(cx, param_env, inner_ty, cache) }, From 0534bf4698acc7b302664bb80d9c85be2648fcd8 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 12:10:59 +0900 Subject: [PATCH 148/226] Move cast_possible_truncation to its own module --- .../src/casts/cast_possible_truncation.rs | 54 +++++++++++++ clippy_lints/src/casts/mod.rs | 76 ++++--------------- 2 files changed, 68 insertions(+), 62 deletions(-) create mode 100644 clippy_lints/src/casts/cast_possible_truncation.rs diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs new file mode 100644 index 0000000000000..33b06b8fe7caf --- /dev/null +++ b/clippy_lints/src/casts/cast_possible_truncation.rs @@ -0,0 +1,54 @@ +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, FloatTy, Ty}; + +use crate::utils::{is_isize_or_usize, span_lint}; + +use super::{utils, CAST_POSSIBLE_TRUNCATION}; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + let msg = match (cast_from.is_integral(), cast_to.is_integral()) { + (true, true) => { + let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); + + let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { + (true, true) | (false, false) => (to_nbits < from_nbits, ""), + (true, false) => ( + to_nbits <= 32, + if to_nbits == 32 { + " on targets with 64-bit wide pointers" + } else { + "" + }, + ), + (false, true) => (from_nbits == 64, " on targets with 32-bit wide pointers"), + }; + + if !should_lint { + return; + } + + format!( + "casting `{}` to `{}` may truncate the value{}", + cast_from, cast_to, suffix, + ) + }, + + (false, true) => { + format!("casting `{}` to `{}` may truncate the value", cast_from, cast_to) + }, + + (_, _) => { + if matches!(cast_from.kind(), &ty::Float(FloatTy::F64)) + && matches!(cast_to.kind(), &ty::Float(FloatTy::F32)) + { + "casting `f64` to `f32` may truncate the value".to_string() + } else { + return; + } + }, + }; + + span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span, &msg); +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 6c2464e0090b7..9b89b076d9065 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -1,4 +1,5 @@ mod cast_lossless; +mod cast_possible_truncation; mod cast_precision_loss; mod utils; @@ -312,52 +313,18 @@ fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_fro let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); - let (span_truncation, suffix_truncation, span_wrap, suffix_wrap) = - match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { - (true, true) | (false, false) => ( - to_nbits < from_nbits, - ArchSuffix::None, - to_nbits == from_nbits && cast_unsigned_to_signed, - ArchSuffix::None, - ), - (true, false) => ( - to_nbits <= 32, - if to_nbits == 32 { - ArchSuffix::_64 - } else { - ArchSuffix::None - }, - to_nbits <= 32 && cast_unsigned_to_signed, - ArchSuffix::_32, - ), - (false, true) => ( - from_nbits == 64, - ArchSuffix::_32, - cast_unsigned_to_signed, - if from_nbits == 64 { - ArchSuffix::_64 - } else { - ArchSuffix::_32 - }, - ), - }; - if span_truncation { - span_lint( - cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - &format!( - "casting `{}` to `{}` may truncate the value{}", - cast_from, - cast_to, - match suffix_truncation { - ArchSuffix::_32 => arch_32_suffix, - ArchSuffix::_64 => arch_64_suffix, - ArchSuffix::None => "", - } - ), - ); - } + let (span_wrap, suffix_wrap) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { + (true, true) | (false, false) => (to_nbits == from_nbits && cast_unsigned_to_signed, ArchSuffix::None), + (true, false) => (to_nbits <= 32 && cast_unsigned_to_signed, ArchSuffix::_32), + (false, true) => ( + cast_unsigned_to_signed, + if from_nbits == 64 { + ArchSuffix::_64 + } else { + ArchSuffix::_32 + }, + ), + }; if span_wrap { span_lint( cx, @@ -529,14 +496,9 @@ fn lint_numeric_casts<'tcx>( ) { cast_precision_loss::check(cx, expr, cast_from, cast_to); cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to); + cast_possible_truncation::check(cx, expr, cast_from, cast_to); match (cast_from.is_integral(), cast_to.is_integral()) { (false, true) => { - span_lint( - cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - &format!("casting `{}` to `{}` may truncate the value", cast_from, cast_to), - ); if !cast_to.is_signed() { span_lint( cx, @@ -553,16 +515,6 @@ fn lint_numeric_casts<'tcx>( check_loss_of_sign(cx, expr, cast_expr, cast_from, cast_to); check_truncation_and_wrapping(cx, expr, cast_from, cast_to); }, - (false, false) => { - if let (&ty::Float(FloatTy::F64), &ty::Float(FloatTy::F32)) = (&cast_from.kind(), &cast_to.kind()) { - span_lint( - cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - "casting `f64` to `f32` may truncate the value", - ); - } - }, (_, _) => {}, } } From 0975031117fc1de35220f0e16d2294acaab154f8 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 12:37:46 +0900 Subject: [PATCH 149/226] Move cast_sign_loss to its own module --- clippy_lints/src/casts/cast_sign_loss.rs | 70 ++++++++++++++++++++++ clippy_lints/src/casts/mod.rs | 74 +++--------------------- 2 files changed, 78 insertions(+), 66 deletions(-) create mode 100644 clippy_lints/src/casts/cast_sign_loss.rs diff --git a/clippy_lints/src/casts/cast_sign_loss.rs b/clippy_lints/src/casts/cast_sign_loss.rs new file mode 100644 index 0000000000000..9656fbebd7720 --- /dev/null +++ b/clippy_lints/src/casts/cast_sign_loss.rs @@ -0,0 +1,70 @@ +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; + +use if_chain::if_chain; + +use crate::consts::{constant, Constant}; +use crate::utils::{method_chain_args, sext, span_lint}; + +use super::CAST_SIGN_LOSS; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + if should_lint(cx, cast_op, cast_from, cast_to) { + span_lint( + cx, + CAST_SIGN_LOSS, + expr.span, + &format!( + "casting `{}` to `{}` may lose the sign of the value", + cast_from, cast_to + ), + ); + } +} + +fn should_lint(cx: &LateContext<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) -> bool { + match (cast_from.is_integral(), cast_to.is_integral()) { + (true, true) => { + if !cast_from.is_signed() || cast_to.is_signed() { + return false; + } + + // Don't lint for positive constants. + let const_val = constant(cx, &cx.typeck_results(), cast_op); + if_chain! { + if let Some((Constant::Int(n), _)) = const_val; + if let ty::Int(ity) = *cast_from.kind(); + if sext(cx.tcx, n, ity) >= 0; + then { + return false; + } + } + + // Don't lint for the result of methods that always return non-negative values. + if let ExprKind::MethodCall(ref path, _, _, _) = cast_op.kind { + let mut method_name = path.ident.name.as_str(); + let allowed_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"]; + + if_chain! { + if method_name == "unwrap"; + if let Some(arglist) = method_chain_args(cast_op, &["unwrap"]); + if let ExprKind::MethodCall(ref inner_path, _, _, _) = &arglist[0][0].kind; + then { + method_name = inner_path.ident.name.as_str(); + } + } + + if allowed_methods.iter().any(|&name| method_name == name) { + return false; + } + } + + true + }, + + (false, true) => !cast_to.is_signed(), + + (_, _) => false, + } +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 9b89b076d9065..f390dfdfab761 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -1,6 +1,7 @@ mod cast_lossless; mod cast_possible_truncation; mod cast_precision_loss; +mod cast_sign_loss; mod utils; use std::borrow::Cow; @@ -17,11 +18,10 @@ use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::sym; use rustc_target::abi::LayoutOf; -use crate::consts::{constant, Constant}; use crate::utils::sugg::Sugg; use crate::utils::{ - is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, method_chain_args, numeric_literal::NumericLiteral, sext, - snippet_opt, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, + is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, numeric_literal::NumericLiteral, snippet_opt, + snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, }; use utils::int_ty_to_nbits; @@ -261,52 +261,6 @@ enum ArchSuffix { None, } -fn check_loss_of_sign(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - if !cast_from.is_signed() || cast_to.is_signed() { - return; - } - - // don't lint for positive constants - let const_val = constant(cx, &cx.typeck_results(), op); - if_chain! { - if let Some((Constant::Int(n), _)) = const_val; - if let ty::Int(ity) = *cast_from.kind(); - if sext(cx.tcx, n, ity) >= 0; - then { - return - } - } - - // don't lint for the result of methods that always return non-negative values - if let ExprKind::MethodCall(ref path, _, _, _) = op.kind { - let mut method_name = path.ident.name.as_str(); - let allowed_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"]; - - if_chain! { - if method_name == "unwrap"; - if let Some(arglist) = method_chain_args(op, &["unwrap"]); - if let ExprKind::MethodCall(ref inner_path, _, _, _) = &arglist[0][0].kind; - then { - method_name = inner_path.ident.name.as_str(); - } - } - - if allowed_methods.iter().any(|&name| method_name == name) { - return; - } - } - - span_lint( - cx, - CAST_SIGN_LOSS, - expr.span, - &format!( - "casting `{}` to `{}` may lose the sign of the value", - cast_from, cast_to - ), - ); -} - fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { let arch_64_suffix = " on targets with 64-bit wide pointers"; let arch_32_suffix = " on targets with 32-bit wide pointers"; @@ -490,29 +444,17 @@ fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &st fn lint_numeric_casts<'tcx>( cx: &LateContext<'tcx>, expr: &Expr<'tcx>, - cast_expr: &Expr<'_>, + cast_op: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>, ) { - cast_precision_loss::check(cx, expr, cast_from, cast_to); - cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to); cast_possible_truncation::check(cx, expr, cast_from, cast_to); + cast_precision_loss::check(cx, expr, cast_from, cast_to); + cast_lossless::check(cx, expr, cast_op, cast_from, cast_to); + cast_sign_loss::check(cx, expr, cast_op, cast_from, cast_to); + match (cast_from.is_integral(), cast_to.is_integral()) { - (false, true) => { - if !cast_to.is_signed() { - span_lint( - cx, - CAST_SIGN_LOSS, - expr.span, - &format!( - "casting `{}` to `{}` may lose the sign of the value", - cast_from, cast_to - ), - ); - } - }, (true, true) => { - check_loss_of_sign(cx, expr, cast_expr, cast_from, cast_to); check_truncation_and_wrapping(cx, expr, cast_from, cast_to); }, (_, _) => {}, From a383e034dc2f3d9cb53bd7164447fe7f3bfbf08c Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 16:11:46 +0900 Subject: [PATCH 150/226] Move cast_possible_wrap to its own module --- clippy_lints/src/casts/cast_possible_wrap.rs | 44 +++++++++++++++ clippy_lints/src/casts/mod.rs | 56 ++------------------ 2 files changed, 48 insertions(+), 52 deletions(-) create mode 100644 clippy_lints/src/casts/cast_possible_wrap.rs diff --git a/clippy_lints/src/casts/cast_possible_wrap.rs b/clippy_lints/src/casts/cast_possible_wrap.rs new file mode 100644 index 0000000000000..56d301ed3e1c5 --- /dev/null +++ b/clippy_lints/src/casts/cast_possible_wrap.rs @@ -0,0 +1,44 @@ +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::Ty; + +use crate::utils::{is_isize_or_usize, span_lint}; + +use super::{utils, CAST_POSSIBLE_WRAP}; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + if !(cast_from.is_integral() && cast_to.is_integral()) { + return; + } + + let arch_64_suffix = " on targets with 64-bit wide pointers"; + let arch_32_suffix = " on targets with 32-bit wide pointers"; + let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); + let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx); + let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); + + let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { + (true, true) | (false, false) => (to_nbits == from_nbits && cast_unsigned_to_signed, ""), + (true, false) => (to_nbits <= 32 && cast_unsigned_to_signed, arch_32_suffix), + (false, true) => ( + cast_unsigned_to_signed, + if from_nbits == 64 { + arch_64_suffix + } else { + arch_32_suffix + }, + ), + }; + + if should_lint { + span_lint( + cx, + CAST_POSSIBLE_WRAP, + expr.span, + &format!( + "casting `{}` to `{}` may wrap around the value{}", + cast_from, cast_to, suffix, + ), + ); + } +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index f390dfdfab761..01528a5a16a0c 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -1,5 +1,6 @@ mod cast_lossless; mod cast_possible_truncation; +mod cast_possible_wrap; mod cast_precision_loss; mod cast_sign_loss; mod utils; @@ -20,8 +21,8 @@ use rustc_target::abi::LayoutOf; use crate::utils::sugg::Sugg; use crate::utils::{ - is_hir_ty_cfg_dependant, is_isize_or_usize, meets_msrv, numeric_literal::NumericLiteral, snippet_opt, - snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, + is_hir_ty_cfg_dependant, meets_msrv, numeric_literal::NumericLiteral, snippet_opt, snippet_with_applicability, + span_lint, span_lint_and_sugg, span_lint_and_then, }; use utils::int_ty_to_nbits; @@ -255,49 +256,6 @@ declare_clippy_lint! { "casting a function pointer to a numeric type not wide enough to store the address" } -enum ArchSuffix { - _32, - _64, - None, -} - -fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { - let arch_64_suffix = " on targets with 64-bit wide pointers"; - let arch_32_suffix = " on targets with 32-bit wide pointers"; - let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); - let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); - let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); - let (span_wrap, suffix_wrap) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { - (true, true) | (false, false) => (to_nbits == from_nbits && cast_unsigned_to_signed, ArchSuffix::None), - (true, false) => (to_nbits <= 32 && cast_unsigned_to_signed, ArchSuffix::_32), - (false, true) => ( - cast_unsigned_to_signed, - if from_nbits == 64 { - ArchSuffix::_64 - } else { - ArchSuffix::_32 - }, - ), - }; - if span_wrap { - span_lint( - cx, - CAST_POSSIBLE_WRAP, - expr.span, - &format!( - "casting `{}` to `{}` may wrap around the value{}", - cast_from, - cast_to, - match suffix_wrap { - ArchSuffix::_32 => arch_32_suffix, - ArchSuffix::_64 => arch_64_suffix, - ArchSuffix::None => "", - } - ), - ); - } -} - declare_lint_pass!(Casts => [ CAST_PRECISION_LOSS, CAST_SIGN_LOSS, @@ -449,16 +407,10 @@ fn lint_numeric_casts<'tcx>( cast_to: Ty<'tcx>, ) { cast_possible_truncation::check(cx, expr, cast_from, cast_to); + cast_possible_wrap::check(cx, expr, cast_from, cast_to); cast_precision_loss::check(cx, expr, cast_from, cast_to); cast_lossless::check(cx, expr, cast_op, cast_from, cast_to); cast_sign_loss::check(cx, expr, cast_op, cast_from, cast_to); - - match (cast_from.is_integral(), cast_to.is_integral()) { - (true, true) => { - check_truncation_and_wrapping(cx, expr, cast_from, cast_to); - }, - (_, _) => {}, - } } fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { From 9709993e412dd3400aec27d4fefae0cbf1f702aa Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 16:43:10 +0900 Subject: [PATCH 151/226] Move unnecessary_cast to its own module --- clippy_lints/src/casts/mod.rs | 120 ++++----------------- clippy_lints/src/casts/unnecessary_cast.rs | 106 ++++++++++++++++++ 2 files changed, 128 insertions(+), 98 deletions(-) create mode 100644 clippy_lints/src/casts/unnecessary_cast.rs diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 01528a5a16a0c..d8c7443650141 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -3,17 +3,18 @@ mod cast_possible_truncation; mod cast_possible_wrap; mod cast_precision_loss; mod cast_sign_loss; +mod unnecessary_cast; mod utils; use std::borrow::Cow; use if_chain::if_chain; -use rustc_ast::{LitFloatType, LitIntType, LitKind}; +use rustc_ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, GenericArg, Lit, MutTy, Mutability, TyKind, UnOp}; +use rustc_hir::{Expr, ExprKind, GenericArg, MutTy, Mutability, TyKind, UnOp}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, FloatTy, InferTy, Ty, TypeAndMut, UintTy}; +use rustc_middle::ty::{self, Ty, TypeAndMut, UintTy}; use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::sym; @@ -21,8 +22,7 @@ use rustc_target::abi::LayoutOf; use crate::utils::sugg::Sugg; use crate::utils::{ - is_hir_ty_cfg_dependant, meets_msrv, numeric_literal::NumericLiteral, snippet_opt, snippet_with_applicability, - span_lint, span_lint_and_sugg, span_lint_and_then, + is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, }; use utils::int_ty_to_nbits; @@ -284,72 +284,25 @@ fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { false } -/// Returns the mantissa bits wide of a fp type. -/// Will return 0 if the type is not a fp -fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { - match typ.kind() { - ty::Float(FloatTy::F32) => 23, - ty::Float(FloatTy::F64) | ty::Infer(InferTy::FloatVar(_)) => 52, - _ => 0, - } -} - impl<'tcx> LateLintPass<'tcx> for Casts { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if expr.span.from_expansion() { return; } - if let ExprKind::Cast(ref ex, cast_to) = expr.kind { + if let ExprKind::Cast(ref cast_expr, cast_to) = expr.kind { if is_hir_ty_cfg_dependant(cx, cast_to) { return; } - let (cast_from, cast_to) = (cx.typeck_results().expr_ty(ex), cx.typeck_results().expr_ty(expr)); - lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to); - if let Some(lit) = get_numeric_literal(ex) { - let literal_str = snippet_opt(cx, ex.span).unwrap_or_default(); - - if_chain! { - if let LitKind::Int(n, _) = lit.node; - if let Some(src) = snippet_opt(cx, lit.span); - if cast_to.is_floating_point(); - if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node); - let from_nbits = 128 - n.leading_zeros(); - let to_nbits = fp_ty_mantissa_nbits(cast_to); - if from_nbits != 0 && to_nbits != 0 && from_nbits <= to_nbits && num_lit.is_decimal(); - then { - let literal_str = if is_unary_neg(ex) { format!("-{}", num_lit.integer) } else { num_lit.integer.into() }; - show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); - return; - } - } - - match lit.node { - LitKind::Int(_, LitIntType::Unsuffixed) if cast_to.is_integral() => { - show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); - }, - LitKind::Float(_, LitFloatType::Unsuffixed) if cast_to.is_floating_point() => { - show_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); - }, - LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) => {}, - _ => { - if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) { - span_lint( - cx, - UNNECESSARY_CAST, - expr.span, - &format!( - "casting to the same type is unnecessary (`{}` -> `{}`)", - cast_from, cast_to - ), - ); - } - }, - } - } - if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { - lint_numeric_casts(cx, expr, ex, cast_from, cast_to); - } + let (cast_from, cast_to) = ( + cx.typeck_results().expr_ty(cast_expr), + cx.typeck_results().expr_ty(expr), + ); + if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { + return; + } + lint_fn_to_numeric_cast(cx, expr, cast_expr, cast_from, cast_to); + lint_numeric_casts(cx, expr, cast_expr, cast_from, cast_to); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); } else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind { if_chain! { @@ -368,37 +321,6 @@ impl<'tcx> LateLintPass<'tcx> for Casts { } } -fn is_unary_neg(expr: &Expr<'_>) -> bool { - matches!(expr.kind, ExprKind::Unary(UnOp::Neg, _)) -} - -fn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<&'e Lit> { - match expr.kind { - ExprKind::Lit(ref lit) => Some(lit), - ExprKind::Unary(UnOp::Neg, e) => { - if let ExprKind::Lit(ref lit) = e.kind { - Some(lit) - } else { - None - } - }, - _ => None, - } -} - -fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) { - let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" }; - span_lint_and_sugg( - cx, - UNNECESSARY_CAST, - expr.span, - &format!("casting {} literal to `{}` is unnecessary", literal_kind_name, cast_to), - "try", - format!("{}_{}", literal_str.trim_end_matches('.'), cast_to), - Applicability::MachineApplicable, - ); -} - fn lint_numeric_casts<'tcx>( cx: &LateContext<'tcx>, expr: &Expr<'tcx>, @@ -406,11 +328,13 @@ fn lint_numeric_casts<'tcx>( cast_from: Ty<'tcx>, cast_to: Ty<'tcx>, ) { - cast_possible_truncation::check(cx, expr, cast_from, cast_to); - cast_possible_wrap::check(cx, expr, cast_from, cast_to); - cast_precision_loss::check(cx, expr, cast_from, cast_to); - cast_lossless::check(cx, expr, cast_op, cast_from, cast_to); - cast_sign_loss::check(cx, expr, cast_op, cast_from, cast_to); + if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { + cast_possible_truncation::check(cx, expr, cast_from, cast_to); + cast_possible_wrap::check(cx, expr, cast_from, cast_to); + cast_precision_loss::check(cx, expr, cast_from, cast_to); + cast_lossless::check(cx, expr, cast_op, cast_from, cast_to); + cast_sign_loss::check(cx, expr, cast_op, cast_from, cast_to); + } } fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs new file mode 100644 index 0000000000000..fa2a07ef1da0c --- /dev/null +++ b/clippy_lints/src/casts/unnecessary_cast.rs @@ -0,0 +1,106 @@ +use rustc_ast::{LitFloatType, LitIntType, LitKind}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, Lit, UnOp}; +use rustc_lint::{LateContext, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::{self, FloatTy, InferTy, Ty}; + +use if_chain::if_chain; + +use crate::utils::{numeric_literal::NumericLiteral, snippet_opt, span_lint, span_lint_and_sugg}; + +use super::UNNECESSARY_CAST; + +pub(super) fn check( + cx: &LateContext<'_>, + expr: &Expr<'_>, + cast_expr: &Expr<'_>, + cast_from: Ty<'_>, + cast_to: Ty<'_>, +) -> bool { + if let Some(lit) = get_numeric_literal(cast_expr) { + let literal_str = snippet_opt(cx, cast_expr.span).unwrap_or_default(); + + if_chain! { + if let LitKind::Int(n, _) = lit.node; + if let Some(src) = snippet_opt(cx, lit.span); + if cast_to.is_floating_point(); + if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node); + let from_nbits = 128 - n.leading_zeros(); + let to_nbits = fp_ty_mantissa_nbits(cast_to); + if from_nbits != 0 && to_nbits != 0 && from_nbits <= to_nbits && num_lit.is_decimal(); + then { + let literal_str = if is_unary_neg(cast_expr) { format!("-{}", num_lit.integer) } else { num_lit.integer.into() }; + lint_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); + return true + } + } + + match lit.node { + LitKind::Int(_, LitIntType::Unsuffixed) if cast_to.is_integral() => { + lint_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); + }, + LitKind::Float(_, LitFloatType::Unsuffixed) if cast_to.is_floating_point() => { + lint_unnecessary_cast(cx, expr, &literal_str, cast_from, cast_to); + }, + LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) => {}, + _ => { + if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) { + span_lint( + cx, + UNNECESSARY_CAST, + expr.span, + &format!( + "casting to the same type is unnecessary (`{}` -> `{}`)", + cast_from, cast_to + ), + ); + return true; + } + }, + } + } + + false +} + +fn lint_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) { + let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" }; + span_lint_and_sugg( + cx, + UNNECESSARY_CAST, + expr.span, + &format!("casting {} literal to `{}` is unnecessary", literal_kind_name, cast_to), + "try", + format!("{}_{}", literal_str.trim_end_matches('.'), cast_to), + Applicability::MachineApplicable, + ); +} + +fn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<&'e Lit> { + match expr.kind { + ExprKind::Lit(ref lit) => Some(lit), + ExprKind::Unary(UnOp::Neg, e) => { + if let ExprKind::Lit(ref lit) = e.kind { + Some(lit) + } else { + None + } + }, + _ => None, + } +} + +/// Returns the mantissa bits wide of a fp type. +/// Will return 0 if the type is not a fp +fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { + match typ.kind() { + ty::Float(FloatTy::F32) => 23, + ty::Float(FloatTy::F64) | ty::Infer(InferTy::FloatVar(_)) => 52, + _ => 0, + } +} + +fn is_unary_neg(expr: &Expr<'_>) -> bool { + matches!(expr.kind, ExprKind::Unary(UnOp::Neg, _)) +} From 0dce9921fd6a1e55430c56e5ccf0faf0f1e23491 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 16:47:46 +0900 Subject: [PATCH 152/226] Remove 'lint_numeric_casts' --- clippy_lints/src/casts/mod.rs | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index d8c7443650141..c7e9066f3eaaf 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -302,8 +302,14 @@ impl<'tcx> LateLintPass<'tcx> for Casts { return; } lint_fn_to_numeric_cast(cx, expr, cast_expr, cast_from, cast_to); - lint_numeric_casts(cx, expr, cast_expr, cast_from, cast_to); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); + if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { + cast_possible_truncation::check(cx, expr, cast_from, cast_to); + cast_possible_wrap::check(cx, expr, cast_from, cast_to); + cast_precision_loss::check(cx, expr, cast_from, cast_to); + cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to); + cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to); + } } else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind { if_chain! { if method_path.ident.name == sym!(cast); @@ -321,22 +327,6 @@ impl<'tcx> LateLintPass<'tcx> for Casts { } } -fn lint_numeric_casts<'tcx>( - cx: &LateContext<'tcx>, - expr: &Expr<'tcx>, - cast_op: &Expr<'_>, - cast_from: Ty<'tcx>, - cast_to: Ty<'tcx>, -) { - if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { - cast_possible_truncation::check(cx, expr, cast_from, cast_to); - cast_possible_wrap::check(cx, expr, cast_from, cast_to); - cast_precision_loss::check(cx, expr, cast_from, cast_to); - cast_lossless::check(cx, expr, cast_op, cast_from, cast_to); - cast_sign_loss::check(cx, expr, cast_op, cast_from, cast_to); - } -} - fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { if_chain! { if let ty::RawPtr(from_ptr_ty) = &cast_from.kind(); From 458f6d19d0c51ee97b7ac90ce60994f627983824 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 17:03:07 +0900 Subject: [PATCH 153/226] Move fn_to_numeric_cast to its own module --- clippy_lints/src/casts/fn_to_numeric_cast.rs | 37 ++++++++++++++++++++ clippy_lints/src/casts/mod.rs | 13 ++----- 2 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 clippy_lints/src/casts/fn_to_numeric_cast.rs diff --git a/clippy_lints/src/casts/fn_to_numeric_cast.rs b/clippy_lints/src/casts/fn_to_numeric_cast.rs new file mode 100644 index 0000000000000..a8d508585b5d4 --- /dev/null +++ b/clippy_lints/src/casts/fn_to_numeric_cast.rs @@ -0,0 +1,37 @@ +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty, UintTy}; + +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; + +use super::{utils, FN_TO_NUMERIC_CAST}; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + // We only want to check casts to `ty::Uint` or `ty::Int` + match cast_to.kind() { + ty::Uint(_) | ty::Int(..) => { /* continue on */ }, + _ => return, + } + + match cast_from.kind() { + ty::FnDef(..) | ty::FnPtr(_) => { + let mut applicability = Applicability::MaybeIncorrect; + let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability); + let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); + + if (to_nbits >= cx.tcx.data_layout.pointer_size.bits()) && (*cast_to.kind() != ty::Uint(UintTy::Usize)) { + span_lint_and_sugg( + cx, + FN_TO_NUMERIC_CAST, + expr.span, + &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), + "try", + format!("{} as usize", from_snippet), + applicability, + ); + } + }, + _ => {}, + } +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index c7e9066f3eaaf..bbe492be72ec7 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -3,6 +3,7 @@ mod cast_possible_truncation; mod cast_possible_wrap; mod cast_precision_loss; mod cast_sign_loss; +mod fn_to_numeric_cast; mod unnecessary_cast; mod utils; @@ -301,6 +302,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts { if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { return; } + + fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to); lint_fn_to_numeric_cast(cx, expr, cast_expr, cast_from, cast_to); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { @@ -386,16 +389,6 @@ fn lint_fn_to_numeric_cast( format!("{} as usize", from_snippet), applicability, ); - } else if *cast_to.kind() != ty::Uint(UintTy::Usize) { - span_lint_and_sugg( - cx, - FN_TO_NUMERIC_CAST, - expr.span, - &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), - "try", - format!("{} as usize", from_snippet), - applicability, - ); } }, _ => {}, From 9a24877e2cd68f22edd3de4a44f59c9899953f91 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 17:06:25 +0900 Subject: [PATCH 154/226] Move fn_to_numeric_cast_with_truncation to its own module --- .../fn_to_numeric_cast_with_truncation.rs | 39 ++++++++++++++++++ clippy_lints/src/casts/mod.rs | 40 +------------------ 2 files changed, 41 insertions(+), 38 deletions(-) create mode 100644 clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs diff --git a/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs b/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs new file mode 100644 index 0000000000000..0085c7b27b290 --- /dev/null +++ b/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs @@ -0,0 +1,39 @@ +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; + +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; + +use super::{utils, FN_TO_NUMERIC_CAST_WITH_TRUNCATION}; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + // We only want to check casts to `ty::Uint` or `ty::Int` + match cast_to.kind() { + ty::Uint(_) | ty::Int(..) => { /* continue on */ }, + _ => return, + } + match cast_from.kind() { + ty::FnDef(..) | ty::FnPtr(_) => { + let mut applicability = Applicability::MaybeIncorrect; + let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability); + + let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); + if to_nbits < cx.tcx.data_layout.pointer_size.bits() { + span_lint_and_sugg( + cx, + FN_TO_NUMERIC_CAST_WITH_TRUNCATION, + expr.span, + &format!( + "casting function pointer `{}` to `{}`, which truncates the value", + from_snippet, cast_to + ), + "try", + format!("{} as usize", from_snippet), + applicability, + ); + } + }, + _ => {}, + } +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index bbe492be72ec7..a80de01cfaf36 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -4,6 +4,7 @@ mod cast_possible_wrap; mod cast_precision_loss; mod cast_sign_loss; mod fn_to_numeric_cast; +mod fn_to_numeric_cast_with_truncation; mod unnecessary_cast; mod utils; @@ -304,7 +305,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts { } fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to); - lint_fn_to_numeric_cast(cx, expr, cast_expr, cast_from, cast_to); + fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { cast_possible_truncation::check(cx, expr, cast_from, cast_to); @@ -358,43 +359,6 @@ fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_f } } -fn lint_fn_to_numeric_cast( - cx: &LateContext<'_>, - expr: &Expr<'_>, - cast_expr: &Expr<'_>, - cast_from: Ty<'_>, - cast_to: Ty<'_>, -) { - // We only want to check casts to `ty::Uint` or `ty::Int` - match cast_to.kind() { - ty::Uint(_) | ty::Int(..) => { /* continue on */ }, - _ => return, - } - match cast_from.kind() { - ty::FnDef(..) | ty::FnPtr(_) => { - let mut applicability = Applicability::MaybeIncorrect; - let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability); - - let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); - if to_nbits < cx.tcx.data_layout.pointer_size.bits() { - span_lint_and_sugg( - cx, - FN_TO_NUMERIC_CAST_WITH_TRUNCATION, - expr.span, - &format!( - "casting function pointer `{}` to `{}`, which truncates the value", - from_snippet, cast_to - ), - "try", - format!("{} as usize", from_snippet), - applicability, - ); - } - }, - _ => {}, - } -} - declare_clippy_lint! { /// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. /// From ebd1ec0e40739d8b968c2b9bfd249485cec866ab Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 17:15:18 +0900 Subject: [PATCH 155/226] Move cast_ptr_alignment to its own module --- clippy_lints/src/casts/cast_ptr_alignment.rs | 81 ++++++++++++++++++++ clippy_lints/src/casts/mod.rs | 67 +--------------- 2 files changed, 85 insertions(+), 63 deletions(-) create mode 100644 clippy_lints/src/casts/cast_ptr_alignment.rs diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs new file mode 100644 index 0000000000000..87fb5557be066 --- /dev/null +++ b/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -0,0 +1,81 @@ +use rustc_hir::{Expr, ExprKind, GenericArg}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; +use rustc_span::symbol::sym; +use rustc_target::abi::LayoutOf; + +use if_chain::if_chain; + +use crate::utils::{is_hir_ty_cfg_dependant, span_lint}; + +use super::CAST_PTR_ALIGNMENT; + +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Cast(ref cast_expr, cast_to) = expr.kind { + if is_hir_ty_cfg_dependant(cx, cast_to) { + return; + } + let (cast_from, cast_to) = ( + cx.typeck_results().expr_ty(cast_expr), + cx.typeck_results().expr_ty(expr), + ); + lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); + } else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind { + if_chain! { + if method_path.ident.name == sym!(cast); + if let Some(generic_args) = method_path.args; + if let [GenericArg::Type(cast_to)] = generic_args.args; + // There probably is no obvious reason to do this, just to be consistent with `as` cases. + if !is_hir_ty_cfg_dependant(cx, cast_to); + then { + let (cast_from, cast_to) = + (cx.typeck_results().expr_ty(&args[0]), cx.typeck_results().expr_ty(expr)); + lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); + } + } + } +} + +fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { + if_chain! { + if let ty::RawPtr(from_ptr_ty) = &cast_from.kind(); + if let ty::RawPtr(to_ptr_ty) = &cast_to.kind(); + if let Ok(from_layout) = cx.layout_of(from_ptr_ty.ty); + if let Ok(to_layout) = cx.layout_of(to_ptr_ty.ty); + if from_layout.align.abi < to_layout.align.abi; + // with c_void, we inherently need to trust the user + if !is_c_void(cx, from_ptr_ty.ty); + // when casting from a ZST, we don't know enough to properly lint + if !from_layout.is_zst(); + then { + span_lint( + cx, + CAST_PTR_ALIGNMENT, + expr.span, + &format!( + "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)", + cast_from, + cast_to, + from_layout.align.abi.bytes(), + to_layout.align.abi.bytes(), + ), + ); + } + } +} + +/// Check if the given type is either `core::ffi::c_void` or +/// one of the platform specific `libc::::c_void` of libc. +fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { + if let ty::Adt(adt, _) = ty.kind() { + let names = cx.get_def_path(adt.did); + + if names.is_empty() { + return false; + } + if names[0] == sym::libc || names[0] == sym::core && *names.last().unwrap() == sym!(c_void) { + return true; + } + } + false +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index a80de01cfaf36..cf8a64e1fd847 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -2,6 +2,7 @@ mod cast_lossless; mod cast_possible_truncation; mod cast_possible_wrap; mod cast_precision_loss; +mod cast_ptr_alignment; mod cast_sign_loss; mod fn_to_numeric_cast; mod fn_to_numeric_cast_with_truncation; @@ -13,22 +14,18 @@ use std::borrow::Cow; use if_chain::if_chain; use rustc_ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, GenericArg, MutTy, Mutability, TyKind, UnOp}; +use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, Ty, TypeAndMut, UintTy}; +use rustc_middle::ty::{self, TypeAndMut, UintTy}; use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; -use rustc_span::symbol::sym; -use rustc_target::abi::LayoutOf; use crate::utils::sugg::Sugg; use crate::utils::{ is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, }; -use utils::int_ty_to_nbits; - declare_clippy_lint! { /// **What it does:** Checks for casts from any numerical to a float type where /// the receiving type cannot store all values from the original type without @@ -270,22 +267,6 @@ declare_lint_pass!(Casts => [ FN_TO_NUMERIC_CAST_WITH_TRUNCATION, ]); -/// Check if the given type is either `core::ffi::c_void` or -/// one of the platform specific `libc::::c_void` of libc. -fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - if let ty::Adt(adt, _) = ty.kind() { - let names = cx.get_def_path(adt.did); - - if names.is_empty() { - return false; - } - if names[0] == sym::libc || names[0] == sym::core && *names.last().unwrap() == sym!(c_void) { - return true; - } - } - false -} - impl<'tcx> LateLintPass<'tcx> for Casts { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if expr.span.from_expansion() { @@ -306,7 +287,6 @@ impl<'tcx> LateLintPass<'tcx> for Casts { fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to); fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to); - lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { cast_possible_truncation::check(cx, expr, cast_from, cast_to); cast_possible_wrap::check(cx, expr, cast_from, cast_to); @@ -314,48 +294,9 @@ impl<'tcx> LateLintPass<'tcx> for Casts { cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to); cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to); } - } else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind { - if_chain! { - if method_path.ident.name == sym!(cast); - if let Some(generic_args) = method_path.args; - if let [GenericArg::Type(cast_to)] = generic_args.args; - // There probably is no obvious reason to do this, just to be consistent with `as` cases. - if !is_hir_ty_cfg_dependant(cx, cast_to); - then { - let (cast_from, cast_to) = - (cx.typeck_results().expr_ty(&args[0]), cx.typeck_results().expr_ty(expr)); - lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); - } - } } - } -} -fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { - if_chain! { - if let ty::RawPtr(from_ptr_ty) = &cast_from.kind(); - if let ty::RawPtr(to_ptr_ty) = &cast_to.kind(); - if let Ok(from_layout) = cx.layout_of(from_ptr_ty.ty); - if let Ok(to_layout) = cx.layout_of(to_ptr_ty.ty); - if from_layout.align.abi < to_layout.align.abi; - // with c_void, we inherently need to trust the user - if !is_c_void(cx, from_ptr_ty.ty); - // when casting from a ZST, we don't know enough to properly lint - if !from_layout.is_zst(); - then { - span_lint( - cx, - CAST_PTR_ALIGNMENT, - expr.span, - &format!( - "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)", - cast_from, - cast_to, - from_layout.align.abi.bytes(), - to_layout.align.abi.bytes(), - ), - ); - } + cast_ptr_alignment::check(cx, expr); } } From f33bb3d900f93b13f4a9060e0060df36ff3a7e3d Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 17:22:21 +0900 Subject: [PATCH 156/226] Move cast_ref_to_mut to its own module --- clippy_lints/src/casts/cast_ref_to_mut.rs | 28 +++++++ clippy_lints/src/casts/mod.rs | 99 +++++++++-------------- clippy_lints/src/lib.rs | 1 - 3 files changed, 68 insertions(+), 60 deletions(-) create mode 100644 clippy_lints/src/casts/cast_ref_to_mut.rs diff --git a/clippy_lints/src/casts/cast_ref_to_mut.rs b/clippy_lints/src/casts/cast_ref_to_mut.rs new file mode 100644 index 0000000000000..3fdc1c6168ba9 --- /dev/null +++ b/clippy_lints/src/casts/cast_ref_to_mut.rs @@ -0,0 +1,28 @@ +use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp}; +use rustc_lint::LateContext; +use rustc_middle::ty; + +use if_chain::if_chain; + +use crate::utils::span_lint; + +use super::CAST_REF_TO_MUT; + +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if_chain! { + if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind; + if let ExprKind::Cast(e, t) = &e.kind; + if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind; + if let ExprKind::Cast(e, t) = &e.kind; + if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind; + if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind(); + then { + span_lint( + cx, + CAST_REF_TO_MUT, + expr.span, + "casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`", + ); + } + } +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index cf8a64e1fd847..7d5ada18be3bb 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -3,6 +3,7 @@ mod cast_possible_truncation; mod cast_possible_wrap; mod cast_precision_loss; mod cast_ptr_alignment; +mod cast_ref_to_mut; mod cast_sign_loss; mod fn_to_numeric_cast; mod fn_to_numeric_cast_with_truncation; @@ -14,7 +15,7 @@ use std::borrow::Cow; use if_chain::if_chain; use rustc_ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp}; +use rustc_hir::{Expr, ExprKind, Mutability, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, TypeAndMut, UintTy}; @@ -23,7 +24,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use crate::utils::sugg::Sugg; use crate::utils::{ - is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then, + is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then, }; declare_clippy_lint! { @@ -255,12 +256,47 @@ declare_clippy_lint! { "casting a function pointer to a numeric type not wide enough to store the address" } +declare_clippy_lint! { + /// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. + /// + /// **Why is this bad?** It’s basically guaranteed to be undefined behaviour. + /// `UnsafeCell` is the only way to obtain aliasable data that is considered + /// mutable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// fn x(r: &i32) { + /// unsafe { + /// *(r as *const _ as *mut _) += 1; + /// } + /// } + /// ``` + /// + /// Instead consider using interior mutability types. + /// + /// ```rust + /// use std::cell::UnsafeCell; + /// + /// fn x(r: &UnsafeCell) { + /// unsafe { + /// *r.get() += 1; + /// } + /// } + /// ``` + pub CAST_REF_TO_MUT, + correctness, + "a cast of reference to a mutable pointer" +} + declare_lint_pass!(Casts => [ CAST_PRECISION_LOSS, CAST_SIGN_LOSS, CAST_POSSIBLE_TRUNCATION, CAST_POSSIBLE_WRAP, CAST_LOSSLESS, + CAST_REF_TO_MUT, UNNECESSARY_CAST, CAST_PTR_ALIGNMENT, FN_TO_NUMERIC_CAST, @@ -269,6 +305,8 @@ declare_lint_pass!(Casts => [ impl<'tcx> LateLintPass<'tcx> for Casts { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + cast_ref_to_mut::check(cx, expr); + if expr.span.from_expansion() { return; } @@ -300,63 +338,6 @@ impl<'tcx> LateLintPass<'tcx> for Casts { } } -declare_clippy_lint! { - /// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. - /// - /// **Why is this bad?** It’s basically guaranteed to be undefined behaviour. - /// `UnsafeCell` is the only way to obtain aliasable data that is considered - /// mutable. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust,ignore - /// fn x(r: &i32) { - /// unsafe { - /// *(r as *const _ as *mut _) += 1; - /// } - /// } - /// ``` - /// - /// Instead consider using interior mutability types. - /// - /// ```rust - /// use std::cell::UnsafeCell; - /// - /// fn x(r: &UnsafeCell) { - /// unsafe { - /// *r.get() += 1; - /// } - /// } - /// ``` - pub CAST_REF_TO_MUT, - correctness, - "a cast of reference to a mutable pointer" -} - -declare_lint_pass!(RefToMut => [CAST_REF_TO_MUT]); - -impl<'tcx> LateLintPass<'tcx> for RefToMut { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if_chain! { - if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind; - if let ExprKind::Cast(e, t) = &e.kind; - if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind; - if let ExprKind::Cast(e, t) = &e.kind; - if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind; - if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind(); - then { - span_lint( - cx, - CAST_REF_TO_MUT, - expr.span, - "casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`", - ); - } - } - } -} - const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0); declare_clippy_lint! { diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index a46c56a01d5d5..47afd7beb7411 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1176,7 +1176,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box slow_vector_initialization::SlowVectorInit); store.register_late_pass(|| box unnecessary_sort_by::UnnecessarySortBy); store.register_late_pass(|| box unnecessary_wraps::UnnecessaryWraps); - store.register_late_pass(|| box casts::RefToMut); store.register_late_pass(|| box assertions_on_constants::AssertionsOnConstants); store.register_late_pass(|| box transmuting_null::TransmutingNull); store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite); From 43c88c60c152f55fb1ada9438ed2378c358b329a Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 17:28:56 +0900 Subject: [PATCH 157/226] Move char_lit_as_u8 to its own module --- clippy_lints/src/casts/char_lit_as_u8.rs | 42 ++++++++++ clippy_lints/src/casts/mod.rs | 102 ++++++++--------------- clippy_lints/src/lib.rs | 1 - 3 files changed, 75 insertions(+), 70 deletions(-) create mode 100644 clippy_lints/src/casts/char_lit_as_u8.rs diff --git a/clippy_lints/src/casts/char_lit_as_u8.rs b/clippy_lints/src/casts/char_lit_as_u8.rs new file mode 100644 index 0000000000000..ccaad1b8f2ac7 --- /dev/null +++ b/clippy_lints/src/casts/char_lit_as_u8.rs @@ -0,0 +1,42 @@ +use rustc_ast::LitKind; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, UintTy}; + +use if_chain::if_chain; + +use crate::utils::{snippet_with_applicability, span_lint_and_then}; + +use super::CHAR_LIT_AS_U8; + +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if_chain! { + if let ExprKind::Cast(e, _) = &expr.kind; + if let ExprKind::Lit(l) = &e.kind; + if let LitKind::Char(c) = l.node; + if ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(expr).kind(); + then { + let mut applicability = Applicability::MachineApplicable; + let snippet = snippet_with_applicability(cx, e.span, "'x'", &mut applicability); + + span_lint_and_then( + cx, + CHAR_LIT_AS_U8, + expr.span, + "casting a character literal to `u8` truncates", + |diag| { + diag.note("`char` is four bytes wide, but `u8` is a single byte"); + + if c.is_ascii() { + diag.span_suggestion( + expr.span, + "use a byte literal instead", + format!("b{}", snippet), + applicability, + ); + } + }); + } + } +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 7d5ada18be3bb..6d49af21a5f08 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -5,6 +5,7 @@ mod cast_precision_loss; mod cast_ptr_alignment; mod cast_ref_to_mut; mod cast_sign_loss; +mod char_lit_as_u8; mod fn_to_numeric_cast; mod fn_to_numeric_cast_with_truncation; mod unnecessary_cast; @@ -13,19 +14,16 @@ mod utils; use std::borrow::Cow; use if_chain::if_chain; -use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, Mutability, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, TypeAndMut, UintTy}; +use rustc_middle::ty::{self, TypeAndMut}; use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use crate::utils::sugg::Sugg; -use crate::utils::{ - is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then, -}; +use crate::utils::{is_hir_ty_cfg_dependant, meets_msrv, span_lint_and_sugg}; declare_clippy_lint! { /// **What it does:** Checks for casts from any numerical to a float type where @@ -290,6 +288,33 @@ declare_clippy_lint! { "a cast of reference to a mutable pointer" } +declare_clippy_lint! { + /// **What it does:** Checks for expressions where a character literal is cast + /// to `u8` and suggests using a byte literal instead. + /// + /// **Why is this bad?** In general, casting values to smaller types is + /// error-prone and should be avoided where possible. In the particular case of + /// converting a character literal to u8, it is easy to avoid by just using a + /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter + /// than `'a' as u8`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// 'x' as u8 + /// ``` + /// + /// A better version, using the byte literal: + /// + /// ```rust,ignore + /// b'x' + /// ``` + pub CHAR_LIT_AS_U8, + complexity, + "casting a character literal to `u8` truncates" +} + declare_lint_pass!(Casts => [ CAST_PRECISION_LOSS, CAST_SIGN_LOSS, @@ -297,10 +322,11 @@ declare_lint_pass!(Casts => [ CAST_POSSIBLE_WRAP, CAST_LOSSLESS, CAST_REF_TO_MUT, - UNNECESSARY_CAST, CAST_PTR_ALIGNMENT, + UNNECESSARY_CAST, FN_TO_NUMERIC_CAST, FN_TO_NUMERIC_CAST_WITH_TRUNCATION, + CHAR_LIT_AS_U8, ]); impl<'tcx> LateLintPass<'tcx> for Casts { @@ -335,74 +361,12 @@ impl<'tcx> LateLintPass<'tcx> for Casts { } cast_ptr_alignment::check(cx, expr); + char_lit_as_u8::check(cx, expr); } } const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0); -declare_clippy_lint! { - /// **What it does:** Checks for expressions where a character literal is cast - /// to `u8` and suggests using a byte literal instead. - /// - /// **Why is this bad?** In general, casting values to smaller types is - /// error-prone and should be avoided where possible. In the particular case of - /// converting a character literal to u8, it is easy to avoid by just using a - /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter - /// than `'a' as u8`. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust,ignore - /// 'x' as u8 - /// ``` - /// - /// A better version, using the byte literal: - /// - /// ```rust,ignore - /// b'x' - /// ``` - pub CHAR_LIT_AS_U8, - complexity, - "casting a character literal to `u8` truncates" -} - -declare_lint_pass!(CharLitAsU8 => [CHAR_LIT_AS_U8]); - -impl<'tcx> LateLintPass<'tcx> for CharLitAsU8 { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if_chain! { - if !expr.span.from_expansion(); - if let ExprKind::Cast(e, _) = &expr.kind; - if let ExprKind::Lit(l) = &e.kind; - if let LitKind::Char(c) = l.node; - if ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(expr).kind(); - then { - let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, e.span, "'x'", &mut applicability); - - span_lint_and_then( - cx, - CHAR_LIT_AS_U8, - expr.span, - "casting a character literal to `u8` truncates", - |diag| { - diag.note("`char` is four bytes wide, but `u8` is a single byte"); - - if c.is_ascii() { - diag.span_suggestion( - expr.span, - "use a byte literal instead", - format!("b{}", snippet), - applicability, - ); - } - }); - } - } - } -} - declare_clippy_lint! { /// **What it does:** /// Checks for `as` casts between raw pointers without changing its mutability, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 47afd7beb7411..67c481145c342 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1108,7 +1108,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box panic_unimplemented::PanicUnimplemented); store.register_late_pass(|| box strings::StringLitAsBytes); store.register_late_pass(|| box derive::Derive); - store.register_late_pass(|| box casts::CharLitAsU8); store.register_late_pass(|| box get_last_with_len::GetLastWithLen); store.register_late_pass(|| box drop_forget_ref::DropForgetRef); store.register_late_pass(|| box empty_enum::EmptyEnum); From 9e631da454e3ab6f756228b438b61126a0e51518 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 20:04:19 +0900 Subject: [PATCH 158/226] Move ptr_as_ptr to its own module --- clippy_lints/src/casts/mod.rs | 143 +++++++++------------------ clippy_lints/src/casts/ptr_as_ptr.rs | 52 ++++++++++ clippy_lints/src/lib.rs | 3 +- 3 files changed, 100 insertions(+), 98 deletions(-) create mode 100644 clippy_lints/src/casts/ptr_as_ptr.rs diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 6d49af21a5f08..b726bd75f1d83 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -8,22 +8,17 @@ mod cast_sign_loss; mod char_lit_as_u8; mod fn_to_numeric_cast; mod fn_to_numeric_cast_with_truncation; +mod ptr_as_ptr; mod unnecessary_cast; mod utils; -use std::borrow::Cow; - -use if_chain::if_chain; -use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, Mutability, TyKind}; +use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, TypeAndMut}; use rustc_semver::RustcVersion; -use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; -use crate::utils::sugg::Sugg; -use crate::utils::{is_hir_ty_cfg_dependant, meets_msrv, span_lint_and_sugg}; +use crate::utils::is_hir_ty_cfg_dependant; declare_clippy_lint! { /// **What it does:** Checks for casts from any numerical to a float type where @@ -315,58 +310,6 @@ declare_clippy_lint! { "casting a character literal to `u8` truncates" } -declare_lint_pass!(Casts => [ - CAST_PRECISION_LOSS, - CAST_SIGN_LOSS, - CAST_POSSIBLE_TRUNCATION, - CAST_POSSIBLE_WRAP, - CAST_LOSSLESS, - CAST_REF_TO_MUT, - CAST_PTR_ALIGNMENT, - UNNECESSARY_CAST, - FN_TO_NUMERIC_CAST, - FN_TO_NUMERIC_CAST_WITH_TRUNCATION, - CHAR_LIT_AS_U8, -]); - -impl<'tcx> LateLintPass<'tcx> for Casts { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - cast_ref_to_mut::check(cx, expr); - - if expr.span.from_expansion() { - return; - } - if let ExprKind::Cast(ref cast_expr, cast_to) = expr.kind { - if is_hir_ty_cfg_dependant(cx, cast_to) { - return; - } - let (cast_from, cast_to) = ( - cx.typeck_results().expr_ty(cast_expr), - cx.typeck_results().expr_ty(expr), - ); - - if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { - return; - } - - fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to); - fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to); - if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { - cast_possible_truncation::check(cx, expr, cast_from, cast_to); - cast_possible_wrap::check(cx, expr, cast_from, cast_to); - cast_precision_loss::check(cx, expr, cast_from, cast_to); - cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to); - cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to); - } - } - - cast_ptr_alignment::check(cx, expr); - char_lit_as_u8::check(cx, expr); - } -} - -const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0); - declare_clippy_lint! { /// **What it does:** /// Checks for `as` casts between raw pointers without changing its mutability, @@ -398,58 +341,66 @@ declare_clippy_lint! { "casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`" } -pub struct PtrAsPtr { +pub struct Casts { msrv: Option, } -impl PtrAsPtr { +impl Casts { #[must_use] pub fn new(msrv: Option) -> Self { Self { msrv } } } -impl_lint_pass!(PtrAsPtr => [PTR_AS_PTR]); +impl_lint_pass!(Casts => [ + CAST_PRECISION_LOSS, + CAST_SIGN_LOSS, + CAST_POSSIBLE_TRUNCATION, + CAST_POSSIBLE_WRAP, + CAST_LOSSLESS, + CAST_REF_TO_MUT, + CAST_PTR_ALIGNMENT, + UNNECESSARY_CAST, + FN_TO_NUMERIC_CAST, + FN_TO_NUMERIC_CAST_WITH_TRUNCATION, + CHAR_LIT_AS_U8, + PTR_AS_PTR, +]); -impl<'tcx> LateLintPass<'tcx> for PtrAsPtr { +impl<'tcx> LateLintPass<'tcx> for Casts { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if !meets_msrv(self.msrv.as_ref(), &PTR_AS_PTR_MSRV) { - return; - } - if expr.span.from_expansion() { return; } - if_chain! { - if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind; - let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr)); - if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind(); - if let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind(); - if matches!((from_mutbl, to_mutbl), - (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut)); - // The `U` in `pointer::cast` have to be `Sized` - // as explained here: https://github.com/rust-lang/rust/issues/60602. - if to_pointee_ty.is_sized(cx.tcx.at(expr.span), cx.param_env); - then { - let mut applicability = Applicability::MachineApplicable; - let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability); - let turbofish = match &cast_to_hir_ty.kind { - TyKind::Infer => Cow::Borrowed(""), - TyKind::Ptr(mut_ty) if matches!(mut_ty.ty.kind, TyKind::Infer) => Cow::Borrowed(""), - _ => Cow::Owned(format!("::<{}>", to_pointee_ty)), - }; - span_lint_and_sugg( - cx, - PTR_AS_PTR, - expr.span, - "`as` casting between raw pointers without changing its mutability", - "try `pointer::cast`, a safer alternative", - format!("{}.cast{}()", cast_expr_sugg.maybe_par(), turbofish), - applicability, - ); + if let ExprKind::Cast(ref cast_expr, cast_to) = expr.kind { + if is_hir_ty_cfg_dependant(cx, cast_to) { + return; + } + let (cast_from, cast_to) = ( + cx.typeck_results().expr_ty(cast_expr), + cx.typeck_results().expr_ty(expr), + ); + + if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { + return; + } + + fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to); + fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to); + if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { + cast_possible_truncation::check(cx, expr, cast_from, cast_to); + cast_possible_wrap::check(cx, expr, cast_from, cast_to); + cast_precision_loss::check(cx, expr, cast_from, cast_to); + cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to); + cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to); } } + + cast_ref_to_mut::check(cx, expr); + cast_ptr_alignment::check(cx, expr); + char_lit_as_u8::check(cx, expr); + ptr_as_ptr::check(cx, expr, &self.msrv); } extract_msrv_attr!(LateContext); diff --git a/clippy_lints/src/casts/ptr_as_ptr.rs b/clippy_lints/src/casts/ptr_as_ptr.rs new file mode 100644 index 0000000000000..abfbadf3642be --- /dev/null +++ b/clippy_lints/src/casts/ptr_as_ptr.rs @@ -0,0 +1,52 @@ +use std::borrow::Cow; + +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, Mutability, TyKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, TypeAndMut}; +use rustc_semver::RustcVersion; + +use if_chain::if_chain; + +use crate::utils::sugg::Sugg; +use crate::utils::{meets_msrv, span_lint_and_sugg}; + +use super::PTR_AS_PTR; + +const PTR_AS_PTR_MSRV: RustcVersion = RustcVersion::new(1, 38, 0); + +pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: &Option) { + if !meets_msrv(msrv.as_ref(), &PTR_AS_PTR_MSRV) { + return; + } + + if_chain! { + if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind; + let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr)); + if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind(); + if let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind(); + if matches!((from_mutbl, to_mutbl), + (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut)); + // The `U` in `pointer::cast` have to be `Sized` + // as explained here: https://github.com/rust-lang/rust/issues/60602. + if to_pointee_ty.is_sized(cx.tcx.at(expr.span), cx.param_env); + then { + let mut applicability = Applicability::MachineApplicable; + let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability); + let turbofish = match &cast_to_hir_ty.kind { + TyKind::Infer => Cow::Borrowed(""), + TyKind::Ptr(mut_ty) if matches!(mut_ty.ty.kind, TyKind::Infer) => Cow::Borrowed(""), + _ => Cow::Owned(format!("::<{}>", to_pointee_ty)), + }; + span_lint_and_sugg( + cx, + PTR_AS_PTR, + expr.span, + "`as` casting between raw pointers without changing its mutability", + "try `pointer::cast`, a safer alternative", + format!("{}.cast{}()", cast_expr_sugg.maybe_par(), turbofish), + applicability, + ); + } + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 67c481145c342..04e151df8e854 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1076,6 +1076,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(move || box use_self::UseSelf::new(msrv)); store.register_late_pass(move || box missing_const_for_fn::MissingConstForFn::new(msrv)); store.register_late_pass(move || box needless_question_mark::NeedlessQuestionMark::new(msrv)); + store.register_late_pass(move || box casts::Casts::new(msrv)); store.register_late_pass(|| box size_of_in_element_count::SizeOfInElementCount); store.register_late_pass(|| box map_clone::MapClone); @@ -1087,7 +1088,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box main_recursion::MainRecursion::default()); store.register_late_pass(|| box lifetimes::Lifetimes); store.register_late_pass(|| box entry::HashMapPass); - store.register_late_pass(|| box casts::Casts); let type_complexity_threshold = conf.type_complexity_threshold; store.register_late_pass(move || box types::TypeComplexity::new(type_complexity_threshold)); store.register_late_pass(|| box minmax::MinMaxPass); @@ -1276,7 +1276,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box strings::StringToString); store.register_late_pass(|| box zero_sized_map_values::ZeroSizedMapValues); store.register_late_pass(|| box vec_init_then_push::VecInitThenPush::default()); - store.register_late_pass(move || box casts::PtrAsPtr::new(msrv)); store.register_late_pass(|| box case_sensitive_file_extension_comparisons::CaseSensitiveFileExtensionComparisons); store.register_late_pass(|| box redundant_slicing::RedundantSlicing); store.register_late_pass(|| box from_str_radix_10::FromStrRadix10); From 9707599714c755c16e0e90b1c91420341704e5fe Mon Sep 17 00:00:00 2001 From: Andrea Nall Date: Tue, 9 Mar 2021 08:30:33 -0600 Subject: [PATCH 159/226] add comment for when can be removed --- clippy_utils/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index c0722f37f4947..44eb37387e768 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1486,6 +1486,9 @@ pub fn match_function_call<'tcx>( None } +// FIXME: Per https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/at/struct.At.html#method.normalize +// this function can be removed once the `normalizie` method does not panic when normalization does +// not succeed /// Checks if `Ty` is normalizable. This function is useful /// to avoid crashes on `layout_of`. pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { @@ -1501,7 +1504,8 @@ fn is_normalizable_helper<'tcx>( if let Some(&cached_result) = cache.get(ty) { return cached_result; } - cache.insert(ty, false); // prevent recursive loops + // prevent recursive loops, false-negative is better than endless loop leading to stack overflow + cache.insert(ty, false); let result = cx.tcx.infer_ctxt().enter(|infcx| { let cause = rustc_middle::traits::ObligationCause::dummy(); if infcx.at(&cause, param_env).normalize(ty).is_ok() { From e0f982bb3e975a3b5925e17790f6df70bad0c153 Mon Sep 17 00:00:00 2001 From: Takayuki Nakata Date: Wed, 10 Mar 2021 00:02:24 +0900 Subject: [PATCH 160/226] Improve doc on `map_flatten` --- clippy_lints/src/methods/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index cc8dcacb1ebe4..612684dc4d856 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -403,7 +403,7 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for usage of `_.map(_).flatten(_)`, + /// **What it does:** Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option` /// /// **Why is this bad?** Readability, this can be written more concisely as /// `_.flat_map(_)` From 8e1ce480b9d4a56e77a3c2f458dacd3c051f5f47 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 9 Mar 2021 17:50:04 +0100 Subject: [PATCH 161/226] Set Clippy authors to "The Rust Clippy Developers" Clippy has grown enough, that putting specific people in the "authors" field is warranted anymore. --- Cargo.toml | 8 +------- clippy_dev/Cargo.toml | 3 +-- clippy_dummy/Cargo.toml | 2 +- clippy_lints/Cargo.toml | 7 +------ mini-macro/Cargo.toml | 8 +------- rustc_tools_util/Cargo.toml | 2 +- 6 files changed, 6 insertions(+), 24 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a6d0c16fd3ae8..2b9488de28994 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,7 @@ [package] name = "clippy" version = "0.1.52" -authors = [ - "Manish Goregaokar ", - "Andre Bogus ", - "Georg Brandl ", - "Martin Carton ", - "Oliver Schneider " -] +authors = ["The Rust Clippy Developers"] description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml index ebf157b80acf1..5cfd5056f5882 100644 --- a/clippy_dev/Cargo.toml +++ b/clippy_dev/Cargo.toml @@ -1,10 +1,9 @@ [package] name = "clippy_dev" version = "0.0.1" -authors = ["Philipp Hansch "] +authors = ["The Rust Clippy Developers"] edition = "2018" - [dependencies] bytecount = "0.6" clap = "2.33" diff --git a/clippy_dummy/Cargo.toml b/clippy_dummy/Cargo.toml index 7b11795fafdc5..6959de7ffee71 100644 --- a/clippy_dummy/Cargo.toml +++ b/clippy_dummy/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "clippy_dummy" # rename to clippy before publishing version = "0.0.303" -authors = ["Manish Goregaokar "] +authors = ["The Rust Clippy Developers"] edition = "2018" readme = "crates-readme.md" description = "A bunch of helpful lints to avoid common pitfalls in Rust." diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index ff4cf527ec482..6bd6c079276e4 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -3,12 +3,7 @@ name = "clippy_lints" # begin automatic update version = "0.1.52" # end automatic update -authors = [ - "Manish Goregaokar ", - "Andre Bogus ", - "Georg Brandl ", - "Martin Carton ", -] +authors = ["The Rust Clippy Developers"] description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/mini-macro/Cargo.toml b/mini-macro/Cargo.toml index 75ab17588a7f4..0d95c86aef030 100644 --- a/mini-macro/Cargo.toml +++ b/mini-macro/Cargo.toml @@ -1,13 +1,7 @@ [package] name = "clippy-mini-macro-test" version = "0.2.0" -authors = [ - "Manish Goregaokar ", - "Andre Bogus ", - "Georg Brandl ", - "Martin Carton ", - "Oliver Schneider " -] +authors = ["The Rust Clippy Developers"] license = "MIT OR Apache-2.0" description = "A macro to test clippy's procedural macro checks" repository = "https://github.com/rust-lang/rust-clippy" diff --git a/rustc_tools_util/Cargo.toml b/rustc_tools_util/Cargo.toml index 6f0fc5bee8f09..2972bc6d51ca8 100644 --- a/rustc_tools_util/Cargo.toml +++ b/rustc_tools_util/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_tools_util" version = "0.2.0" -authors = ["Matthias Krüger "] +authors = ["The Rust Clippy Developers"] description = "small helper to generate version information for git packages" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" From 6f60dd884ef73b310b3f8c3e8370892ac2e10120 Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 5 Oct 2020 22:53:00 +0000 Subject: [PATCH 162/226] Update match branches This updates all places where match branches check on StatementKind or UseContext. This doesn't properly implement them, but adds TODOs where they are, and also adds some best guesses to what they should be in some cases. --- clippy_utils/src/qualify_min_const_fn.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 2cb9588e13f98..53935f02a90e4 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -210,7 +210,7 @@ fn check_statement(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, statemen StatementKind::Assign(box (place, rval)) => { check_place(tcx, *place, span, body)?; check_rvalue(tcx, body, def_id, rval, span) - }, + } StatementKind::FakeRead(_, place) | // just an assignment @@ -218,6 +218,13 @@ fn check_statement(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, statemen StatementKind::LlvmInlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())), + StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping{ + dst, src, size, + }) => { + check_operand(tcx, dst, span, body)?; + check_operand(tcx, src, span, body)?; + check_operand(tcx, size, span, body) + }, // These are all NOPs StatementKind::StorageLive(_) | StatementKind::StorageDead(_) From fb4dc5845bc2b692597c450e81946268162bf3e4 Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 29 Dec 2020 02:00:04 +0000 Subject: [PATCH 163/226] Update cranelift --- clippy_utils/src/qualify_min_const_fn.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 53935f02a90e4..0678d8253d590 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -219,11 +219,11 @@ fn check_statement(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, statemen StatementKind::LlvmInlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())), StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping{ - dst, src, size, + dst, src, count, }) => { check_operand(tcx, dst, span, body)?; check_operand(tcx, src, span, body)?; - check_operand(tcx, size, span, body) + check_operand(tcx, count, span, body) }, // These are all NOPs StatementKind::StorageLive(_) From cb8bc0b6e659cc82b80a056dbe7b7df3acda7df6 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 23 Jan 2021 08:57:04 +0000 Subject: [PATCH 164/226] Switch to changing cp_non_overlap in tform It was suggested to lower this in MIR instead of ssa, so do that instead. --- clippy_utils/src/qualify_min_const_fn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 0678d8253d590..1391f7505e27c 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -224,7 +224,7 @@ fn check_statement(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, statemen check_operand(tcx, dst, span, body)?; check_operand(tcx, src, span, body)?; check_operand(tcx, count, span, body) - }, + } // These are all NOPs StatementKind::StorageLive(_) | StatementKind::StorageDead(_) From 8d5e0f512fec8f4b1fb0644051b249d310f611eb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 6 Dec 2020 22:00:24 +0100 Subject: [PATCH 165/226] Simplify clippy author. --- clippy_lints/src/utils/author.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 6e3d4fde10777..3dd190ba44018 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -2,7 +2,7 @@ //! to generate a clippy lint detecting said code automatically. use crate::utils::get_attr; -use rustc_ast::ast::{Attribute, LitFloatType, LitKind}; +use rustc_ast::ast::{LitFloatType, LitKind}; use rustc_ast::walk_list; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; @@ -10,7 +10,6 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor}; use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; -use rustc_session::Session; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -66,7 +65,7 @@ fn done() { impl<'tcx> LateLintPass<'tcx> for Author { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - if !has_attr(cx.sess(), &item.attrs) { + if !has_attr(cx, item.hir_id()) { return; } prelude(); @@ -75,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { - if !has_attr(cx.sess(), &item.attrs) { + if !has_attr(cx, item.hir_id()) { return; } prelude(); @@ -84,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { - if !has_attr(cx.sess(), &item.attrs) { + if !has_attr(cx, item.hir_id()) { return; } prelude(); @@ -93,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_variant(&mut self, cx: &LateContext<'tcx>, var: &'tcx hir::Variant<'_>) { - if !has_attr(cx.sess(), &var.attrs) { + if !has_attr(cx, var.id) { return; } prelude(); @@ -103,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::StructField<'_>) { - if !has_attr(cx.sess(), &field.attrs) { + if !has_attr(cx, field.hir_id) { return; } prelude(); @@ -112,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { - if !has_attr(cx.sess(), &expr.attrs) { + if !has_attr(cx, expr.hir_id) { return; } prelude(); @@ -121,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) { - if !has_attr(cx.sess(), &arm.attrs) { + if !has_attr(cx, arm.hir_id) { return; } prelude(); @@ -130,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) { - if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) { + if !has_attr(cx, stmt.hir_id) { return; } prelude(); @@ -139,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ForeignItem<'_>) { - if !has_attr(cx.sess(), &item.attrs) { + if !has_attr(cx, item.hir_id()) { return; } prelude(); @@ -719,8 +718,9 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { } } -fn has_attr(sess: &Session, attrs: &[Attribute]) -> bool { - get_attr(sess, attrs, "author").count() > 0 +fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool { + let attrs = cx.tcx.hir().attrs(hir_id); + get_attr(cx.sess(), attrs, "author").count() > 0 } #[must_use] From 476c5283d5a815474e9bd3d103c788bdc9655bd9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Nov 2020 09:24:42 +0100 Subject: [PATCH 166/226] Do not store attrs in FnKind. --- clippy_lints/src/cognitive_complexity.rs | 4 ++-- clippy_lints/src/functions.rs | 9 ++++----- clippy_lints/src/future_not_send.rs | 2 +- clippy_lints/src/misc.rs | 2 +- clippy_lints/src/missing_const_for_fn.rs | 2 +- clippy_lints/src/needless_pass_by_value.rs | 5 +++-- clippy_lints/src/panic_in_result_fn.rs | 4 +--- clippy_lints/src/pass_by_ref_or_value.rs | 5 +++-- clippy_lints/src/returns.rs | 2 +- clippy_lints/src/unnecessary_wraps.rs | 4 ++-- 10 files changed, 19 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index f21a734bb439f..658d445dfec54 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -76,8 +76,8 @@ impl CognitiveComplexity { if rust_cc > self.limit.limit() { let fn_span = match kind { - FnKind::ItemFn(ident, _, _, _, _) | FnKind::Method(ident, _, _, _) => ident.span, - FnKind::Closure(_) => { + FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span, + FnKind::Closure => { let header_span = body_span.with_hi(decl.output.span().lo()); let pos = snippet_opt(cx, header_span).and_then(|snip| { let low_offset = snip.find('|')?; diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index e4b3a9009f612..ae0b8d06dc2fb 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -251,9 +251,9 @@ impl<'tcx> LateLintPass<'tcx> for Functions { hir_id: hir::HirId, ) { let unsafety = match kind { - intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety, - intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety, - intravisit::FnKind::Closure(_) => return, + intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety, + intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety, + intravisit::FnKind::Closure => return, }; // don't warn for implementations, it's not their fault @@ -267,9 +267,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions { .. }, _, - _, ) - | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => { + | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => { self.check_arg_number(cx, decl, span.with_hi(decl.output.span().hi())) }, _ => {}, diff --git a/clippy_lints/src/future_not_send.rs b/clippy_lints/src/future_not_send.rs index 7208e66ff7be1..9e1a8864a3ebe 100644 --- a/clippy_lints/src/future_not_send.rs +++ b/clippy_lints/src/future_not_send.rs @@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { _: Span, hir_id: HirId, ) { - if let FnKind::Closure(_) = kind { + if let FnKind::Closure = kind { return; } let ret_ty = utils::return_ty(cx, hir_id); diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 2ef5c6aa2a4e2..35b4c3d5b03ab 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -278,7 +278,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints { span: Span, _: HirId, ) { - if let FnKind::Closure(_) = k { + if let FnKind::Closure = k { // Does not apply to closures return; } diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index 6ebeaced62a33..b0998a80128ce 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { return; } }, - FnKind::Closure(..) => return, + FnKind::Closure => return, } let mir = cx.tcx.optimized_mir(def_id); diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 54033f4087140..cac4b2075114a 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -80,13 +80,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } match kind { - FnKind::ItemFn(.., header, _, attrs) => { + FnKind::ItemFn(.., header, _) => { + let attrs = cx.tcx.hir().attrs(hir_id); if header.abi != Abi::Rust || requires_exact_signature(attrs) { return; } }, FnKind::Method(..) => (), - FnKind::Closure(..) => return, + FnKind::Closure => return, } // Exclude non-inherent impls diff --git a/clippy_lints/src/panic_in_result_fn.rs b/clippy_lints/src/panic_in_result_fn.rs index 37e2b50def17a..207423a186149 100644 --- a/clippy_lints/src/panic_in_result_fn.rs +++ b/clippy_lints/src/panic_in_result_fn.rs @@ -43,9 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn { span: Span, hir_id: hir::HirId, ) { - if !matches!(fn_kind, FnKind::Closure(_)) - && is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) - { + if !matches!(fn_kind, FnKind::Closure) && is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) { lint_impl_body(cx, span, body); } } diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index b9ba32001b513..ff700aa514607 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -224,10 +224,11 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { } match kind { - FnKind::ItemFn(.., header, _, attrs) => { + FnKind::ItemFn(.., header, _) => { if header.abi != Abi::Rust { return; } + let attrs = cx.tcx.hir().attrs(hir_id); for a in attrs { if let Some(meta_items) = a.meta_item_list() { if a.has_name(sym::proc_macro_derive) @@ -239,7 +240,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { } }, FnKind::Method(..) => (), - FnKind::Closure(..) => return, + FnKind::Closure => return, } // Exclude non-inherent impls diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index e438f92b136ac..28d7011207f8d 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { _: HirId, ) { match kind { - FnKind::Closure(_) => { + FnKind::Closure => { // when returning without value in closure, replace this `return` // with an empty block to prevent invalid suggestion (see #6501) let replacement = if let ExprKind::Ret(None) = &body.value.kind { diff --git a/clippy_lints/src/unnecessary_wraps.rs b/clippy_lints/src/unnecessary_wraps.rs index 1e58576d0599c..8e076397c119a 100644 --- a/clippy_lints/src/unnecessary_wraps.rs +++ b/clippy_lints/src/unnecessary_wraps.rs @@ -66,12 +66,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps { ) { // Abort if public function/method or closure. match fn_kind { - FnKind::ItemFn(.., visibility, _) | FnKind::Method(.., Some(visibility), _) => { + FnKind::ItemFn(.., visibility) | FnKind::Method(.., Some(visibility)) => { if visibility.node.is_pub() { return; } }, - FnKind::Closure(..) => return, + FnKind::Closure => return, _ => (), } From 3e721b144559d1eab00178bf4cc06ff969a118d7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 25 Nov 2020 22:07:09 +0100 Subject: [PATCH 167/226] Remove hir::StmtKind::attrs. --- clippy_lints/src/utils/inspector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 9c1d98cd70745..4ac15095ef5f9 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { } fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) { - if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) { + if !has_attr(cx.sess(), cx.tcx.hir().attrs(stmt.hir_id)) { return; } match stmt.kind { From acd6014b806cdb2600218e63aa599012bb2507e6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 25 Nov 2020 22:45:24 +0100 Subject: [PATCH 168/226] Remove hir::Local::attrs. --- clippy_lints/src/returns.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 28d7011207f8d..e8646695e0b23 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { if let Some(stmt) = block.stmts.iter().last(); if let StmtKind::Local(local) = &stmt.kind; if local.ty.is_none(); - if local.attrs.is_empty(); + if cx.tcx.hir().attrs(local.hir_id).is_empty(); if let Some(initexpr) = &local.init; if let PatKind::Binding(.., ident, _) = local.pat.kind; if let ExprKind::Path(qpath) = &retexpr.kind; From b32cffe493cd9ad428b59f3185f54d835ea427fb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 26 Nov 2020 23:38:53 +0100 Subject: [PATCH 169/226] Remove hir::Crate::attrs. --- clippy_lints/src/doc.rs | 5 +++-- clippy_lints/src/loops.rs | 2 +- clippy_lints/src/main_recursion.rs | 4 ++-- clippy_lints/src/missing_doc.rs | 3 ++- clippy_utils/src/lib.rs | 6 +++--- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 39a202f281cb7..8deccd6f9d777 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -208,8 +208,9 @@ impl_lint_pass!(DocMarkdown => ); impl<'tcx> LateLintPass<'tcx> for DocMarkdown { - fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) { - check_attrs(cx, &self.valid_idents, &krate.item.attrs); + fn check_crate(&mut self, cx: &LateContext<'tcx>, _: &'tcx hir::Crate<'_>) { + let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); + check_attrs(cx, &self.valid_idents, attrs); } fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index c89a087657509..9b626d81ebd81 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -578,7 +578,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { // also check for empty `loop {}` statements, skipping those in #[panic_handler] if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) { let msg = "empty `loop {}` wastes CPU cycles"; - let help = if is_no_std_crate(cx.tcx.hir().krate()) { + let help = if is_no_std_crate(cx) { "you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body" } else { "you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body" diff --git a/clippy_lints/src/main_recursion.rs b/clippy_lints/src/main_recursion.rs index 1ed3f3de83908..1b274c79d3820 100644 --- a/clippy_lints/src/main_recursion.rs +++ b/clippy_lints/src/main_recursion.rs @@ -32,8 +32,8 @@ pub struct MainRecursion { impl_lint_pass!(MainRecursion => [MAIN_RECURSION]); impl LateLintPass<'_> for MainRecursion { - fn check_crate(&mut self, _: &LateContext<'_>, krate: &Crate<'_>) { - self.has_no_std_attr = is_no_std_crate(krate); + fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) { + self.has_no_std_attr = is_no_std_crate(cx); } fn check_expr_post(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 761b9261772b2..a1eb8e29850b8 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -127,7 +127,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) { - self.check_missing_docs_attrs(cx, &krate.item.attrs, krate.item.span, "the", "crate"); + let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); + self.check_missing_docs_attrs(cx, attrs, krate.item.span, "the", "crate"); } fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 42512cadfb18d..4cd7ed5c45da3 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -61,7 +61,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::Node; use rustc_hir::{ - def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind, + def, Arm, Block, Body, Constness, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind, MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, TyKind, Unsafety, }; use rustc_infer::infer::TyCtxtInferExt; @@ -1510,8 +1510,8 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { did.map_or(false, |did| must_use_attr(&cx.tcx.get_attrs(did)).is_some()) } -pub fn is_no_std_crate(krate: &Crate<'_>) -> bool { - krate.item.attrs.iter().any(|attr| { +pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { + cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| { if let ast::AttrKind::Normal(ref attr, _) = attr.kind { attr.path == sym::no_std } else { From 04496071e4bb8d163f17f43dad216bc0a96e0abf Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 26 Nov 2020 23:46:48 +0100 Subject: [PATCH 170/226] Remove hir::Arm::attrs. --- clippy_lints/src/matches.rs | 4 ++-- clippy_lints/src/utils/inspector.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index efc8b13942507..9c87759d51d2d 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1207,11 +1207,11 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr if b0 != b1; let if_guard = &b0_arms[0].guard; if if_guard.is_none() || b0_arms.len() == 1; - if b0_arms[0].attrs.is_empty(); + if cx.tcx.hir().attrs(b0_arms[0].hir_id).is_empty(); if b0_arms[1..].iter() .all(|arm| { find_bool_lit(&arm.body.kind, desugared).map_or(false, |b| b == b0) && - arm.guard.is_none() && arm.attrs.is_empty() + arm.guard.is_none() && cx.tcx.hir().attrs(arm.hir_id).is_empty() }); then { // The suggestion may be incorrect, because some arms can have `cfg` attributes diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 4ac15095ef5f9..e1c58d88952e8 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { } fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) { - if !has_attr(cx.sess(), &arm.attrs) { + if !has_attr(cx.sess(), cx.tcx.hir().attrs(arm.hir_id)) { return; } print_pat(cx, &arm.pat, 1); From 55f68ead6b455b5715c39af760c30794a7404bd2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Nov 2020 00:07:36 +0100 Subject: [PATCH 171/226] Remove hir::Variant::attrs. --- clippy_lints/src/missing_doc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index a1eb8e29850b8..8665a2d71b6dc 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -192,6 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) { - self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a", "variant"); + let attrs = cx.tcx.hir().attrs(v.id); + self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant"); } } From c3a17dba6ccd0dee7e175d178203e930c04c3f03 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Nov 2020 00:27:34 +0100 Subject: [PATCH 172/226] Remove hir::StructField::attrs. --- clippy_lints/src/missing_doc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 8665a2d71b6dc..e82fe9f010005 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -187,7 +187,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) { if !sf.is_positional() { - self.check_missing_docs_attrs(cx, &sf.attrs, sf.span, "a", "struct field"); + let attrs = cx.tcx.hir().attrs(sf.hir_id); + self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field"); } } From dd2af148ccfaa30b29341823ac8e38989ffd1b6d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Nov 2020 09:41:53 +0100 Subject: [PATCH 173/226] Remove hir::TraitItem::attrs. --- clippy_lints/src/attrs.rs | 2 +- clippy_lints/src/doc.rs | 3 ++- clippy_lints/src/functions.rs | 5 +++-- clippy_lints/src/inline_fn_without_body.rs | 3 ++- clippy_lints/src/missing_doc.rs | 3 ++- clippy_lints/src/missing_inline.rs | 3 ++- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 652d1fa16b6de..5ca67507a3d47 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -359,7 +359,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if is_relevant_trait(cx, item) { - check_attrs(cx, item.span, item.ident.name, &item.attrs) + check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())) } } } diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 8deccd6f9d777..5299b192f501e 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -250,7 +250,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { - let headers = check_attrs(cx, &self.valid_idents, &item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + let headers = check_attrs(cx, &self.valid_idents, attrs); if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind { if !in_external_macro(cx.tcx.sess, item.span) { lint_for_missing_headers(cx, item.hir_id(), item.span, sig, headers, None, None); diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index ae0b8d06dc2fb..4a10f9abce4b7 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -344,7 +344,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions { check_result_unit_err(cx, &sig.decl, item.span, fn_header_span); } - let attr = must_use_attr(&item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attr = must_use_attr(attrs); if let Some(attr) = attr { check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr); } @@ -352,7 +353,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions { let body = cx.tcx.hir().body(eid); Self::check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.hir_id()); - if attr.is_none() && is_public && !is_proc_macro(cx.sess(), &item.attrs) { + if attr.is_none() && is_public && !is_proc_macro(cx.sess(), attrs) { check_must_use_candidate( cx, &sig.decl, diff --git a/clippy_lints/src/inline_fn_without_body.rs b/clippy_lints/src/inline_fn_without_body.rs index d1c3fdc71461b..00acbd6cc3f76 100644 --- a/clippy_lints/src/inline_fn_without_body.rs +++ b/clippy_lints/src/inline_fn_without_body.rs @@ -34,7 +34,8 @@ declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]); impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind { - check_attrs(cx, item.ident.name, &item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + check_attrs(cx, item.ident.name, attrs); } } } diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index e82fe9f010005..0a75b47e2c65f 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -167,7 +167,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id()); - self.check_missing_docs_attrs(cx, &trait_item.attrs, trait_item.span, article, desc); + let attrs = cx.tcx.hir().attrs(trait_item.hir_id()); + self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc); } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 47d7c5306c433..74afc292f0181 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -108,7 +108,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // an impl is not provided let desc = "a default trait method"; let item = cx.tcx.hir().trait_item(tit.id); - check_missing_inline_attrs(cx, &item.attrs, item.span, desc); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + check_missing_inline_attrs(cx, attrs, item.span, desc); } }, } From 49835d8abf93ca0d3249d7f534963fe28313aa18 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Nov 2020 09:55:10 +0100 Subject: [PATCH 174/226] Remove hir::ImplItem::attrs. --- clippy_lints/src/attrs.rs | 2 +- clippy_lints/src/doc.rs | 3 ++- clippy_lints/src/functions.rs | 5 +++-- clippy_lints/src/missing_doc.rs | 3 ++- clippy_lints/src/missing_inline.rs | 3 ++- clippy_lints/src/utils/inspector.rs | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 5ca67507a3d47..362b11792a8de 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -353,7 +353,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if is_relevant_impl(cx, item) { - check_attrs(cx, item.span, item.ident.name, &item.attrs) + check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())) } } diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 5299b192f501e..058f64780d69d 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -260,7 +260,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown { } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { - let headers = check_attrs(cx, &self.valid_idents, &item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + let headers = check_attrs(cx, &self.valid_idents, attrs); if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) { return; } diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 4a10f9abce4b7..b48b0b9f3e2f2 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -312,11 +312,12 @@ impl<'tcx> LateLintPass<'tcx> for Functions { if is_public && trait_ref_of_method(cx, item.hir_id()).is_none() { check_result_unit_err(cx, &sig.decl, item.span, fn_header_span); } - let attr = must_use_attr(&item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attr = must_use_attr(attrs); if let Some(attr) = attr { check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr); } else if is_public - && !is_proc_macro(cx.sess(), &item.attrs) + && !is_proc_macro(cx.sess(), attrs) && trait_ref_of_method(cx, item.hir_id()).is_none() { check_must_use_candidate( diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 0a75b47e2c65f..84852dd602bbb 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -183,7 +183,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id()); - self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, article, desc); + let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc); } fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) { diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 74afc292f0181..c915e329087f5 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -161,6 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { } } - check_missing_inline_attrs(cx, &impl_item.attrs, impl_item.span, desc); + let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + check_missing_inline_attrs(cx, attrs, impl_item.span, desc); } } diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index e1c58d88952e8..e95840e9db1cc 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -40,7 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { - if !has_attr(cx.sess(), &item.attrs) { + if !has_attr(cx.sess(), cx.tcx.hir().attrs(item.hir_id())) { return; } println!("impl item `{}`", item.ident.name); From dc9560cfd2e466ffbaf4615197ed4386ccb90c1d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 24 Jan 2021 13:17:54 +0100 Subject: [PATCH 175/226] Remove hir::Item::attrs. --- clippy_lints/src/attrs.rs | 7 ++++--- clippy_lints/src/derive.rs | 3 ++- clippy_lints/src/doc.rs | 3 ++- clippy_lints/src/exhaustive_items.rs | 3 ++- clippy_lints/src/functions.rs | 5 +++-- clippy_lints/src/macro_use.rs | 4 ++-- clippy_lints/src/missing_doc.rs | 3 ++- clippy_lints/src/missing_inline.rs | 3 ++- clippy_lints/src/needless_borrow.rs | 5 +++-- clippy_lints/src/partialeq_ne_impl.rs | 3 ++- clippy_lints/src/utils/inspector.rs | 2 +- 11 files changed, 25 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 362b11792a8de..78f0846e88e7d 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -276,14 +276,15 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { } fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { + let attrs = cx.tcx.hir().attrs(item.hir_id()); if is_relevant_item(cx, item) { - check_attrs(cx, item.span, item.ident.name, &item.attrs) + check_attrs(cx, item.span, item.ident.name, attrs) } match item.kind { ItemKind::ExternCrate(..) | ItemKind::Use(..) => { - let skip_unused_imports = item.attrs.iter().any(|attr| attr.has_name(sym::macro_use)); + let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use)); - for attr in item.attrs { + for attr in attrs { if in_external_macro(cx.sess(), attr.span) { return; } diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index e8510bde9adcd..66cf6682f8501 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -170,7 +170,8 @@ impl<'tcx> LateLintPass<'tcx> for Derive { }) = item.kind { let ty = cx.tcx.type_of(item.def_id); - let is_automatically_derived = is_automatically_derived(&*item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + let is_automatically_derived = is_automatically_derived(attrs); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived); diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 058f64780d69d..23c99e45ca7fc 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -214,7 +214,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown { } fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - let headers = check_attrs(cx, &self.valid_idents, &item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + let headers = check_attrs(cx, &self.valid_idents, attrs); match item.kind { hir::ItemKind::Fn(ref sig, _, body_id) => { if !(is_entrypoint_fn(cx, item.def_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) { diff --git a/clippy_lints/src/exhaustive_items.rs b/clippy_lints/src/exhaustive_items.rs index ab9be3398bfa6..316f748486280 100644 --- a/clippy_lints/src/exhaustive_items.rs +++ b/clippy_lints/src/exhaustive_items.rs @@ -73,7 +73,8 @@ impl LateLintPass<'_> for ExhaustiveItems { if_chain! { if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind; if cx.access_levels.is_exported(item.hir_id()); - if !item.attrs.iter().any(|a| a.has_name(sym::non_exhaustive)); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)); then { let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind { if v.fields().iter().any(|f| !f.vis.node.is_pub()) { diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index b48b0b9f3e2f2..234cb0f53aa0c 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -280,7 +280,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions { } fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - let attr = must_use_attr(&item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attr = must_use_attr(attrs); if let hir::ItemKind::Fn(ref sig, ref _generics, ref body_id) = item.kind { let is_public = cx.access_levels.is_exported(item.hir_id()); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); @@ -291,7 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions { check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr); return; } - if is_public && !is_proc_macro(cx.sess(), &item.attrs) && attr_by_name(&item.attrs, "no_mangle").is_none() { + if is_public && !is_proc_macro(cx.sess(), attrs) && attr_by_name(attrs, "no_mangle").is_none() { check_must_use_candidate( cx, &sig.decl, diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index 40f04bd677d52..6d9c78393c8c4 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -107,8 +107,8 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports { if_chain! { if cx.sess().opts.edition >= Edition::Edition2018; if let hir::ItemKind::Use(path, _kind) = &item.kind; - if let Some(mac_attr) = item - .attrs + let attrs = cx.tcx.hir().attrs(item.hir_id()); + if let Some(mac_attr) = attrs .iter() .find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string())); if let Res::Def(DefKind::Mod, id) = path.res; diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 84852dd602bbb..6ec4c38d0f9cc 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -161,7 +161,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id()); - self.check_missing_docs_attrs(cx, &it.attrs, it.span, article, desc); + let attrs = cx.tcx.hir().attrs(it.hir_id()); + self.check_missing_docs_attrs(cx, attrs, it.span, article, desc); } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index c915e329087f5..9b604471573d9 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -93,7 +93,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { match it.kind { hir::ItemKind::Fn(..) => { let desc = "a function"; - check_missing_inline_attrs(cx, &it.attrs, it.span, desc); + let attrs = cx.tcx.hir().attrs(it.hir_id()); + check_missing_inline_attrs(cx, attrs, it.span, desc); }, hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics, ref _bounds, trait_items) => { // note: we need to check if the trait is exported so we can't use diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 1453ea6e8975d..1aadcfd87b60f 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -115,8 +115,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow { } } - fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if is_automatically_derived(item.attrs) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { + let attrs = cx.tcx.hir().attrs(item.hir_id()); + if is_automatically_derived(attrs) { debug_assert!(self.derived_item.is_none()); self.derived_item = Some(item.def_id); } diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index 3d6129aa78d4c..aca1ed5ca6563 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -35,7 +35,8 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if_chain! { if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind; - if !is_automatically_derived(&*item.attrs); + let attrs = cx.tcx.hir().attrs(item.hir_id()); + if !is_automatically_derived(attrs); if let Some(eq_trait) = cx.tcx.lang_items().eq_trait(); if trait_ref.path.res.def_id() == eq_trait; then { diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index e95840e9db1cc..07a79592a4acd 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -33,7 +33,7 @@ declare_lint_pass!(DeepCodeInspector => [DEEP_CODE_INSPECTION]); impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - if !has_attr(cx.sess(), &item.attrs) { + if !has_attr(cx.sess(), cx.tcx.hir().attrs(item.hir_id())) { return; } print_item(cx, item); From 6c668266c0d4a949e534bb2770fa3fcc8b64ef1d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 Nov 2020 17:41:05 +0100 Subject: [PATCH 176/226] Remove hir::Expr::attrs. --- clippy_lints/src/returns.rs | 3 ++- clippy_lints/src/utils/inspector.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index e8646695e0b23..40c0f1f45895b 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -177,7 +177,8 @@ fn check_final_expr<'tcx>( // simple return is always "bad" ExprKind::Ret(ref inner) => { // allow `#[cfg(a)] return a; #[cfg(b)] return b;` - if !expr.attrs.iter().any(attr_is_cfg) { + let attrs = cx.tcx.hir().attrs(expr.hir_id); + if !attrs.iter().any(attr_is_cfg) { let borrows = inner.map_or(false, |inner| last_statement_borrows(cx, inner)); if !borrows { emit_return_lint( diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 07a79592a4acd..9e3973e1d51fc 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { // fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { - if !has_attr(cx.sess(), &expr.attrs) { + if !has_attr(cx.sess(), cx.tcx.hir().attrs(expr.hir_id)) { return; } print_expr(cx, expr, 0); From ae6be4f36182722e7a3b021868ee913f1a97200e Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 11 Mar 2021 10:38:49 +0100 Subject: [PATCH 177/226] Bump nightly version => 2021-03-11 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 865043b46d179..c52a7f2e74321 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-02-25" +channel = "nightly-2021-03-11" components = ["llvm-tools-preview", "rustc-dev", "rust-src"] From 9c1dd0c22721029dc47e5fe73d85670abab9adfc Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 11 Mar 2021 10:57:49 +0100 Subject: [PATCH 178/226] Fix remaining dogfood errors (internal lints) --- clippy_lints/src/loops/explicit_iter_loop.rs | 8 ++++---- clippy_lints/src/loops/for_kv_map.rs | 3 ++- clippy_lints/src/loops/manual_memcpy.rs | 2 +- clippy_lints/src/loops/needless_collect.rs | 6 +++--- clippy_lints/src/methods/iter_count.rs | 6 +++--- clippy_utils/src/eager_or_lazy.rs | 5 +++-- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index 44d0891689105..9683e59a3962d 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -4,7 +4,7 @@ use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty, TyS}; -use rustc_span::symbol::sym; +use rustc_span::sym; use crate::utils::{is_type_diagnostic_item, match_type, paths}; @@ -55,9 +55,9 @@ fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { is_iterable_array(ty, cx) || is_type_diagnostic_item(cx, ty, sym::vec_type) || match_type(cx, ty, &paths::LINKED_LIST) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || - is_type_diagnostic_item(cx, ty, sym!(hashset_type)) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::hashmap_type) || + is_type_diagnostic_item(cx, ty, sym::hashset_type) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::BINARY_HEAP) || match_type(cx, ty, &paths::BTREEMAP) || match_type(cx, ty, &paths::BTREESET) diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index eb53c3179ca4a..6ee9b95a3b689 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -4,6 +4,7 @@ use crate::utils::{is_type_diagnostic_item, match_type, multispan_sugg, paths, s use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty; +use rustc_span::sym; /// Checks for the `FOR_KV_MAP` lint. pub(super) fn check<'tcx>( @@ -35,7 +36,7 @@ pub(super) fn check<'tcx>( _ => arg, }; - if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP) { + if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP) { span_lint_and_then( cx, FOR_KV_MAP, diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs index c41eb32f9d885..fad96c2d5c04c 100644 --- a/clippy_lints/src/loops/manual_memcpy.rs +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -328,7 +328,7 @@ fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'_>) -> bool { _ => false, }; - is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) + is_slice || is_type_diagnostic_item(cx, ty, sym::vec_type) || is_type_diagnostic_item(cx, ty, sym::vecdeque_type) } fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { diff --git a/clippy_lints/src/loops/needless_collect.rs b/clippy_lints/src/loops/needless_collect.rs index 6f27130910550..92560c806295c 100644 --- a/clippy_lints/src/loops/needless_collect.rs +++ b/clippy_lints/src/loops/needless_collect.rs @@ -29,9 +29,9 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont then { let ty = cx.typeck_results().node_type(ty.hir_id); if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::BTREEMAP) || - is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { + is_type_diagnostic_item(cx, ty, sym::hashmap_type) { if method.ident.name == sym!(len) { let span = shorten_needless_collect_span(expr); span_lint_and_sugg( @@ -99,7 +99,7 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); if let ty = cx.typeck_results().node_type(ty.hir_id); if is_type_diagnostic_item(cx, ty, sym::vec_type) || - is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || + is_type_diagnostic_item(cx, ty, sym::vecdeque_type) || match_type(cx, ty, &paths::LINKED_LIST); if let Some(iter_calls) = detect_iter_and_into_iters(block, *ident); if iter_calls.len() == 1; diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index 1b99bacc3f1c2..71d65a01d3e85 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -14,11 +14,11 @@ pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &' "slice" } else if is_type_diagnostic_item(cx, ty, sym::vec_type) { "Vec" - } else if is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, ty, sym::vecdeque_type) { "VecDeque" - } else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) { + } else if is_type_diagnostic_item(cx, ty, sym::hashset_type) { "HashSet" - } else if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { + } else if is_type_diagnostic_item(cx, ty, sym::hashmap_type) { "HashMap" } else if match_type(cx, ty, &paths::BTREEMAP) { "BTreeMap" diff --git a/clippy_utils/src/eager_or_lazy.rs b/clippy_utils/src/eager_or_lazy.rs index f54a35a0a1877..8013c4e4fcbe4 100644 --- a/clippy_utils/src/eager_or_lazy.rs +++ b/clippy_utils/src/eager_or_lazy.rs @@ -9,7 +9,7 @@ //! - or-fun-call //! - option-if-let-else -use crate::{is_ctor_or_promotable_const_function, is_type_diagnostic_item, match_type, paths}; +use crate::{is_ctor_or_promotable_const_function, is_type_diagnostic_item}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit; @@ -100,7 +100,8 @@ fn identify_some_potentially_expensive_patterns<'tcx>(cx: &LateContext<'tcx>, ex ExprKind::Call(..) => !is_ctor_or_promotable_const_function(self.cx, expr), ExprKind::Index(obj, _) => { let ty = self.cx.typeck_results().expr_ty(obj); - is_type_diagnostic_item(self.cx, ty, sym::hashmap_type) || match_type(self.cx, ty, &paths::BTREEMAP) + is_type_diagnostic_item(self.cx, ty, sym::hashmap_type) + || is_type_diagnostic_item(self.cx, ty, sym::BTreeMap) }, ExprKind::MethodCall(..) => true, _ => false, From f0f07accbce24adb5706eeb4e14e0e1c6b2b973b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 00:14:38 +0900 Subject: [PATCH 179/226] move expect_used, filter_next, get_unwrap, ok_expect and unwrap_used to their own modules --- clippy_lints/src/methods/expect_used.rs | 30 +++ clippy_lints/src/methods/filter_next.rs | 31 +++ clippy_lints/src/methods/get_unwrap.rs | 84 +++++++ clippy_lints/src/methods/mod.rs | 218 ++---------------- clippy_lints/src/methods/ok_expect.rs | 45 ++++ .../src/methods/option_map_unwrap_or.rs | 2 +- .../src/methods/unnecessary_lazy_eval.rs | 2 +- clippy_lints/src/methods/unwrap_used.rs | 34 +++ 8 files changed, 244 insertions(+), 202 deletions(-) create mode 100644 clippy_lints/src/methods/expect_used.rs create mode 100644 clippy_lints/src/methods/filter_next.rs create mode 100644 clippy_lints/src/methods/get_unwrap.rs create mode 100644 clippy_lints/src/methods/ok_expect.rs create mode 100644 clippy_lints/src/methods/unwrap_used.rs diff --git a/clippy_lints/src/methods/expect_used.rs b/clippy_lints/src/methods/expect_used.rs new file mode 100644 index 0000000000000..90b781bd9d190 --- /dev/null +++ b/clippy_lints/src/methods/expect_used.rs @@ -0,0 +1,30 @@ +use crate::utils::{is_type_diagnostic_item, span_lint_and_help}; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::sym; + +use super::EXPECT_USED; + +/// lint use of `expect()` for `Option`s and `Result`s +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) { + let obj_ty = cx.typeck_results().expr_ty(&expect_args[0]).peel_refs(); + + let mess = if is_type_diagnostic_item(cx, obj_ty, sym::option_type) { + Some((EXPECT_USED, "an Option", "None")) + } else if is_type_diagnostic_item(cx, obj_ty, sym::result_type) { + Some((EXPECT_USED, "a Result", "Err")) + } else { + None + }; + + if let Some((lint, kind, none_value)) = mess { + span_lint_and_help( + cx, + lint, + expr.span, + &format!("used `expect()` on `{}` value", kind,), + None, + &format!("if this value is an `{}`, it will panic", none_value,), + ); + } +} diff --git a/clippy_lints/src/methods/filter_next.rs b/clippy_lints/src/methods/filter_next.rs new file mode 100644 index 0000000000000..81619e73017f2 --- /dev/null +++ b/clippy_lints/src/methods/filter_next.rs @@ -0,0 +1,31 @@ +use crate::utils::{match_trait_method, paths, snippet, span_lint, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::FILTER_NEXT; + +/// lint use of `filter().next()` for `Iterators` +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) { + // lint if caller of `.filter().next()` is an Iterator + if match_trait_method(cx, expr, &paths::ITERATOR) { + let msg = "called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling \ + `.find(..)` instead"; + let filter_snippet = snippet(cx, filter_args[1].span, ".."); + if filter_snippet.lines().count() <= 1 { + let iter_snippet = snippet(cx, filter_args[0].span, ".."); + // add note if not multi-line + span_lint_and_sugg( + cx, + FILTER_NEXT, + expr.span, + msg, + "try this", + format!("{}.find({})", iter_snippet, filter_snippet), + Applicability::MachineApplicable, + ); + } else { + span_lint(cx, FILTER_NEXT, expr.span, msg); + } + } +} diff --git a/clippy_lints/src/methods/get_unwrap.rs b/clippy_lints/src/methods/get_unwrap.rs new file mode 100644 index 0000000000000..2684c50e01b7d --- /dev/null +++ b/clippy_lints/src/methods/get_unwrap.rs @@ -0,0 +1,84 @@ +use crate::methods::derefs_to_slice; +use crate::utils::{ + get_parent_expr, is_type_diagnostic_item, match_type, paths, snippet_with_applicability, span_lint_and_sugg, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::sym; + +use super::GET_UNWRAP; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args: &'tcx [hir::Expr<'_>], is_mut: bool) { + // Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`, + // because they do not implement `IndexMut` + let mut applicability = Applicability::MachineApplicable; + let expr_ty = cx.typeck_results().expr_ty(&get_args[0]); + let get_args_str = if get_args.len() > 1 { + snippet_with_applicability(cx, get_args[1].span, "..", &mut applicability) + } else { + return; // not linting on a .get().unwrap() chain or variant + }; + let mut needs_ref; + let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() { + needs_ref = get_args_str.parse::().is_ok(); + "slice" + } else if is_type_diagnostic_item(cx, expr_ty, sym::vec_type) { + needs_ref = get_args_str.parse::().is_ok(); + "Vec" + } else if is_type_diagnostic_item(cx, expr_ty, sym!(vecdeque_type)) { + needs_ref = get_args_str.parse::().is_ok(); + "VecDeque" + } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym!(hashmap_type)) { + needs_ref = true; + "HashMap" + } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) { + needs_ref = true; + "BTreeMap" + } else { + return; // caller is not a type that we want to lint + }; + + let mut span = expr.span; + + // Handle the case where the result is immediately dereferenced + // by not requiring ref and pulling the dereference into the + // suggestion. + if_chain! { + if needs_ref; + if let Some(parent) = get_parent_expr(cx, expr); + if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind; + then { + needs_ref = false; + span = parent.span; + } + } + + let mut_str = if is_mut { "_mut" } else { "" }; + let borrow_str = if !needs_ref { + "" + } else if is_mut { + "&mut " + } else { + "&" + }; + + span_lint_and_sugg( + cx, + GET_UNWRAP, + span, + &format!( + "called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise", + mut_str, caller_type + ), + "try this", + format!( + "{}{}[{}]", + borrow_str, + snippet_with_applicability(cx, get_args[0].span, "..", &mut applicability), + get_args_str + ), + applicability, + ); +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index e8af9b3d7d912..71080e9bef0c9 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1,14 +1,19 @@ mod bind_instead_of_map; mod bytes_nth; +mod expect_used; mod filter_map_identity; +mod filter_next; +mod get_unwrap; mod implicit_clone; mod inefficient_to_string; mod inspect_for_each; mod iter_count; mod manual_saturating_arithmetic; +mod ok_expect; mod option_map_unwrap_or; mod unnecessary_filter_map; mod unnecessary_lazy_eval; +mod unwrap_used; use std::borrow::Cow; use std::fmt; @@ -1649,15 +1654,15 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let method_names: Vec<&str> = method_names.iter().map(|s| &**s).collect(); match method_names.as_slice() { - ["unwrap", "get"] => lint_get_unwrap(cx, expr, arg_lists[1], false), - ["unwrap", "get_mut"] => lint_get_unwrap(cx, expr, arg_lists[1], true), - ["unwrap", ..] => lint_unwrap(cx, expr, arg_lists[0]), - ["expect", "ok"] => lint_ok_expect(cx, expr, arg_lists[1]), - ["expect", ..] => lint_expect(cx, expr, arg_lists[0]), - ["unwrap_or", "map"] => option_map_unwrap_or::lint(cx, expr, arg_lists[1], arg_lists[0], method_spans[1]), + ["unwrap", "get"] => get_unwrap::check(cx, expr, arg_lists[1], false), + ["unwrap", "get_mut"] => get_unwrap::check(cx, expr, arg_lists[1], true), + ["unwrap", ..] => unwrap_used::check(cx, expr, arg_lists[0]), + ["expect", "ok"] => ok_expect::check(cx, expr, arg_lists[1]), + ["expect", ..] => expect_used::check(cx, expr, arg_lists[0]), + ["unwrap_or", "map"] => option_map_unwrap_or::check(cx, expr, arg_lists[1], arg_lists[0], method_spans[1]), ["unwrap_or_else", "map"] => { if !lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0], self.msrv.as_ref()) { - unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "unwrap_or"); + unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "unwrap_or"); } }, ["map_or", ..] => lint_map_or_none(cx, expr, arg_lists[0]), @@ -1665,15 +1670,15 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let biom_option_linted = bind_instead_of_map::OptionAndThenSome::lint(cx, expr, arg_lists[0]); let biom_result_linted = bind_instead_of_map::ResultAndThenOk::lint(cx, expr, arg_lists[0]); if !biom_option_linted && !biom_result_linted { - unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "and"); + unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "and"); } }, ["or_else", ..] => { if !bind_instead_of_map::ResultOrElseErrInfo::lint(cx, expr, arg_lists[0]) { - unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "or"); + unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "or"); } }, - ["next", "filter"] => lint_filter_next(cx, expr, arg_lists[1]), + ["next", "filter"] => filter_next::check(cx, expr, arg_lists[1]), ["next", "skip_while"] => lint_skip_while_next(cx, expr, arg_lists[1]), ["next", "iter"] => lint_iter_next(cx, expr, arg_lists[1]), ["map", "filter"] => lint_filter_map(cx, expr, false), @@ -1724,9 +1729,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["map", "as_mut"] => { lint_option_as_ref_deref(cx, expr, arg_lists[1], arg_lists[0], true, self.msrv.as_ref()) }, - ["unwrap_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "unwrap_or"), - ["get_or_insert_with", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "get_or_insert"), - ["ok_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "ok_or"), + ["unwrap_or_else", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "unwrap_or"), + ["get_or_insert_with", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "get_or_insert"), + ["ok_or_else", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "ok_or"), ["collect", "map"] => lint_map_collect(cx, expr, arg_lists[1], arg_lists[0]), ["for_each", "inspect"] => inspect_for_each::lint(cx, expr, method_spans[1]), ["to_owned", ..] => implicit_clone::check(cx, expr, sym::ToOwned), @@ -2712,79 +2717,6 @@ fn lint_iter_nth_zero<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_ar } } -fn lint_get_unwrap<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args: &'tcx [hir::Expr<'_>], is_mut: bool) { - // Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`, - // because they do not implement `IndexMut` - let mut applicability = Applicability::MachineApplicable; - let expr_ty = cx.typeck_results().expr_ty(&get_args[0]); - let get_args_str = if get_args.len() > 1 { - snippet_with_applicability(cx, get_args[1].span, "..", &mut applicability) - } else { - return; // not linting on a .get().unwrap() chain or variant - }; - let mut needs_ref; - let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() { - needs_ref = get_args_str.parse::().is_ok(); - "slice" - } else if is_type_diagnostic_item(cx, expr_ty, sym::vec_type) { - needs_ref = get_args_str.parse::().is_ok(); - "Vec" - } else if is_type_diagnostic_item(cx, expr_ty, sym::vecdeque_type) { - needs_ref = get_args_str.parse::().is_ok(); - "VecDeque" - } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::hashmap_type) { - needs_ref = true; - "HashMap" - } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) { - needs_ref = true; - "BTreeMap" - } else { - return; // caller is not a type that we want to lint - }; - - let mut span = expr.span; - - // Handle the case where the result is immediately dereferenced - // by not requiring ref and pulling the dereference into the - // suggestion. - if_chain! { - if needs_ref; - if let Some(parent) = get_parent_expr(cx, expr); - if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind; - then { - needs_ref = false; - span = parent.span; - } - } - - let mut_str = if is_mut { "_mut" } else { "" }; - let borrow_str = if !needs_ref { - "" - } else if is_mut { - "&mut " - } else { - "&" - }; - - span_lint_and_sugg( - cx, - GET_UNWRAP, - span, - &format!( - "called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise", - mut_str, caller_type - ), - "try this", - format!( - "{}{}[{}]", - borrow_str, - snippet_with_applicability(cx, get_args[0].span, "..", &mut applicability), - get_args_str - ), - applicability, - ); -} - fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[hir::Expr<'_>]) { // lint if caller of skip is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { @@ -2843,80 +2775,6 @@ fn derefs_to_slice<'tcx>( } } -/// lint use of `unwrap()` for `Option`s and `Result`s -fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { - let obj_ty = cx.typeck_results().expr_ty(&unwrap_args[0]).peel_refs(); - - let mess = if is_type_diagnostic_item(cx, obj_ty, sym::option_type) { - Some((UNWRAP_USED, "an Option", "None")) - } else if is_type_diagnostic_item(cx, obj_ty, sym::result_type) { - Some((UNWRAP_USED, "a Result", "Err")) - } else { - None - }; - - if let Some((lint, kind, none_value)) = mess { - span_lint_and_help( - cx, - lint, - expr.span, - &format!("used `unwrap()` on `{}` value", kind,), - None, - &format!( - "if you don't want to handle the `{}` case gracefully, consider \ - using `expect()` to provide a better panic message", - none_value, - ), - ); - } -} - -/// lint use of `expect()` for `Option`s and `Result`s -fn lint_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) { - let obj_ty = cx.typeck_results().expr_ty(&expect_args[0]).peel_refs(); - - let mess = if is_type_diagnostic_item(cx, obj_ty, sym::option_type) { - Some((EXPECT_USED, "an Option", "None")) - } else if is_type_diagnostic_item(cx, obj_ty, sym::result_type) { - Some((EXPECT_USED, "a Result", "Err")) - } else { - None - }; - - if let Some((lint, kind, none_value)) = mess { - span_lint_and_help( - cx, - lint, - expr.span, - &format!("used `expect()` on `{}` value", kind,), - None, - &format!("if this value is an `{}`, it will panic", none_value,), - ); - } -} - -/// lint use of `ok().expect()` for `Result`s -fn lint_ok_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) { - if_chain! { - // lint if the caller of `ok()` is a `Result` - if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&ok_args[0]), sym::result_type); - let result_type = cx.typeck_results().expr_ty(&ok_args[0]); - if let Some(error_type) = get_error_type(cx, result_type); - if has_debug_impl(error_type, cx); - - then { - span_lint_and_help( - cx, - OK_EXPECT, - expr.span, - "called `ok().expect()` on a `Result` value", - None, - "you can call `expect()` directly on the `Result`", - ); - } - } -} - /// lint use of `map().flatten()` for `Iterators` and 'Options' fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_args: &'tcx [hir::Expr<'_>]) { // lint if caller of `.map().flatten()` is an Iterator @@ -3107,31 +2965,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -/// lint use of `filter().next()` for `Iterators` -fn lint_filter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) { - // lint if caller of `.filter().next()` is an Iterator - if match_trait_method(cx, expr, &paths::ITERATOR) { - let msg = "called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling \ - `.find(..)` instead"; - let filter_snippet = snippet(cx, filter_args[1].span, ".."); - if filter_snippet.lines().count() <= 1 { - let iter_snippet = snippet(cx, filter_args[0].span, ".."); - // add note if not multi-line - span_lint_and_sugg( - cx, - FILTER_NEXT, - expr.span, - msg, - "try this", - format!("{}.find({})", iter_snippet, filter_snippet), - Applicability::MachineApplicable, - ); - } else { - span_lint(cx, FILTER_NEXT, expr.span, msg); - } - } -} - /// lint use of `skip_while().next()` for `Iterators` fn lint_skip_while_next<'tcx>( cx: &LateContext<'tcx>, @@ -3914,21 +3747,6 @@ fn lint_map_collect( } } -/// Given a `Result` type, return its error type (`E`). -fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option> { - match ty.kind() { - ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::result_type) => substs.types().nth(1), - _ => None, - } -} - -/// This checks whether a given type is known to implement Debug. -fn has_debug_impl<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { - cx.tcx - .get_diagnostic_item(sym::debug_trait) - .map_or(false, |debug| implements_trait(cx, ty, debug, &[])) -} - enum Convention { Eq(&'static str), StartsWith(&'static str), diff --git a/clippy_lints/src/methods/ok_expect.rs b/clippy_lints/src/methods/ok_expect.rs new file mode 100644 index 0000000000000..c1706cc7cc7d2 --- /dev/null +++ b/clippy_lints/src/methods/ok_expect.rs @@ -0,0 +1,45 @@ +use crate::utils::{implements_trait, is_type_diagnostic_item, span_lint_and_help}; +use if_chain::if_chain; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; +use rustc_span::sym; + +use super::OK_EXPECT; + +/// lint use of `ok().expect()` for `Result`s +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) { + if_chain! { + // lint if the caller of `ok()` is a `Result` + if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&ok_args[0]), sym::result_type); + let result_type = cx.typeck_results().expr_ty(&ok_args[0]); + if let Some(error_type) = get_error_type(cx, result_type); + if has_debug_impl(error_type, cx); + + then { + span_lint_and_help( + cx, + OK_EXPECT, + expr.span, + "called `ok().expect()` on a `Result` value", + None, + "you can call `expect()` directly on the `Result`", + ); + } + } +} + +/// Given a `Result` type, return its error type (`E`). +fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option> { + match ty.kind() { + ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::result_type) => substs.types().nth(1), + _ => None, + } +} + +/// This checks whether a given type is known to implement Debug. +fn has_debug_impl<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { + cx.tcx + .get_diagnostic_item(sym::debug_trait) + .map_or(false, |debug| implements_trait(cx, ty, debug, &[])) +} diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index 7763fd5f113fa..7cdd49bbf0307 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -12,7 +12,7 @@ use rustc_span::{sym, Symbol}; use super::MAP_UNWRAP_OR; /// lint use of `map().unwrap_or()` for `Option`s -pub(super) fn lint<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &rustc_hir::Expr<'_>, map_args: &'tcx [rustc_hir::Expr<'_>], diff --git a/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/clippy_lints/src/methods/unnecessary_lazy_eval.rs index 40ccb8c80b342..a17259d697faa 100644 --- a/clippy_lints/src/methods/unnecessary_lazy_eval.rs +++ b/clippy_lints/src/methods/unnecessary_lazy_eval.rs @@ -9,7 +9,7 @@ use super::UNNECESSARY_LAZY_EVALUATIONS; /// lint use of `_else(simple closure)` for `Option`s and `Result`s that can be /// replaced with `(return value of simple closure)` -pub(super) fn lint<'tcx>( +pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, args: &'tcx [hir::Expr<'_>], diff --git a/clippy_lints/src/methods/unwrap_used.rs b/clippy_lints/src/methods/unwrap_used.rs new file mode 100644 index 0000000000000..094c3fc45c493 --- /dev/null +++ b/clippy_lints/src/methods/unwrap_used.rs @@ -0,0 +1,34 @@ +use crate::utils::{is_type_diagnostic_item, span_lint_and_help}; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::sym; + +use super::UNWRAP_USED; + +/// lint use of `unwrap()` for `Option`s and `Result`s +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { + let obj_ty = cx.typeck_results().expr_ty(&unwrap_args[0]).peel_refs(); + + let mess = if is_type_diagnostic_item(cx, obj_ty, sym::option_type) { + Some((UNWRAP_USED, "an Option", "None")) + } else if is_type_diagnostic_item(cx, obj_ty, sym::result_type) { + Some((UNWRAP_USED, "a Result", "Err")) + } else { + None + }; + + if let Some((lint, kind, none_value)) = mess { + span_lint_and_help( + cx, + lint, + expr.span, + &format!("used `unwrap()` on `{}` value", kind,), + None, + &format!( + "if you don't want to handle the `{}` case gracefully, consider \ + using `expect()` to provide a better panic message", + none_value, + ), + ); + } +} From 483bac2dc0a47df87141a98df1d470b25cd2eda3 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 00:31:15 +0900 Subject: [PATCH 180/226] move skip_while_next to its own module --- clippy_lints/src/methods/mod.rs | 22 ++------------------- clippy_lints/src/methods/skip_while_next.rs | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 clippy_lints/src/methods/skip_while_next.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 71080e9bef0c9..34def45a8dd83 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -11,6 +11,7 @@ mod iter_count; mod manual_saturating_arithmetic; mod ok_expect; mod option_map_unwrap_or; +mod skip_while_next; mod unnecessary_filter_map; mod unnecessary_lazy_eval; mod unwrap_used; @@ -1679,7 +1680,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } }, ["next", "filter"] => filter_next::check(cx, expr, arg_lists[1]), - ["next", "skip_while"] => lint_skip_while_next(cx, expr, arg_lists[1]), + ["next", "skip_while"] => skip_while_next::check(cx, expr, arg_lists[1]), ["next", "iter"] => lint_iter_next(cx, expr, arg_lists[1]), ["map", "filter"] => lint_filter_map(cx, expr, false), ["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]), @@ -2965,25 +2966,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -/// lint use of `skip_while().next()` for `Iterators` -fn lint_skip_while_next<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - _skip_while_args: &'tcx [hir::Expr<'_>], -) { - // lint if caller of `.skip_while().next()` is an Iterator - if match_trait_method(cx, expr, &paths::ITERATOR) { - span_lint_and_help( - cx, - SKIP_WHILE_NEXT, - expr.span, - "called `skip_while(

).next()` on an `Iterator`", - None, - "this is more succinctly expressed by calling `.find(!

)` instead", - ); - } -} - /// lint use of `filter().map()` or `find().map()` for `Iterators` fn lint_filter_map<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, is_find: bool) { if_chain! { diff --git a/clippy_lints/src/methods/skip_while_next.rs b/clippy_lints/src/methods/skip_while_next.rs new file mode 100644 index 0000000000000..8ba6ae952003e --- /dev/null +++ b/clippy_lints/src/methods/skip_while_next.rs @@ -0,0 +1,20 @@ +use crate::utils::{match_trait_method, paths, span_lint_and_help}; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::SKIP_WHILE_NEXT; + +/// lint use of `skip_while().next()` for `Iterators` +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, _skip_while_args: &'tcx [hir::Expr<'_>]) { + // lint if caller of `.skip_while().next()` is an Iterator + if match_trait_method(cx, expr, &paths::ITERATOR) { + span_lint_and_help( + cx, + SKIP_WHILE_NEXT, + expr.span, + "called `skip_while(

).next()` on an `Iterator`", + None, + "this is more succinctly expressed by calling `.find(!

)` instead", + ); + } +} From 110dac7f58257a0186daf13688aa8b02fba67bdb Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 00:43:27 +0900 Subject: [PATCH 181/226] move option_as_ref_deref to its own module --- clippy_lints/src/methods/mod.rs | 114 +--------------- .../src/methods/option_as_ref_deref.rs | 122 ++++++++++++++++++ 2 files changed, 125 insertions(+), 111 deletions(-) create mode 100644 clippy_lints/src/methods/option_as_ref_deref.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 34def45a8dd83..c6b6ef34bc442 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -10,6 +10,7 @@ mod inspect_for_each; mod iter_count; mod manual_saturating_arithmetic; mod ok_expect; +mod option_as_ref_deref; mod option_map_unwrap_or; mod skip_while_next; mod unnecessary_filter_map; @@ -1725,10 +1726,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods { }, ["is_file", ..] => lint_filetype_is_file(cx, expr, arg_lists[0]), ["map", "as_ref"] => { - lint_option_as_ref_deref(cx, expr, arg_lists[1], arg_lists[0], false, self.msrv.as_ref()) + option_as_ref_deref::check(cx, expr, arg_lists[1], arg_lists[0], false, self.msrv.as_ref()) }, ["map", "as_mut"] => { - lint_option_as_ref_deref(cx, expr, arg_lists[1], arg_lists[0], true, self.msrv.as_ref()) + option_as_ref_deref::check(cx, expr, arg_lists[1], arg_lists[0], true, self.msrv.as_ref()) }, ["unwrap_or_else", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "unwrap_or"), ["get_or_insert_with", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "get_or_insert"), @@ -3584,115 +3585,6 @@ fn lint_suspicious_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) { ); } -const OPTION_AS_REF_DEREF_MSRV: RustcVersion = RustcVersion::new(1, 40, 0); - -/// lint use of `_.as_ref().map(Deref::deref)` for `Option`s -fn lint_option_as_ref_deref<'tcx>( - cx: &LateContext<'tcx>, - expr: &hir::Expr<'_>, - as_ref_args: &[hir::Expr<'_>], - map_args: &[hir::Expr<'_>], - is_mut: bool, - msrv: Option<&RustcVersion>, -) { - if !meets_msrv(msrv, &OPTION_AS_REF_DEREF_MSRV) { - return; - } - - let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not); - - let option_ty = cx.typeck_results().expr_ty(&as_ref_args[0]); - if !is_type_diagnostic_item(cx, option_ty, sym::option_type) { - return; - } - - let deref_aliases: [&[&str]; 9] = [ - &paths::DEREF_TRAIT_METHOD, - &paths::DEREF_MUT_TRAIT_METHOD, - &paths::CSTRING_AS_C_STR, - &paths::OS_STRING_AS_OS_STR, - &paths::PATH_BUF_AS_PATH, - &paths::STRING_AS_STR, - &paths::STRING_AS_MUT_STR, - &paths::VEC_AS_SLICE, - &paths::VEC_AS_MUT_SLICE, - ]; - - let is_deref = match map_args[1].kind { - hir::ExprKind::Path(ref expr_qpath) => cx - .qpath_res(expr_qpath, map_args[1].hir_id) - .opt_def_id() - .map_or(false, |fun_def_id| { - deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path)) - }), - hir::ExprKind::Closure(_, _, body_id, _, _) => { - let closure_body = cx.tcx.hir().body(body_id); - let closure_expr = remove_blocks(&closure_body.value); - - match &closure_expr.kind { - hir::ExprKind::MethodCall(_, _, args, _) => { - if_chain! { - if args.len() == 1; - if path_to_local_id(&args[0], closure_body.params[0].pat.hir_id); - let adj = cx - .typeck_results() - .expr_adjustments(&args[0]) - .iter() - .map(|x| &x.kind) - .collect::>(); - if let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj; - then { - let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap(); - deref_aliases.iter().any(|path| match_def_path(cx, method_did, path)) - } else { - false - } - } - }, - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, m, ref inner) if same_mutability(m) => { - if_chain! { - if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner1) = inner.kind; - if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner2) = inner1.kind; - then { - path_to_local_id(inner2, closure_body.params[0].pat.hir_id) - } else { - false - } - } - }, - _ => false, - } - }, - _ => false, - }; - - if is_deref { - let current_method = if is_mut { - format!(".as_mut().map({})", snippet(cx, map_args[1].span, "..")) - } else { - format!(".as_ref().map({})", snippet(cx, map_args[1].span, "..")) - }; - let method_hint = if is_mut { "as_deref_mut" } else { "as_deref" }; - let hint = format!("{}.{}()", snippet(cx, as_ref_args[0].span, ".."), method_hint); - let suggestion = format!("try using {} instead", method_hint); - - let msg = format!( - "called `{0}` on an Option value. This can be done more directly \ - by calling `{1}` instead", - current_method, hint - ); - span_lint_and_sugg( - cx, - OPTION_AS_REF_DEREF, - expr.span, - &msg, - &suggestion, - hint, - Applicability::MachineApplicable, - ); - } -} - fn lint_map_collect( cx: &LateContext<'_>, expr: &hir::Expr<'_>, diff --git a/clippy_lints/src/methods/option_as_ref_deref.rs b/clippy_lints/src/methods/option_as_ref_deref.rs new file mode 100644 index 0000000000000..89067dbfe0e51 --- /dev/null +++ b/clippy_lints/src/methods/option_as_ref_deref.rs @@ -0,0 +1,122 @@ +use crate::utils::{ + is_type_diagnostic_item, match_def_path, meets_msrv, path_to_local_id, paths, remove_blocks, snippet, + span_lint_and_sugg, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_semver::RustcVersion; +use rustc_span::sym; + +use super::OPTION_AS_REF_DEREF; + +const OPTION_AS_REF_DEREF_MSRV: RustcVersion = RustcVersion::new(1, 40, 0); + +/// lint use of `_.as_ref().map(Deref::deref)` for `Option`s +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &hir::Expr<'_>, + as_ref_args: &[hir::Expr<'_>], + map_args: &[hir::Expr<'_>], + is_mut: bool, + msrv: Option<&RustcVersion>, +) { + if !meets_msrv(msrv, &OPTION_AS_REF_DEREF_MSRV) { + return; + } + + let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not); + + let option_ty = cx.typeck_results().expr_ty(&as_ref_args[0]); + if !is_type_diagnostic_item(cx, option_ty, sym::option_type) { + return; + } + + let deref_aliases: [&[&str]; 9] = [ + &paths::DEREF_TRAIT_METHOD, + &paths::DEREF_MUT_TRAIT_METHOD, + &paths::CSTRING_AS_C_STR, + &paths::OS_STRING_AS_OS_STR, + &paths::PATH_BUF_AS_PATH, + &paths::STRING_AS_STR, + &paths::STRING_AS_MUT_STR, + &paths::VEC_AS_SLICE, + &paths::VEC_AS_MUT_SLICE, + ]; + + let is_deref = match map_args[1].kind { + hir::ExprKind::Path(ref expr_qpath) => cx + .qpath_res(expr_qpath, map_args[1].hir_id) + .opt_def_id() + .map_or(false, |fun_def_id| { + deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path)) + }), + hir::ExprKind::Closure(_, _, body_id, _, _) => { + let closure_body = cx.tcx.hir().body(body_id); + let closure_expr = remove_blocks(&closure_body.value); + + match &closure_expr.kind { + hir::ExprKind::MethodCall(_, _, args, _) => { + if_chain! { + if args.len() == 1; + if path_to_local_id(&args[0], closure_body.params[0].pat.hir_id); + let adj = cx + .typeck_results() + .expr_adjustments(&args[0]) + .iter() + .map(|x| &x.kind) + .collect::>(); + if let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj; + then { + let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap(); + deref_aliases.iter().any(|path| match_def_path(cx, method_did, path)) + } else { + false + } + } + }, + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, m, ref inner) if same_mutability(m) => { + if_chain! { + if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner1) = inner.kind; + if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner2) = inner1.kind; + then { + path_to_local_id(inner2, closure_body.params[0].pat.hir_id) + } else { + false + } + } + }, + _ => false, + } + }, + _ => false, + }; + + if is_deref { + let current_method = if is_mut { + format!(".as_mut().map({})", snippet(cx, map_args[1].span, "..")) + } else { + format!(".as_ref().map({})", snippet(cx, map_args[1].span, "..")) + }; + let method_hint = if is_mut { "as_deref_mut" } else { "as_deref" }; + let hint = format!("{}.{}()", snippet(cx, as_ref_args[0].span, ".."), method_hint); + let suggestion = format!("try using {} instead", method_hint); + + let msg = format!( + "called `{0}` on an Option value. This can be done more directly \ + by calling `{1}` instead", + current_method, hint + ); + span_lint_and_sugg( + cx, + OPTION_AS_REF_DEREF, + expr.span, + &msg, + &suggestion, + hint, + Applicability::MachineApplicable, + ); + } +} From 60a053725e5c5c3a78e3d0918ca00e9e98324a95 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 00:48:21 +0900 Subject: [PATCH 182/226] move suspicious_map to its own module --- clippy_lints/src/methods/mod.rs | 14 ++------------ clippy_lints/src/methods/suspicious_map.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 clippy_lints/src/methods/suspicious_map.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c6b6ef34bc442..a807afb605119 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -13,6 +13,7 @@ mod ok_expect; mod option_as_ref_deref; mod option_map_unwrap_or; mod skip_while_next; +mod suspicious_map; mod unnecessary_filter_map; mod unnecessary_lazy_eval; mod unwrap_used; @@ -1716,7 +1717,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { unnecessary_filter_map::lint(cx, expr, arg_lists[0]); filter_map_identity::check(cx, expr, arg_lists[0], method_spans[0]); }, - ["count", "map"] => lint_suspicious_map(cx, expr), + ["count", "map"] => suspicious_map::check(cx, expr), ["assume_init"] => lint_maybe_uninit(cx, &arg_lists[0][0], expr), ["unwrap_or", arith @ ("checked_add" | "checked_sub" | "checked_mul")] => { manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..]) @@ -3574,17 +3575,6 @@ fn is_maybe_uninit_ty_valid(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { } } -fn lint_suspicious_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) { - span_lint_and_help( - cx, - SUSPICIOUS_MAP, - expr.span, - "this call to `map()` won't have an effect on the call to `count()`", - None, - "make sure you did not confuse `map` with `filter` or `for_each`", - ); -} - fn lint_map_collect( cx: &LateContext<'_>, expr: &hir::Expr<'_>, diff --git a/clippy_lints/src/methods/suspicious_map.rs b/clippy_lints/src/methods/suspicious_map.rs new file mode 100644 index 0000000000000..e135a826dc4d0 --- /dev/null +++ b/clippy_lints/src/methods/suspicious_map.rs @@ -0,0 +1,16 @@ +use crate::utils::span_lint_and_help; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::SUSPICIOUS_MAP; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>) { + span_lint_and_help( + cx, + SUSPICIOUS_MAP, + expr.span, + "this call to `map()` won't have an effect on the call to `count()`", + None, + "make sure you did not confuse `map` with `filter` or `for_each`", + ); +} From 8623b331eebfa097bb33dff1df5efa324e6a780a Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 00:55:19 +0900 Subject: [PATCH 183/226] move filetype_is_file to its own module --- clippy_lints/src/methods/filetype_is_file.rs | 39 ++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 35 +----------------- 2 files changed, 41 insertions(+), 33 deletions(-) create mode 100644 clippy_lints/src/methods/filetype_is_file.rs diff --git a/clippy_lints/src/methods/filetype_is_file.rs b/clippy_lints/src/methods/filetype_is_file.rs new file mode 100644 index 0000000000000..b03835f97e634 --- /dev/null +++ b/clippy_lints/src/methods/filetype_is_file.rs @@ -0,0 +1,39 @@ +use crate::utils::{get_parent_expr, match_type, paths, span_lint_and_help}; +use if_chain::if_chain; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::source_map::Span; + +use super::FILETYPE_IS_FILE; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { + let ty = cx.typeck_results().expr_ty(&args[0]); + + if !match_type(cx, ty, &paths::FILE_TYPE) { + return; + } + + let span: Span; + let verb: &str; + let lint_unary: &str; + let help_unary: &str; + if_chain! { + if let Some(parent) = get_parent_expr(cx, expr); + if let hir::ExprKind::Unary(op, _) = parent.kind; + if op == hir::UnOp::Not; + then { + lint_unary = "!"; + verb = "denies"; + help_unary = ""; + span = parent.span; + } else { + lint_unary = ""; + verb = "covers"; + help_unary = "!"; + span = expr.span; + } + } + let lint_msg = format!("`{}FileType::is_file()` only {} regular files", lint_unary, verb); + let help_msg = format!("use `{}FileType::is_dir()` instead", help_unary); + span_lint_and_help(cx, FILETYPE_IS_FILE, span, &lint_msg, None, &help_msg); +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index a807afb605119..54a6a4cf93417 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1,6 +1,7 @@ mod bind_instead_of_map; mod bytes_nth; mod expect_used; +mod filetype_is_file; mod filter_map_identity; mod filter_next; mod get_unwrap; @@ -1725,7 +1726,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub"] => { check_pointer_offset(cx, expr, arg_lists[0]) }, - ["is_file", ..] => lint_filetype_is_file(cx, expr, arg_lists[0]), + ["is_file", ..] => filetype_is_file::check(cx, expr, arg_lists[0]), ["map", "as_ref"] => { option_as_ref_deref::check(cx, expr, arg_lists[1], arg_lists[0], false, self.msrv.as_ref()) }, @@ -3859,38 +3860,6 @@ fn check_pointer_offset(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir: } } -fn lint_filetype_is_file(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let ty = cx.typeck_results().expr_ty(&args[0]); - - if !match_type(cx, ty, &paths::FILE_TYPE) { - return; - } - - let span: Span; - let verb: &str; - let lint_unary: &str; - let help_unary: &str; - if_chain! { - if let Some(parent) = get_parent_expr(cx, expr); - if let hir::ExprKind::Unary(op, _) = parent.kind; - if op == hir::UnOp::Not; - then { - lint_unary = "!"; - verb = "denies"; - help_unary = ""; - span = parent.span; - } else { - lint_unary = ""; - verb = "covers"; - help_unary = "!"; - span = expr.span; - } - } - let lint_msg = format!("`{}FileType::is_file()` only {} regular files", lint_unary, verb); - let help_msg = format!("use `{}FileType::is_dir()` instead", help_unary); - span_lint_and_help(cx, FILETYPE_IS_FILE, span, &lint_msg, None, &help_msg); -} - fn lint_from_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let ty = cx.typeck_results().expr_ty(expr); let arg_ty = cx.typeck_results().expr_ty(&args[0]); From 35147d4cf342ee479d50afcb70aceab4ea506c2d Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 01:03:47 +0900 Subject: [PATCH 184/226] move uninit_assumed_init to its own module --- clippy_lints/src/methods/mod.rs | 31 ++-------------- .../src/methods/uninit_assumed_init.rs | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 clippy_lints/src/methods/uninit_assumed_init.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 54a6a4cf93417..acb8318970ec5 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -15,6 +15,7 @@ mod option_as_ref_deref; mod option_map_unwrap_or; mod skip_while_next; mod suspicious_map; +mod uninit_assumed_init; mod unnecessary_filter_map; mod unnecessary_lazy_eval; mod unwrap_used; @@ -1719,7 +1720,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { filter_map_identity::check(cx, expr, arg_lists[0], method_spans[0]); }, ["count", "map"] => suspicious_map::check(cx, expr), - ["assume_init"] => lint_maybe_uninit(cx, &arg_lists[0][0], expr), + ["assume_init"] => uninit_assumed_init::check(cx, &arg_lists[0][0], expr), ["unwrap_or", arith @ ("checked_add" | "checked_sub" | "checked_mul")] => { manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..]) }, @@ -3548,34 +3549,6 @@ fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_ } } -/// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter) -fn lint_maybe_uninit(cx: &LateContext<'_>, expr: &hir::Expr<'_>, outer: &hir::Expr<'_>) { - if_chain! { - if let hir::ExprKind::Call(ref callee, ref args) = expr.kind; - if args.is_empty(); - if let hir::ExprKind::Path(ref path) = callee.kind; - if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT); - if !is_maybe_uninit_ty_valid(cx, cx.typeck_results().expr_ty_adjusted(outer)); - then { - span_lint( - cx, - UNINIT_ASSUMED_INIT, - outer.span, - "this call for this type may be undefined behavior" - ); - } - } -} - -fn is_maybe_uninit_ty_valid(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - match ty.kind() { - ty::Array(ref component, _) => is_maybe_uninit_ty_valid(cx, component), - ty::Tuple(ref types) => types.types().all(|ty| is_maybe_uninit_ty_valid(cx, ty)), - ty::Adt(ref adt, _) => match_def_path(cx, adt.did, &paths::MEM_MAYBEUNINIT), - _ => false, - } -} - fn lint_map_collect( cx: &LateContext<'_>, expr: &hir::Expr<'_>, diff --git a/clippy_lints/src/methods/uninit_assumed_init.rs b/clippy_lints/src/methods/uninit_assumed_init.rs new file mode 100644 index 0000000000000..798b66192c818 --- /dev/null +++ b/clippy_lints/src/methods/uninit_assumed_init.rs @@ -0,0 +1,35 @@ +use crate::utils::{match_def_path, match_qpath, paths, span_lint}; +use if_chain::if_chain; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; + +use super::UNINIT_ASSUMED_INIT; + +/// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter) +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, outer: &hir::Expr<'_>) { + if_chain! { + if let hir::ExprKind::Call(ref callee, ref args) = expr.kind; + if args.is_empty(); + if let hir::ExprKind::Path(ref path) = callee.kind; + if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT); + if !is_maybe_uninit_ty_valid(cx, cx.typeck_results().expr_ty_adjusted(outer)); + then { + span_lint( + cx, + UNINIT_ASSUMED_INIT, + outer.span, + "this call for this type may be undefined behavior" + ); + } + } +} + +fn is_maybe_uninit_ty_valid(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { + match ty.kind() { + ty::Array(ref component, _) => is_maybe_uninit_ty_valid(cx, component), + ty::Tuple(ref types) => types.types().all(|ty| is_maybe_uninit_ty_valid(cx, ty)), + ty::Adt(ref adt, _) => match_def_path(cx, adt.did, &paths::MEM_MAYBEUNINIT), + _ => false, + } +} From 45ee914df0c1d1a6a15272bd6833023dd4185b9b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 01:09:33 +0900 Subject: [PATCH 185/226] move iter_cloned_collect to its own module --- .../src/methods/iter_cloned_collect.rs | 30 +++++++++++++++++++ clippy_lints/src/methods/mod.rs | 24 ++------------- 2 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 clippy_lints/src/methods/iter_cloned_collect.rs diff --git a/clippy_lints/src/methods/iter_cloned_collect.rs b/clippy_lints/src/methods/iter_cloned_collect.rs new file mode 100644 index 0000000000000..c3e48ffa5fae4 --- /dev/null +++ b/clippy_lints/src/methods/iter_cloned_collect.rs @@ -0,0 +1,30 @@ +use crate::methods::derefs_to_slice; +use crate::utils::{is_type_diagnostic_item, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::sym; + +use super::ITER_CLONED_COLLECT; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) { + if_chain! { + if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::vec_type); + if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])); + if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite()); + + then { + span_lint_and_sugg( + cx, + ITER_CLONED_COLLECT, + to_replace, + "called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \ + more readable", + "try", + ".to_vec()".to_string(), + Applicability::MachineApplicable, + ); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index acb8318970ec5..92d8077c1ab2d 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -8,6 +8,7 @@ mod get_unwrap; mod implicit_clone; mod inefficient_to_string; mod inspect_for_each; +mod iter_cloned_collect; mod iter_count; mod manual_saturating_arithmetic; mod ok_expect; @@ -1711,7 +1712,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]), ["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]), ["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]), - ["collect", "cloned"] => lint_iter_cloned_collect(cx, expr, arg_lists[1]), + ["collect", "cloned"] => iter_cloned_collect::check(cx, expr, arg_lists[1]), ["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]), ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]), ["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0], method_spans[0]), @@ -2494,27 +2495,6 @@ fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_> } } -fn lint_iter_cloned_collect<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) { - if_chain! { - if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::vec_type); - if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])); - if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite()); - - then { - span_lint_and_sugg( - cx, - ITER_CLONED_COLLECT, - to_replace, - "called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \ - more readable", - "try", - ".to_vec()".to_string(), - Applicability::MachineApplicable, - ); - } - } -} - fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) { fn check_fold_with_op( cx: &LateContext<'_>, From 6376da70be18d6cb9dbe22b5a661896cf916bc51 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 3 Mar 2021 01:16:16 +0900 Subject: [PATCH 186/226] replace `lints` and `lint` with `check` --- .../src/methods/bind_instead_of_map.rs | 2 +- clippy_lints/src/methods/bytes_nth.rs | 2 +- .../src/methods/inefficient_to_string.rs | 2 +- clippy_lints/src/methods/inspect_for_each.rs | 2 +- clippy_lints/src/methods/iter_count.rs | 2 +- .../methods/manual_saturating_arithmetic.rs | 2 +- clippy_lints/src/methods/mod.rs | 22 +++++++++---------- .../src/methods/unnecessary_filter_map.rs | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/clippy_lints/src/methods/bind_instead_of_map.rs b/clippy_lints/src/methods/bind_instead_of_map.rs index 540a1484a8558..5decb81d9f2e2 100644 --- a/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/clippy_lints/src/methods/bind_instead_of_map.rs @@ -158,7 +158,7 @@ pub(crate) trait BindInsteadOfMap { } /// Lint use of `_.and_then(|x| Some(y))` for `Option`s - fn lint(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) -> bool { + fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) -> bool { if !match_type(cx, cx.typeck_results().expr_ty(&args[0]), Self::TYPE_QPATH) { return false; } diff --git a/clippy_lints/src/methods/bytes_nth.rs b/clippy_lints/src/methods/bytes_nth.rs index defc50ede2243..71a7e195e41ce 100644 --- a/clippy_lints/src/methods/bytes_nth.rs +++ b/clippy_lints/src/methods/bytes_nth.rs @@ -7,7 +7,7 @@ use rustc_span::sym; use super::BYTES_NTH; -pub(super) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>]) { +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>]) { if_chain! { if let ExprKind::MethodCall(_, _, ref args, _) = expr.kind; let ty = cx.typeck_results().expr_ty(&iter_args[0]).peel_refs(); diff --git a/clippy_lints/src/methods/inefficient_to_string.rs b/clippy_lints/src/methods/inefficient_to_string.rs index c83b6f2c32963..3045b09c2389f 100644 --- a/clippy_lints/src/methods/inefficient_to_string.rs +++ b/clippy_lints/src/methods/inefficient_to_string.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::{self, Ty}; use rustc_span::sym; /// Checks for the `INEFFICIENT_TO_STRING` lint -pub fn lint<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) { +pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) { if_chain! { if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD); diff --git a/clippy_lints/src/methods/inspect_for_each.rs b/clippy_lints/src/methods/inspect_for_each.rs index 6d41ee38a2767..959457a5bfc96 100644 --- a/clippy_lints/src/methods/inspect_for_each.rs +++ b/clippy_lints/src/methods/inspect_for_each.rs @@ -7,7 +7,7 @@ use crate::utils::{match_trait_method, paths, span_lint_and_help}; use super::INSPECT_FOR_EACH; /// lint use of `inspect().for_each()` for `Iterators` -pub(super) fn lint<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, inspect_span: Span) { +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, inspect_span: Span) { if match_trait_method(cx, expr, &paths::ITERATOR) { let msg = "called `inspect(..).for_each(..)` on an `Iterator`"; let hint = "move the code from `inspect(..)` to `for_each(..)` and remove the `inspect(..)`"; diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index 71d65a01d3e85..869440e0165b2 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -8,7 +8,7 @@ use rustc_span::sym; use super::ITER_COUNT; -pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], iter_method: &str) { +pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], iter_method: &str) { let ty = cx.typeck_results().expr_ty(&iter_args[0]); let caller_type = if derefs_to_slice(cx, &iter_args[0], ty).is_some() { "slice" diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index eaa604c2ae63e..0b414e0eb9567 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -6,7 +6,7 @@ use rustc_hir as hir; use rustc_lint::LateContext; use rustc_target::abi::LayoutOf; -pub fn lint(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[&[hir::Expr<'_>]], arith: &str) { +pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[&[hir::Expr<'_>]], arith: &str) { let unwrap_arg = &args[0][1]; let arith_lhs = &args[1][0]; let arith_rhs = &args[1][1]; diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 92d8077c1ab2d..639d013f786cd 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1673,14 +1673,14 @@ impl<'tcx> LateLintPass<'tcx> for Methods { }, ["map_or", ..] => lint_map_or_none(cx, expr, arg_lists[0]), ["and_then", ..] => { - let biom_option_linted = bind_instead_of_map::OptionAndThenSome::lint(cx, expr, arg_lists[0]); - let biom_result_linted = bind_instead_of_map::ResultAndThenOk::lint(cx, expr, arg_lists[0]); + let biom_option_linted = bind_instead_of_map::OptionAndThenSome::check(cx, expr, arg_lists[0]); + let biom_result_linted = bind_instead_of_map::ResultAndThenOk::check(cx, expr, arg_lists[0]); if !biom_option_linted && !biom_result_linted { unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "and"); } }, ["or_else", ..] => { - if !bind_instead_of_map::ResultOrElseErrInfo::lint(cx, expr, arg_lists[0]) { + if !bind_instead_of_map::ResultOrElseErrInfo::check(cx, expr, arg_lists[0]) { unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "or"); } }, @@ -1703,12 +1703,12 @@ impl<'tcx> LateLintPass<'tcx> for Methods { lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) }, ["extend", ..] => lint_extend(cx, expr, arg_lists[0]), - ["count", "into_iter"] => iter_count::lints(cx, expr, &arg_lists[1], "into_iter"), - ["count", "iter"] => iter_count::lints(cx, expr, &arg_lists[1], "iter"), - ["count", "iter_mut"] => iter_count::lints(cx, expr, &arg_lists[1], "iter_mut"), + ["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"), + ["count", "iter"] => iter_count::check(cx, expr, &arg_lists[1], "iter"), + ["count", "iter_mut"] => iter_count::check(cx, expr, &arg_lists[1], "iter_mut"), ["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false), ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true), - ["nth", "bytes"] => bytes_nth::lints(cx, expr, &arg_lists[1]), + ["nth", "bytes"] => bytes_nth::check(cx, expr, &arg_lists[1]), ["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]), ["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]), ["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]), @@ -1717,13 +1717,13 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]), ["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0], method_spans[0]), ["filter_map", ..] => { - unnecessary_filter_map::lint(cx, expr, arg_lists[0]); + unnecessary_filter_map::check(cx, expr, arg_lists[0]); filter_map_identity::check(cx, expr, arg_lists[0], method_spans[0]); }, ["count", "map"] => suspicious_map::check(cx, expr), ["assume_init"] => uninit_assumed_init::check(cx, &arg_lists[0][0], expr), ["unwrap_or", arith @ ("checked_add" | "checked_sub" | "checked_mul")] => { - manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..]) + manual_saturating_arithmetic::check(cx, expr, &arg_lists, &arith["checked_".len()..]) }, ["add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub"] => { check_pointer_offset(cx, expr, arg_lists[0]) @@ -1739,7 +1739,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["get_or_insert_with", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "get_or_insert"), ["ok_or_else", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "ok_or"), ["collect", "map"] => lint_map_collect(cx, expr, arg_lists[1], arg_lists[0]), - ["for_each", "inspect"] => inspect_for_each::lint(cx, expr, method_spans[1]), + ["for_each", "inspect"] => inspect_for_each::check(cx, expr, method_spans[1]), ["to_owned", ..] => implicit_clone::check(cx, expr, sym::ToOwned), ["to_os_string", ..] => implicit_clone::check(cx, expr, sym::OsStr), ["to_path_buf", ..] => implicit_clone::check(cx, expr, sym::Path), @@ -1765,7 +1765,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { lint_clone_on_ref_ptr(cx, expr, &args[0]); } if args.len() == 1 && method_call.ident.name == sym!(to_string) { - inefficient_to_string::lint(cx, expr, &args[0], self_ty); + inefficient_to_string::check(cx, expr, &args[0], self_ty); } if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 5691fcb88e95c..12b2cf0a16582 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -9,7 +9,7 @@ use if_chain::if_chain; use super::UNNECESSARY_FILTER_MAP; -pub(super) fn lint(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { if !match_trait_method(cx, expr, &paths::ITERATOR) { return; } From 9b0a42b67d66cb79bdd09379d0b0e7959fc1505a Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 4 Mar 2021 19:46:44 +0900 Subject: [PATCH 187/226] move zst_offset to its own module --- clippy_lints/src/methods/mod.rs | 15 ++------------- clippy_lints/src/methods/zst_offset.rs | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 clippy_lints/src/methods/zst_offset.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 639d013f786cd..c944568dc6194 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -20,6 +20,7 @@ mod uninit_assumed_init; mod unnecessary_filter_map; mod unnecessary_lazy_eval; mod unwrap_used; +mod zst_offset; use std::borrow::Cow; use std::fmt; @@ -1726,7 +1727,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { manual_saturating_arithmetic::check(cx, expr, &arg_lists, &arith["checked_".len()..]) }, ["add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub"] => { - check_pointer_offset(cx, expr, arg_lists[0]) + zst_offset::check(cx, expr, arg_lists[0]) }, ["is_file", ..] => filetype_is_file::check(cx, expr, arg_lists[0]), ["map", "as_ref"] => { @@ -3801,18 +3802,6 @@ fn is_bool(ty: &hir::Ty<'_>) -> bool { } } -fn check_pointer_offset(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - if_chain! { - if args.len() == 2; - if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.typeck_results().expr_ty(&args[0]).kind(); - if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)); - if layout.is_zst(); - then { - span_lint(cx, ZST_OFFSET, expr.span, "offset calculation on zero-sized value"); - } - } -} - fn lint_from_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let ty = cx.typeck_results().expr_ty(expr); let arg_ty = cx.typeck_results().expr_ty(&args[0]); diff --git a/clippy_lints/src/methods/zst_offset.rs b/clippy_lints/src/methods/zst_offset.rs new file mode 100644 index 0000000000000..f1335726736ca --- /dev/null +++ b/clippy_lints/src/methods/zst_offset.rs @@ -0,0 +1,19 @@ +use crate::utils::span_lint; +use if_chain::if_chain; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; + +use super::ZST_OFFSET; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { + if_chain! { + if args.len() == 2; + if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.typeck_results().expr_ty(&args[0]).kind(); + if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)); + if layout.is_zst(); + then { + span_lint(cx, ZST_OFFSET, expr.span, "offset calculation on zero-sized value"); + } + } +} From db91d9cf9a620cc258ab84a152a9333351ac166e Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 4 Mar 2021 19:47:06 +0900 Subject: [PATCH 188/226] move map_collect_result_unit to its own module --- .../src/methods/map_collect_result_unit.rs | 45 +++++++++++++++++++ clippy_lints/src/methods/mod.rs | 39 +--------------- 2 files changed, 47 insertions(+), 37 deletions(-) create mode 100644 clippy_lints/src/methods/map_collect_result_unit.rs diff --git a/clippy_lints/src/methods/map_collect_result_unit.rs b/clippy_lints/src/methods/map_collect_result_unit.rs new file mode 100644 index 0000000000000..5b20e268d9f7e --- /dev/null +++ b/clippy_lints/src/methods/map_collect_result_unit.rs @@ -0,0 +1,45 @@ +use crate::utils::{is_type_diagnostic_item, match_trait_method, paths, snippet, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::symbol::sym; + +use super::MAP_COLLECT_RESULT_UNIT; + +pub(super) fn check( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + map_args: &[hir::Expr<'_>], + collect_args: &[hir::Expr<'_>], +) { + if_chain! { + // called on Iterator + if let [map_expr] = collect_args; + if match_trait_method(cx, map_expr, &paths::ITERATOR); + // return of collect `Result<(),_>` + let collect_ret_ty = cx.typeck_results().expr_ty(expr); + if is_type_diagnostic_item(cx, collect_ret_ty, sym::result_type); + if let ty::Adt(_, substs) = collect_ret_ty.kind(); + if let Some(result_t) = substs.types().next(); + if result_t.is_unit(); + // get parts for snippet + if let [iter, map_fn] = map_args; + then { + span_lint_and_sugg( + cx, + MAP_COLLECT_RESULT_UNIT, + expr.span, + "`.map().collect()` can be replaced with `.try_for_each()`", + "try this", + format!( + "{}.try_for_each({})", + snippet(cx, iter.span, ".."), + snippet(cx, map_fn.span, "..") + ), + Applicability::MachineApplicable, + ); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c944568dc6194..baa342ab3bb8c 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -11,6 +11,7 @@ mod inspect_for_each; mod iter_cloned_collect; mod iter_count; mod manual_saturating_arithmetic; +mod map_collect_result_unit; mod ok_expect; mod option_as_ref_deref; mod option_map_unwrap_or; @@ -1739,7 +1740,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["unwrap_or_else", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "unwrap_or"), ["get_or_insert_with", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "get_or_insert"), ["ok_or_else", ..] => unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "ok_or"), - ["collect", "map"] => lint_map_collect(cx, expr, arg_lists[1], arg_lists[0]), + ["collect", "map"] => map_collect_result_unit::check(cx, expr, arg_lists[1], arg_lists[0]), ["for_each", "inspect"] => inspect_for_each::check(cx, expr, method_spans[1]), ["to_owned", ..] => implicit_clone::check(cx, expr, sym::ToOwned), ["to_os_string", ..] => implicit_clone::check(cx, expr, sym::OsStr), @@ -3530,42 +3531,6 @@ fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_ } } -fn lint_map_collect( - cx: &LateContext<'_>, - expr: &hir::Expr<'_>, - map_args: &[hir::Expr<'_>], - collect_args: &[hir::Expr<'_>], -) { - if_chain! { - // called on Iterator - if let [map_expr] = collect_args; - if match_trait_method(cx, map_expr, &paths::ITERATOR); - // return of collect `Result<(),_>` - let collect_ret_ty = cx.typeck_results().expr_ty(expr); - if is_type_diagnostic_item(cx, collect_ret_ty, sym::result_type); - if let ty::Adt(_, substs) = collect_ret_ty.kind(); - if let Some(result_t) = substs.types().next(); - if result_t.is_unit(); - // get parts for snippet - if let [iter, map_fn] = map_args; - then { - span_lint_and_sugg( - cx, - MAP_COLLECT_RESULT_UNIT, - expr.span, - "`.map().collect()` can be replaced with `.try_for_each()`", - "try this", - format!( - "{}.try_for_each({})", - snippet(cx, iter.span, ".."), - snippet(cx, map_fn.span, "..") - ), - Applicability::MachineApplicable, - ); - } - } -} - enum Convention { Eq(&'static str), StartsWith(&'static str), From 3fe099ba8d2f6f4d085e7480f020f9f87e6b39e8 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 4 Mar 2021 22:50:53 +0900 Subject: [PATCH 189/226] move iter_next_slice to its own module --- clippy_lints/src/methods/iter_next_slice.rs | 68 +++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 66 ++------------------ 2 files changed, 73 insertions(+), 61 deletions(-) create mode 100644 clippy_lints/src/methods/iter_next_slice.rs diff --git a/clippy_lints/src/methods/iter_next_slice.rs b/clippy_lints/src/methods/iter_next_slice.rs new file mode 100644 index 0000000000000..3c03a949cfed0 --- /dev/null +++ b/clippy_lints/src/methods/iter_next_slice.rs @@ -0,0 +1,68 @@ +use crate::methods::derefs_to_slice; +use crate::utils::{get_parent_expr, higher, is_type_diagnostic_item, snippet_with_applicability, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_ast::ast; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::symbol::sym; + +use super::ITER_NEXT_SLICE; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) { + let caller_expr = &iter_args[0]; + + // Skip lint if the `iter().next()` expression is a for loop argument, + // since it is already covered by `&loops::ITER_NEXT_LOOP` + let mut parent_expr_opt = get_parent_expr(cx, expr); + while let Some(parent_expr) = parent_expr_opt { + if higher::for_loop(parent_expr).is_some() { + return; + } + parent_expr_opt = get_parent_expr(cx, parent_expr); + } + + if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() { + // caller is a Slice + if_chain! { + if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind; + if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen }) + = higher::range(index_expr); + if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind; + if let ast::LitKind::Int(start_idx, _) = start_lit.node; + then { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + ITER_NEXT_SLICE, + expr.span, + "using `.iter().next()` on a Slice without end index", + "try calling", + format!("{}.get({})", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability), start_idx), + applicability, + ); + } + } + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(caller_expr), sym::vec_type) + || matches!( + &cx.typeck_results().expr_ty(caller_expr).peel_refs().kind(), + ty::Array(_, _) + ) + { + // caller is a Vec or an Array + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + ITER_NEXT_SLICE, + expr.span, + "using `.iter().next()` on an array", + "try calling", + format!( + "{}.get(0)", + snippet_with_applicability(cx, caller_expr.span, "..", &mut applicability) + ), + applicability, + ); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index baa342ab3bb8c..46c9524af5536 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -10,6 +10,7 @@ mod inefficient_to_string; mod inspect_for_each; mod iter_cloned_collect; mod iter_count; +mod iter_next_slice; mod manual_saturating_arithmetic; mod map_collect_result_unit; mod ok_expect; @@ -46,9 +47,9 @@ use crate::consts::{constant, Constant}; use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::usage::mutated_variables; use crate::utils::{ - contains_return, contains_ty, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, - in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, - match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, + contains_return, contains_ty, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, + is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, + match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg, walk_ptrs_ty_depth, SpanlessEq, @@ -1688,7 +1689,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { }, ["next", "filter"] => filter_next::check(cx, expr, arg_lists[1]), ["next", "skip_while"] => skip_while_next::check(cx, expr, arg_lists[1]), - ["next", "iter"] => lint_iter_next(cx, expr, arg_lists[1]), + ["next", "iter"] => iter_next_slice::check(cx, expr, arg_lists[1]), ["map", "filter"] => lint_filter_map(cx, expr, false), ["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]), ["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1], self.msrv.as_ref()), @@ -2598,63 +2599,6 @@ fn lint_step_by<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx } } -fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) { - let caller_expr = &iter_args[0]; - - // Skip lint if the `iter().next()` expression is a for loop argument, - // since it is already covered by `&loops::ITER_NEXT_LOOP` - let mut parent_expr_opt = get_parent_expr(cx, expr); - while let Some(parent_expr) = parent_expr_opt { - if higher::for_loop(parent_expr).is_some() { - return; - } - parent_expr_opt = get_parent_expr(cx, parent_expr); - } - - if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() { - // caller is a Slice - if_chain! { - if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind; - if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen }) - = higher::range(index_expr); - if let hir::ExprKind::Lit(ref start_lit) = &start_expr.kind; - if let ast::LitKind::Int(start_idx, _) = start_lit.node; - then { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - ITER_NEXT_SLICE, - expr.span, - "using `.iter().next()` on a Slice without end index", - "try calling", - format!("{}.get({})", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability), start_idx), - applicability, - ); - } - } - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(caller_expr), sym::vec_type) - || matches!( - &cx.typeck_results().expr_ty(caller_expr).peel_refs().kind(), - ty::Array(_, _) - ) - { - // caller is a Vec or an Array - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - ITER_NEXT_SLICE, - expr.span, - "using `.iter().next()` on an array", - "try calling", - format!( - "{}.get(0)", - snippet_with_applicability(cx, caller_expr.span, "..", &mut applicability) - ), - applicability, - ); - } -} - fn lint_iter_nth<'tcx>( cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, From 5912ca986c52041d01384393cbf2da10270738ee Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 4 Mar 2021 23:06:05 +0900 Subject: [PATCH 190/226] move iter_nth, iter_nth_zero and iterator_step_by_zero to their own module --- clippy_lints/src/methods/iter_nth.rs | 38 ++++++++++ clippy_lints/src/methods/iter_nth_zero.rs | 27 +++++++ .../src/methods/iterator_step_by_zero.rs | 19 +++++ clippy_lints/src/methods/mod.rs | 74 ++----------------- 4 files changed, 91 insertions(+), 67 deletions(-) create mode 100644 clippy_lints/src/methods/iter_nth.rs create mode 100644 clippy_lints/src/methods/iter_nth_zero.rs create mode 100644 clippy_lints/src/methods/iterator_step_by_zero.rs diff --git a/clippy_lints/src/methods/iter_nth.rs b/clippy_lints/src/methods/iter_nth.rs new file mode 100644 index 0000000000000..c8adea9536b2d --- /dev/null +++ b/clippy_lints/src/methods/iter_nth.rs @@ -0,0 +1,38 @@ +use crate::methods::derefs_to_slice; +use crate::methods::iter_nth_zero; +use crate::utils::{is_type_diagnostic_item, span_lint_and_help}; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +use super::ITER_NTH; + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &hir::Expr<'_>, + nth_and_iter_args: &[&'tcx [hir::Expr<'tcx>]], + is_mut: bool, +) { + let iter_args = nth_and_iter_args[1]; + let mut_str = if is_mut { "_mut" } else { "" }; + let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() { + "slice" + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { + "Vec" + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { + "VecDeque" + } else { + let nth_args = nth_and_iter_args[0]; + iter_nth_zero::check(cx, expr, &nth_args); + return; // caller is not a type that we want to lint + }; + + span_lint_and_help( + cx, + ITER_NTH, + expr.span, + &format!("called `.iter{0}().nth()` on a {1}", mut_str, caller_type), + None, + &format!("calling `.get{}()` is both faster and more readable", mut_str), + ); +} diff --git a/clippy_lints/src/methods/iter_nth_zero.rs b/clippy_lints/src/methods/iter_nth_zero.rs new file mode 100644 index 0000000000000..247192d81f3ec --- /dev/null +++ b/clippy_lints/src/methods/iter_nth_zero.rs @@ -0,0 +1,27 @@ +use crate::consts::{constant, Constant}; +use crate::utils::{match_trait_method, paths, snippet_with_applicability, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::ITER_NTH_ZERO; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) { + if_chain! { + if match_trait_method(cx, expr, &paths::ITERATOR); + if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &nth_args[1]); + then { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + ITER_NTH_ZERO, + expr.span, + "called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent", + "try calling `.next()` instead of `.nth(0)`", + format!("{}.next()", snippet_with_applicability(cx, nth_args[0].span, "..", &mut applicability)), + applicability, + ); + } + } +} diff --git a/clippy_lints/src/methods/iterator_step_by_zero.rs b/clippy_lints/src/methods/iterator_step_by_zero.rs new file mode 100644 index 0000000000000..3e05d7f76b75a --- /dev/null +++ b/clippy_lints/src/methods/iterator_step_by_zero.rs @@ -0,0 +1,19 @@ +use crate::consts::{constant, Constant}; +use crate::utils::{match_trait_method, paths, span_lint}; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::ITERATOR_STEP_BY_ZERO; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) { + if match_trait_method(cx, expr, &paths::ITERATOR) { + if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &args[1]) { + span_lint( + cx, + ITERATOR_STEP_BY_ZERO, + expr.span, + "`Iterator::step_by(0)` will panic at runtime", + ); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 46c9524af5536..259d370550c84 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -11,6 +11,9 @@ mod inspect_for_each; mod iter_cloned_collect; mod iter_count; mod iter_next_slice; +mod iter_nth; +mod iter_nth_zero; +mod iterator_step_by_zero; mod manual_saturating_arithmetic; mod map_collect_result_unit; mod ok_expect; @@ -43,7 +46,6 @@ use rustc_span::source_map::Span; use rustc_span::symbol::{sym, Symbol, SymbolStr}; use rustc_typeck::hir_ty_to_ty; -use crate::consts::{constant, Constant}; use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::usage::mutated_variables; use crate::utils::{ @@ -1709,11 +1711,11 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"), ["count", "iter"] => iter_count::check(cx, expr, &arg_lists[1], "iter"), ["count", "iter_mut"] => iter_count::check(cx, expr, &arg_lists[1], "iter_mut"), - ["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false), - ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true), + ["nth", "iter"] => iter_nth::check(cx, expr, &arg_lists, false), + ["nth", "iter_mut"] => iter_nth::check(cx, expr, &arg_lists, true), ["nth", "bytes"] => bytes_nth::check(cx, expr, &arg_lists[1]), - ["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]), - ["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]), + ["nth", ..] => iter_nth_zero::check(cx, expr, arg_lists[0]), + ["step_by", ..] => iterator_step_by_zero::check(cx, expr, arg_lists[0]), ["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]), ["collect", "cloned"] => iter_cloned_collect::check(cx, expr, arg_lists[1]), ["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]), @@ -2586,68 +2588,6 @@ fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: } } -fn lint_step_by<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) { - if match_trait_method(cx, expr, &paths::ITERATOR) { - if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &args[1]) { - span_lint( - cx, - ITERATOR_STEP_BY_ZERO, - expr.span, - "`Iterator::step_by(0)` will panic at runtime", - ); - } - } -} - -fn lint_iter_nth<'tcx>( - cx: &LateContext<'tcx>, - expr: &hir::Expr<'_>, - nth_and_iter_args: &[&'tcx [hir::Expr<'tcx>]], - is_mut: bool, -) { - let iter_args = nth_and_iter_args[1]; - let mut_str = if is_mut { "_mut" } else { "" }; - let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() { - "slice" - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { - "Vec" - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vecdeque_type) { - "VecDeque" - } else { - let nth_args = nth_and_iter_args[0]; - lint_iter_nth_zero(cx, expr, &nth_args); - return; // caller is not a type that we want to lint - }; - - span_lint_and_help( - cx, - ITER_NTH, - expr.span, - &format!("called `.iter{0}().nth()` on a {1}", mut_str, caller_type), - None, - &format!("calling `.get{}()` is both faster and more readable", mut_str), - ); -} - -fn lint_iter_nth_zero<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) { - if_chain! { - if match_trait_method(cx, expr, &paths::ITERATOR); - if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &nth_args[1]); - then { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - ITER_NTH_ZERO, - expr.span, - "called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent", - "try calling `.next()` instead of `.nth(0)`", - format!("{}.next()", snippet_with_applicability(cx, nth_args[0].span, "..", &mut applicability)), - applicability, - ); - } - } -} - fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[hir::Expr<'_>]) { // lint if caller of skip is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { From b5d809a660240d5c826989839bd5eaab63fbb312 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 4 Mar 2021 23:47:30 +0900 Subject: [PATCH 191/226] move wrong_self_convention to its own module --- clippy_lints/src/methods/mod.rs | 81 +++---------------- .../src/methods/wrong_self_convention.rs | 76 +++++++++++++++++ 2 files changed, 86 insertions(+), 71 deletions(-) create mode 100644 clippy_lints/src/methods/wrong_self_convention.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 259d370550c84..3cd720bc9ca70 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -25,10 +25,10 @@ mod uninit_assumed_init; mod unnecessary_filter_map; mod unnecessary_lazy_eval; mod unwrap_used; +mod wrong_self_convention; mod zst_offset; use std::borrow::Cow; -use std::fmt; use std::iter; use bind_instead_of_map::BindInsteadOfMap; @@ -1868,7 +1868,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } } - lint_wrong_self_convention( + wrong_self_convention::check( cx, &name, item.vis.node.is_pub(), @@ -1924,7 +1924,14 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty(); then { - lint_wrong_self_convention(cx, &item.ident.name.as_str(), false, self_ty, first_arg_ty, first_arg_span); + wrong_self_convention::check( + cx, + &item.ident.name.as_str(), + false, + self_ty, + first_arg_ty, + first_arg_span + ); } } @@ -1949,39 +1956,6 @@ impl<'tcx> LateLintPass<'tcx> for Methods { extract_msrv_attr!(LateContext); } -fn lint_wrong_self_convention<'tcx>( - cx: &LateContext<'tcx>, - item_name: &str, - is_pub: bool, - self_ty: &'tcx TyS<'tcx>, - first_arg_ty: &'tcx TyS<'tcx>, - first_arg_span: Span, -) { - let lint = if is_pub { - WRONG_PUB_SELF_CONVENTION - } else { - WRONG_SELF_CONVENTION - }; - if let Some((ref conv, self_kinds)) = &CONVENTIONS.iter().find(|(ref conv, _)| conv.check(item_name)) { - if !self_kinds.iter().any(|k| k.matches(cx, self_ty, first_arg_ty)) { - span_lint( - cx, - lint, - first_arg_span, - &format!( - "methods called `{}` usually take {}; consider choosing a less ambiguous name", - conv, - &self_kinds - .iter() - .map(|k| k.description()) - .collect::>() - .join(" or ") - ), - ); - } - } -} - /// Checks for the `OR_FUN_CALL` lint. #[allow(clippy::too_many_lines)] fn lint_or_fun_call<'tcx>( @@ -3415,22 +3389,6 @@ fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_ } } -enum Convention { - Eq(&'static str), - StartsWith(&'static str), -} - -#[rustfmt::skip] -const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [ - (Convention::Eq("new"), &[SelfKind::No]), - (Convention::StartsWith("as_"), &[SelfKind::Ref, SelfKind::RefMut]), - (Convention::StartsWith("from_"), &[SelfKind::No]), - (Convention::StartsWith("into_"), &[SelfKind::Value]), - (Convention::StartsWith("is_"), &[SelfKind::Ref, SelfKind::No]), - (Convention::Eq("to_mut"), &[SelfKind::RefMut]), - (Convention::StartsWith("to_"), &[SelfKind::Ref]), -]; - const FN_HEADER: hir::FnHeader = hir::FnHeader { unsafety: hir::Unsafety::Normal, constness: hir::Constness::NotConst, @@ -3602,25 +3560,6 @@ impl SelfKind { } } -impl Convention { - #[must_use] - fn check(&self, other: &str) -> bool { - match *self { - Self::Eq(this) => this == other, - Self::StartsWith(this) => other.starts_with(this) && this != other, - } - } -} - -impl fmt::Display for Convention { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match *self { - Self::Eq(this) => this.fmt(f), - Self::StartsWith(this) => this.fmt(f).and_then(|_| '*'.fmt(f)), - } - } -} - #[derive(Clone, Copy)] enum OutType { Unit, diff --git a/clippy_lints/src/methods/wrong_self_convention.rs b/clippy_lints/src/methods/wrong_self_convention.rs new file mode 100644 index 0000000000000..90fab57743661 --- /dev/null +++ b/clippy_lints/src/methods/wrong_self_convention.rs @@ -0,0 +1,76 @@ +use crate::methods::SelfKind; +use crate::utils::span_lint; +use rustc_lint::LateContext; +use rustc_middle::ty::TyS; +use rustc_span::source_map::Span; +use std::fmt; + +use super::WRONG_PUB_SELF_CONVENTION; +use super::WRONG_SELF_CONVENTION; + +#[rustfmt::skip] +const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [ + (Convention::Eq("new"), &[SelfKind::No]), + (Convention::StartsWith("as_"), &[SelfKind::Ref, SelfKind::RefMut]), + (Convention::StartsWith("from_"), &[SelfKind::No]), + (Convention::StartsWith("into_"), &[SelfKind::Value]), + (Convention::StartsWith("is_"), &[SelfKind::Ref, SelfKind::No]), + (Convention::Eq("to_mut"), &[SelfKind::RefMut]), + (Convention::StartsWith("to_"), &[SelfKind::Ref]), +]; +enum Convention { + Eq(&'static str), + StartsWith(&'static str), +} + +impl Convention { + #[must_use] + fn check(&self, other: &str) -> bool { + match *self { + Self::Eq(this) => this == other, + Self::StartsWith(this) => other.starts_with(this) && this != other, + } + } +} + +impl fmt::Display for Convention { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match *self { + Self::Eq(this) => this.fmt(f), + Self::StartsWith(this) => this.fmt(f).and_then(|_| '*'.fmt(f)), + } + } +} + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + item_name: &str, + is_pub: bool, + self_ty: &'tcx TyS<'tcx>, + first_arg_ty: &'tcx TyS<'tcx>, + first_arg_span: Span, +) { + let lint = if is_pub { + WRONG_PUB_SELF_CONVENTION + } else { + WRONG_SELF_CONVENTION + }; + if let Some((ref conv, self_kinds)) = &CONVENTIONS.iter().find(|(ref conv, _)| conv.check(item_name)) { + if !self_kinds.iter().any(|k| k.matches(cx, self_ty, first_arg_ty)) { + span_lint( + cx, + lint, + first_arg_span, + &format!( + "methods called `{}` usually take {}; consider choosing a less ambiguous name", + conv, + &self_kinds + .iter() + .map(|k| k.description()) + .collect::>() + .join(" or ") + ), + ); + } + } +} From 2ade32ddf2ec13a6ec2e03c14e7393ce784d4d18 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 5 Mar 2021 00:16:43 +0900 Subject: [PATCH 192/226] move string_extend_chars and clone_on_ref_ptr to their own module --- clippy_lints/src/methods/clone_on_ref_ptr.rs | 36 ++++++++++ clippy_lints/src/methods/mod.rs | 72 ++----------------- .../src/methods/string_extend_chars.rs | 42 +++++++++++ 3 files changed, 82 insertions(+), 68 deletions(-) create mode 100644 clippy_lints/src/methods/clone_on_ref_ptr.rs create mode 100644 clippy_lints/src/methods/string_extend_chars.rs diff --git a/clippy_lints/src/methods/clone_on_ref_ptr.rs b/clippy_lints/src/methods/clone_on_ref_ptr.rs new file mode 100644 index 0000000000000..3d5a68d69d7d2 --- /dev/null +++ b/clippy_lints/src/methods/clone_on_ref_ptr.rs @@ -0,0 +1,36 @@ +use crate::utils::{is_type_diagnostic_item, match_type, paths, snippet_with_macro_callsite, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::symbol::sym; + +use super::CLONE_ON_REF_PTR; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { + let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs(); + + if let ty::Adt(_, subst) = obj_ty.kind() { + let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) { + "Rc" + } else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) { + "Arc" + } else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) { + "Weak" + } else { + return; + }; + + let snippet = snippet_with_macro_callsite(cx, arg.span, ".."); + + span_lint_and_sugg( + cx, + CLONE_ON_REF_PTR, + expr.span, + "using `.clone()` on a ref-counted pointer", + "try this", + format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet), + Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak + ); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 3cd720bc9ca70..480f32a434084 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1,5 +1,6 @@ mod bind_instead_of_map; mod bytes_nth; +mod clone_on_ref_ptr; mod expect_used; mod filetype_is_file; mod filter_map_identity; @@ -20,6 +21,7 @@ mod ok_expect; mod option_as_ref_deref; mod option_map_unwrap_or; mod skip_while_next; +mod string_extend_chars; mod suspicious_map; mod uninit_assumed_init; mod unnecessary_filter_map; @@ -1707,7 +1709,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["is_some", "rposition"] => { lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) }, - ["extend", ..] => lint_extend(cx, expr, arg_lists[0]), + ["extend", ..] => string_extend_chars::check(cx, expr, arg_lists[0]), ["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"), ["count", "iter"] => iter_count::check(cx, expr, &arg_lists[1], "iter"), ["count", "iter_mut"] => iter_count::check(cx, expr, &arg_lists[1], "iter_mut"), @@ -1767,7 +1769,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]); if args.len() == 1 && method_call.ident.name == sym::clone { lint_clone_on_copy(cx, expr, &args[0], self_ty); - lint_clone_on_ref_ptr(cx, expr, &args[0]); + clone_on_ref_ptr::check(cx, expr, &args[0]); } if args.len() == 1 && method_call.ident.name == sym!(to_string) { inefficient_to_string::check(cx, expr, &args[0], self_ty); @@ -2408,72 +2410,6 @@ fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Exp } } -fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { - let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs(); - - if let ty::Adt(_, subst) = obj_ty.kind() { - let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) { - "Rc" - } else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) { - "Arc" - } else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) { - "Weak" - } else { - return; - }; - - let snippet = snippet_with_macro_callsite(cx, arg.span, ".."); - - span_lint_and_sugg( - cx, - CLONE_ON_REF_PTR, - expr.span, - "using `.clone()` on a ref-counted pointer", - "try this", - format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet), - Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak - ); - } -} - -fn lint_string_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let arg = &args[1]; - if let Some(arglists) = method_chain_args(arg, &["chars"]) { - let target = &arglists[0][0]; - let self_ty = cx.typeck_results().expr_ty(target).peel_refs(); - let ref_str = if *self_ty.kind() == ty::Str { - "" - } else if is_type_diagnostic_item(cx, self_ty, sym::string_type) { - "&" - } else { - return; - }; - - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - STRING_EXTEND_CHARS, - expr.span, - "calling `.extend(_.chars())`", - "try this", - format!( - "{}.push_str({}{})", - snippet_with_applicability(cx, args[0].span, "..", &mut applicability), - ref_str, - snippet_with_applicability(cx, target.span, "..", &mut applicability) - ), - applicability, - ); - } -} - -fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let obj_ty = cx.typeck_results().expr_ty(&args[0]).peel_refs(); - if is_type_diagnostic_item(cx, obj_ty, sym::string_type) { - lint_string_extend(cx, expr, args); - } -} - fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) { fn check_fold_with_op( cx: &LateContext<'_>, diff --git a/clippy_lints/src/methods/string_extend_chars.rs b/clippy_lints/src/methods/string_extend_chars.rs new file mode 100644 index 0000000000000..0a08ea26175fe --- /dev/null +++ b/clippy_lints/src/methods/string_extend_chars.rs @@ -0,0 +1,42 @@ +use crate::utils::{is_type_diagnostic_item, method_chain_args, snippet_with_applicability, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::symbol::sym; + +use super::STRING_EXTEND_CHARS; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { + let obj_ty = cx.typeck_results().expr_ty(&args[0]).peel_refs(); + if is_type_diagnostic_item(cx, obj_ty, sym::string_type) { + let arg = &args[1]; + if let Some(arglists) = method_chain_args(arg, &["chars"]) { + let target = &arglists[0][0]; + let self_ty = cx.typeck_results().expr_ty(target).peel_refs(); + let ref_str = if *self_ty.kind() == ty::Str { + "" + } else if is_type_diagnostic_item(cx, self_ty, sym::string_type) { + "&" + } else { + return; + }; + + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + STRING_EXTEND_CHARS, + expr.span, + "calling `.extend(_.chars())`", + "try this", + format!( + "{}.push_str({}{})", + snippet_with_applicability(cx, args[0].span, "..", &mut applicability), + ref_str, + snippet_with_applicability(cx, target.span, "..", &mut applicability) + ), + applicability, + ); + } + } +} From 8006dab817e6bfa0a71a593d46c5569e8a98a6b7 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 15:29:02 +0900 Subject: [PATCH 193/226] move single_char_insert_string to its own module --- clippy_lints/src/methods/mod.rs | 23 ++-------------- .../src/methods/single_char_insert_string.rs | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 clippy_lints/src/methods/single_char_insert_string.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 480f32a434084..ef671e41cb59b 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -20,6 +20,7 @@ mod map_collect_result_unit; mod ok_expect; mod option_as_ref_deref; mod option_map_unwrap_or; +mod single_char_insert_string; mod skip_while_next; mod string_extend_chars; mod suspicious_map; @@ -1779,7 +1780,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if match_def_path(cx, fn_def_id, &paths::PUSH_STR) { lint_single_char_push_string(cx, expr, args); } else if match_def_path(cx, fn_def_id, &paths::INSERT_STR) { - lint_single_char_insert_string(cx, expr, args); + single_char_insert_string::check(cx, expr, args); } } @@ -3235,26 +3236,6 @@ fn lint_single_char_push_string(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args } } -/// lint for length-1 `str`s as argument for `insert_str` -fn lint_single_char_insert_string(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let mut applicability = Applicability::MachineApplicable; - if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[2], &mut applicability) { - let base_string_snippet = - snippet_with_applicability(cx, args[0].span.source_callsite(), "_", &mut applicability); - let pos_arg = snippet_with_applicability(cx, args[1].span, "..", &mut applicability); - let sugg = format!("{}.insert({}, {})", base_string_snippet, pos_arg, extension_string); - span_lint_and_sugg( - cx, - SINGLE_CHAR_ADD_STR, - expr.span, - "calling `insert_str()` using a single-character string literal", - "consider using `insert` with a character literal", - sugg, - applicability, - ); - } -} - /// Checks for the `USELESS_ASREF` lint. fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) { // when we get here, we've already checked that the call name is "as_ref" or "as_mut" diff --git a/clippy_lints/src/methods/single_char_insert_string.rs b/clippy_lints/src/methods/single_char_insert_string.rs new file mode 100644 index 0000000000000..0ce8b66978dc1 --- /dev/null +++ b/clippy_lints/src/methods/single_char_insert_string.rs @@ -0,0 +1,27 @@ +use crate::methods::get_hint_if_single_char_arg; +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::SINGLE_CHAR_ADD_STR; + +/// lint for length-1 `str`s as argument for `insert_str` +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { + let mut applicability = Applicability::MachineApplicable; + if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[2], &mut applicability) { + let base_string_snippet = + snippet_with_applicability(cx, args[0].span.source_callsite(), "_", &mut applicability); + let pos_arg = snippet_with_applicability(cx, args[1].span, "..", &mut applicability); + let sugg = format!("{}.insert({}, {})", base_string_snippet, pos_arg, extension_string); + span_lint_and_sugg( + cx, + SINGLE_CHAR_ADD_STR, + expr.span, + "calling `insert_str()` using a single-character string literal", + "consider using `insert` with a character literal", + sugg, + applicability, + ); + } +} From 805aa47f43ab9b61a69f63682176604cdcda8fae Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 15:39:28 +0900 Subject: [PATCH 194/226] move single_char_push_string to its own module --- clippy_lints/src/methods/mod.rs | 22 ++-------------- .../src/methods/single_char_push_string.rs | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 clippy_lints/src/methods/single_char_push_string.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index ef671e41cb59b..24d610cf5f8f7 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -21,6 +21,7 @@ mod ok_expect; mod option_as_ref_deref; mod option_map_unwrap_or; mod single_char_insert_string; +mod single_char_push_string; mod skip_while_next; mod string_extend_chars; mod suspicious_map; @@ -1778,7 +1779,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { if match_def_path(cx, fn_def_id, &paths::PUSH_STR) { - lint_single_char_push_string(cx, expr, args); + single_char_push_string::check(cx, expr, args); } else if match_def_path(cx, fn_def_id, &paths::INSERT_STR) { single_char_insert_string::check(cx, expr, args); } @@ -3217,25 +3218,6 @@ fn lint_single_char_pattern(cx: &LateContext<'_>, _expr: &hir::Expr<'_>, arg: &h } } -/// lint for length-1 `str`s as argument for `push_str` -fn lint_single_char_push_string(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let mut applicability = Applicability::MachineApplicable; - if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability) { - let base_string_snippet = - snippet_with_applicability(cx, args[0].span.source_callsite(), "..", &mut applicability); - let sugg = format!("{}.push({})", base_string_snippet, extension_string); - span_lint_and_sugg( - cx, - SINGLE_CHAR_ADD_STR, - expr.span, - "calling `push_str()` using a single-character string literal", - "consider using `push` with a character literal", - sugg, - applicability, - ); - } -} - /// Checks for the `USELESS_ASREF` lint. fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) { // when we get here, we've already checked that the call name is "as_ref" or "as_mut" diff --git a/clippy_lints/src/methods/single_char_push_string.rs b/clippy_lints/src/methods/single_char_push_string.rs new file mode 100644 index 0000000000000..deacc70b713e5 --- /dev/null +++ b/clippy_lints/src/methods/single_char_push_string.rs @@ -0,0 +1,26 @@ +use crate::methods::get_hint_if_single_char_arg; +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::SINGLE_CHAR_ADD_STR; + +/// lint for length-1 `str`s as argument for `push_str` +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { + let mut applicability = Applicability::MachineApplicable; + if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability) { + let base_string_snippet = + snippet_with_applicability(cx, args[0].span.source_callsite(), "..", &mut applicability); + let sugg = format!("{}.push({})", base_string_snippet, extension_string); + span_lint_and_sugg( + cx, + SINGLE_CHAR_ADD_STR, + expr.span, + "calling `push_str()` using a single-character string literal", + "consider using `push` with a character literal", + sugg, + applicability, + ); + } +} From 0c8d143515a19b04a404765ecb8145a183dc2186 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 17:28:14 +0900 Subject: [PATCH 195/226] move into_iter_on_ref and single_char_pattern to their own modules --- clippy_lints/src/methods/into_iter_on_ref.rs | 42 ++++++++++++ clippy_lints/src/methods/mod.rs | 67 +++---------------- .../src/methods/single_char_pattern.rs | 23 +++++++ 3 files changed, 74 insertions(+), 58 deletions(-) create mode 100644 clippy_lints/src/methods/into_iter_on_ref.rs create mode 100644 clippy_lints/src/methods/single_char_pattern.rs diff --git a/clippy_lints/src/methods/into_iter_on_ref.rs b/clippy_lints/src/methods/into_iter_on_ref.rs new file mode 100644 index 0000000000000..d94b243404c36 --- /dev/null +++ b/clippy_lints/src/methods/into_iter_on_ref.rs @@ -0,0 +1,42 @@ +use crate::utils::{has_iter_method, match_trait_method, paths, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; +use rustc_span::source_map::Span; + +use super::INTO_ITER_ON_REF; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_>, method_span: Span) { + if !match_trait_method(cx, expr, &paths::INTO_ITERATOR) { + return; + } + if let Some((kind, method_name)) = ty_has_iter_method(cx, self_ref_ty) { + span_lint_and_sugg( + cx, + INTO_ITER_ON_REF, + method_span, + &format!( + "this `.into_iter()` call is equivalent to `.{}()` and will not consume the `{}`", + method_name, kind, + ), + "call directly", + method_name.to_string(), + Applicability::MachineApplicable, + ); + } +} + +fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(&'static str, &'static str)> { + has_iter_method(cx, self_ref_ty).map(|ty_name| { + let mutbl = match self_ref_ty.kind() { + ty::Ref(_, _, mutbl) => mutbl, + _ => unreachable!(), + }; + let method_name = match mutbl { + hir::Mutability::Not => "iter", + hir::Mutability::Mut => "iter_mut", + }; + (ty_name, method_name) + }) +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 24d610cf5f8f7..28e2d896e6cdb 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -9,6 +9,7 @@ mod get_unwrap; mod implicit_clone; mod inefficient_to_string; mod inspect_for_each; +mod into_iter_on_ref; mod iter_cloned_collect; mod iter_count; mod iter_next_slice; @@ -21,6 +22,7 @@ mod ok_expect; mod option_as_ref_deref; mod option_map_unwrap_or; mod single_char_insert_string; +mod single_char_pattern; mod single_char_push_string; mod skip_while_next; mod string_extend_chars; @@ -53,12 +55,11 @@ use rustc_typeck::hir_ty_to_ty; use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::usage::mutated_variables; use crate::utils::{ - contains_return, contains_ty, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, - is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, - match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, - remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, - span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg, walk_ptrs_ty_depth, - SpanlessEq, + contains_return, contains_ty, get_parent_expr, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, + is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method, + match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, remove_blocks, return_ty, + single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, + span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg, walk_ptrs_ty_depth, SpanlessEq, }; declare_clippy_lint! { @@ -1789,12 +1790,12 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ty::Ref(_, ty, _) if *ty.kind() == ty::Str => { for &(method, pos) in &PATTERN_METHODS { if method_call.ident.name.as_str() == method && args.len() > pos { - lint_single_char_pattern(cx, expr, &args[pos]); + single_char_pattern::check(cx, expr, &args[pos]); } } }, ty::Ref(..) if method_call.ident.name == sym::into_iter => { - lint_into_iter(cx, expr, self_ty, *method_span); + into_iter_on_ref::check(cx, expr, self_ty, *method_span); }, _ => (), } @@ -3202,22 +3203,6 @@ fn get_hint_if_single_char_arg( } } -/// lint for length-1 `str`s for methods in `PATTERN_METHODS` -fn lint_single_char_pattern(cx: &LateContext<'_>, _expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { - let mut applicability = Applicability::MachineApplicable; - if let Some(hint) = get_hint_if_single_char_arg(cx, arg, &mut applicability) { - span_lint_and_sugg( - cx, - SINGLE_CHAR_PATTERN, - arg.span, - "single-character string constant used as pattern", - "try using a `char` instead", - hint, - applicability, - ); - } -} - /// Checks for the `USELESS_ASREF` lint. fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) { // when we get here, we've already checked that the call name is "as_ref" or "as_mut" @@ -3254,40 +3239,6 @@ fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_re } } -fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(Symbol, &'static str)> { - has_iter_method(cx, self_ref_ty).map(|ty_name| { - let mutbl = match self_ref_ty.kind() { - ty::Ref(_, _, mutbl) => mutbl, - _ => unreachable!(), - }; - let method_name = match mutbl { - hir::Mutability::Not => "iter", - hir::Mutability::Mut => "iter_mut", - }; - (ty_name, method_name) - }) -} - -fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_>, method_span: Span) { - if !match_trait_method(cx, expr, &paths::INTO_ITERATOR) { - return; - } - if let Some((kind, method_name)) = ty_has_iter_method(cx, self_ref_ty) { - span_lint_and_sugg( - cx, - INTO_ITER_ON_REF, - method_span, - &format!( - "this `.into_iter()` call is equivalent to `.{}()` and will not consume the `{}`", - method_name, kind, - ), - "call directly", - method_name.to_string(), - Applicability::MachineApplicable, - ); - } -} - const FN_HEADER: hir::FnHeader = hir::FnHeader { unsafety: hir::Unsafety::Normal, constness: hir::Constness::NotConst, diff --git a/clippy_lints/src/methods/single_char_pattern.rs b/clippy_lints/src/methods/single_char_pattern.rs new file mode 100644 index 0000000000000..61cbc9d2f0a62 --- /dev/null +++ b/clippy_lints/src/methods/single_char_pattern.rs @@ -0,0 +1,23 @@ +use crate::methods::get_hint_if_single_char_arg; +use crate::utils::span_lint_and_sugg; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::SINGLE_CHAR_PATTERN; + +/// lint for length-1 `str`s for methods in `PATTERN_METHODS` +pub(super) fn check(cx: &LateContext<'_>, _expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { + let mut applicability = Applicability::MachineApplicable; + if let Some(hint) = get_hint_if_single_char_arg(cx, arg, &mut applicability) { + span_lint_and_sugg( + cx, + SINGLE_CHAR_PATTERN, + arg.span, + "single-character string constant used as pattern", + "try using a `char` instead", + hint, + applicability, + ); + } +} From 2561b7ea062f0c07f27d9ebdf0c355ab29a4edf9 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 17:46:50 +0900 Subject: [PATCH 196/226] move from_iter_insteam_of_collect to its own module --- .../methods/from_iter_instead_of_collect.rs | 67 +++++++++++++++++++ clippy_lints/src/methods/mod.rs | 62 +---------------- 2 files changed, 69 insertions(+), 60 deletions(-) create mode 100644 clippy_lints/src/methods/from_iter_instead_of_collect.rs diff --git a/clippy_lints/src/methods/from_iter_instead_of_collect.rs b/clippy_lints/src/methods/from_iter_instead_of_collect.rs new file mode 100644 index 0000000000000..e50d0a3340026 --- /dev/null +++ b/clippy_lints/src/methods/from_iter_instead_of_collect.rs @@ -0,0 +1,67 @@ +use crate::utils::{get_trait_def_id, implements_trait, paths, span_lint_and_sugg, sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::{LateContext, LintContext}; +use rustc_middle::ty::Ty; + +use super::FROM_ITER_INSTEAD_OF_COLLECT; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { + let ty = cx.typeck_results().expr_ty(expr); + let arg_ty = cx.typeck_results().expr_ty(&args[0]); + + if_chain! { + if let Some(from_iter_id) = get_trait_def_id(cx, &paths::FROM_ITERATOR); + if let Some(iter_id) = get_trait_def_id(cx, &paths::ITERATOR); + + if implements_trait(cx, ty, from_iter_id, &[]) && implements_trait(cx, arg_ty, iter_id, &[]); + then { + // `expr` implements `FromIterator` trait + let iter_expr = sugg::Sugg::hir(cx, &args[0], "..").maybe_par(); + let turbofish = extract_turbofish(cx, expr, ty); + let sugg = format!("{}.collect::<{}>()", iter_expr, turbofish); + span_lint_and_sugg( + cx, + FROM_ITER_INSTEAD_OF_COLLECT, + expr.span, + "usage of `FromIterator::from_iter`", + "use `.collect()` instead of `::from_iter()`", + sugg, + Applicability::MaybeIncorrect, + ); + } + } +} + +fn extract_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ty: Ty<'tcx>) -> String { + if_chain! { + let call_site = expr.span.source_callsite(); + if let Ok(snippet) = cx.sess().source_map().span_to_snippet(call_site); + let snippet_split = snippet.split("::").collect::>(); + if let Some((_, elements)) = snippet_split.split_last(); + + then { + // is there a type specifier? (i.e.: like `` in `collections::BTreeSet::::`) + if let Some(type_specifier) = snippet_split.iter().find(|e| e.starts_with('<') && e.ends_with('>')) { + // remove the type specifier from the path elements + let without_ts = elements.iter().filter_map(|e| { + if e == type_specifier { None } else { Some((*e).to_string()) } + }).collect::>(); + // join and add the type specifier at the end (i.e.: `collections::BTreeSet`) + format!("{}{}", without_ts.join("::"), type_specifier) + } else { + // type is not explicitly specified so wildcards are needed + // i.e.: 2 wildcards in `std::collections::BTreeMap<&i32, &char>` + let ty_str = ty.to_string(); + let start = ty_str.find('<').unwrap_or(0); + let end = ty_str.find('>').unwrap_or_else(|| ty_str.len()); + let nb_wildcard = ty_str[start..end].split(',').count(); + let wildcards = format!("_{}", ", _".repeat(nb_wildcard - 1)); + format!("{}<{}>", elements.join("::"), wildcards) + } + } else { + ty.to_string() + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 28e2d896e6cdb..9a0ef6c01c1a2 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5,6 +5,7 @@ mod expect_used; mod filetype_is_file; mod filter_map_identity; mod filter_next; +mod from_iter_instead_of_collect; mod get_unwrap; mod implicit_clone; mod inefficient_to_string; @@ -1761,7 +1762,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { hir::ExprKind::Call(ref func, ref args) => { if let hir::ExprKind::Path(path) = &func.kind { if match_qpath(path, &["from_iter"]) { - lint_from_iter(cx, expr, args); + from_iter_instead_of_collect::check(cx, expr, args); } } }, @@ -3440,65 +3441,6 @@ fn is_bool(ty: &hir::Ty<'_>) -> bool { } } -fn lint_from_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let ty = cx.typeck_results().expr_ty(expr); - let arg_ty = cx.typeck_results().expr_ty(&args[0]); - - if_chain! { - if let Some(from_iter_id) = get_trait_def_id(cx, &paths::FROM_ITERATOR); - if let Some(iter_id) = get_trait_def_id(cx, &paths::ITERATOR); - - if implements_trait(cx, ty, from_iter_id, &[]) && implements_trait(cx, arg_ty, iter_id, &[]); - then { - // `expr` implements `FromIterator` trait - let iter_expr = sugg::Sugg::hir(cx, &args[0], "..").maybe_par(); - let turbofish = extract_turbofish(cx, expr, ty); - let sugg = format!("{}.collect::<{}>()", iter_expr, turbofish); - span_lint_and_sugg( - cx, - FROM_ITER_INSTEAD_OF_COLLECT, - expr.span, - "usage of `FromIterator::from_iter`", - "use `.collect()` instead of `::from_iter()`", - sugg, - Applicability::MaybeIncorrect, - ); - } - } -} - -fn extract_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ty: Ty<'tcx>) -> String { - if_chain! { - let call_site = expr.span.source_callsite(); - if let Ok(snippet) = cx.sess().source_map().span_to_snippet(call_site); - let snippet_split = snippet.split("::").collect::>(); - if let Some((_, elements)) = snippet_split.split_last(); - - then { - // is there a type specifier? (i.e.: like `` in `collections::BTreeSet::::`) - if let Some(type_specifier) = snippet_split.iter().find(|e| e.starts_with('<') && e.ends_with('>')) { - // remove the type specifier from the path elements - let without_ts = elements.iter().filter_map(|e| { - if e == type_specifier { None } else { Some((*e).to_string()) } - }).collect::>(); - // join and add the type specifier at the end (i.e.: `collections::BTreeSet`) - format!("{}{}", without_ts.join("::"), type_specifier) - } else { - // type is not explicitly specified so wildcards are needed - // i.e.: 2 wildcards in `std::collections::BTreeMap<&i32, &char>` - let ty_str = ty.to_string(); - let start = ty_str.find('<').unwrap_or(0); - let end = ty_str.find('>').unwrap_or_else(|| ty_str.len()); - let nb_wildcard = ty_str[start..end].split(',').count(); - let wildcards = format!("_{}", ", _".repeat(nb_wildcard - 1)); - format!("{}<{}>", elements.join("::"), wildcards) - } - } else { - ty.to_string() - } - } -} - fn fn_header_equals(expected: hir::FnHeader, actual: hir::FnHeader) -> bool { expected.constness == actual.constness && expected.unsafety == actual.unsafety From 183daeb961c83d5be108cfa5ee463bba412dedc4 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 17:55:29 +0900 Subject: [PATCH 197/226] move filter_map to its own module --- clippy_lints/src/methods/filter_map.rs | 85 ++++++++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 81 ++---------------------- 2 files changed, 89 insertions(+), 77 deletions(-) create mode 100644 clippy_lints/src/methods/filter_map.rs diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs new file mode 100644 index 0000000000000..f559160004cb1 --- /dev/null +++ b/clippy_lints/src/methods/filter_map.rs @@ -0,0 +1,85 @@ +use crate::utils::{match_trait_method, path_to_local_id, paths, snippet, span_lint_and_sugg, SpanlessEq}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_hir::{Expr, ExprKind, PatKind, UnOp}; +use rustc_lint::LateContext; +use rustc_middle::ty::TyS; +use rustc_span::symbol::sym; + +use super::MANUAL_FILTER_MAP; +use super::MANUAL_FIND_MAP; + +/// lint use of `filter().map()` or `find().map()` for `Iterators` +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, is_find: bool) { + if_chain! { + if let ExprKind::MethodCall(_, _, [map_recv, map_arg], map_span) = expr.kind; + if let ExprKind::MethodCall(_, _, [_, filter_arg], filter_span) = map_recv.kind; + if match_trait_method(cx, map_recv, &paths::ITERATOR); + + // filter(|x| ...is_some())... + if let ExprKind::Closure(_, _, filter_body_id, ..) = filter_arg.kind; + let filter_body = cx.tcx.hir().body(filter_body_id); + if let [filter_param] = filter_body.params; + // optional ref pattern: `filter(|&x| ..)` + let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind { + (ref_pat, true) + } else { + (filter_param.pat, false) + }; + // closure ends with is_some() or is_ok() + if let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind; + if let ExprKind::MethodCall(path, _, [filter_arg], _) = filter_body.value.kind; + if let Some(opt_ty) = cx.typeck_results().expr_ty(filter_arg).ty_adt_def(); + if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::option_type, opt_ty.did) { + Some(false) + } else if cx.tcx.is_diagnostic_item(sym::result_type, opt_ty.did) { + Some(true) + } else { + None + }; + if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" }; + + // ...map(|x| ...unwrap()) + if let ExprKind::Closure(_, _, map_body_id, ..) = map_arg.kind; + let map_body = cx.tcx.hir().body(map_body_id); + if let [map_param] = map_body.params; + if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind; + // closure ends with expect() or unwrap() + if let ExprKind::MethodCall(seg, _, [map_arg, ..], _) = map_body.value.kind; + if matches!(seg.ident.name, sym::expect | sym::unwrap | sym::unwrap_or); + + let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| { + // in `filter(|x| ..)`, replace `*x` with `x` + let a_path = if_chain! { + if !is_filter_param_ref; + if let ExprKind::Unary(UnOp::Deref, expr_path) = a.kind; + then { expr_path } else { a } + }; + // let the filter closure arg and the map closure arg be equal + if_chain! { + if path_to_local_id(a_path, filter_param_id); + if path_to_local_id(b, map_param_id); + if TyS::same_type(cx.typeck_results().expr_ty_adjusted(a), cx.typeck_results().expr_ty_adjusted(b)); + then { + return true; + } + } + false + }; + if SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(filter_arg, map_arg); + then { + let span = filter_span.to(map_span); + let (filter_name, lint) = if is_find { + ("find", MANUAL_FIND_MAP) + } else { + ("filter", MANUAL_FILTER_MAP) + }; + let msg = format!("`{}(..).map(..)` can be simplified as `{0}_map(..)`", filter_name); + let to_opt = if is_result { ".ok()" } else { "" }; + let sugg = format!("{}_map(|{}| {}{})", filter_name, map_param_ident, + snippet(cx, map_arg.span, ".."), to_opt); + span_lint_and_sugg(cx, lint, span, &msg, "try", sugg, Applicability::MachineApplicable); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 9a0ef6c01c1a2..61d562cbc2844 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -3,6 +3,7 @@ mod bytes_nth; mod clone_on_ref_ptr; mod expect_used; mod filetype_is_file; +mod filter_map; mod filter_map_identity; mod filter_next; mod from_iter_instead_of_collect; @@ -43,7 +44,7 @@ use if_chain::if_chain; use rustc_ast::ast; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::{Expr, ExprKind, PatKind, TraitItem, TraitItemKind, UnOp}; +use rustc_hir::{PatKind, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass, Lint, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, TraitRef, Ty, TyS}; @@ -1698,10 +1699,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["next", "filter"] => filter_next::check(cx, expr, arg_lists[1]), ["next", "skip_while"] => skip_while_next::check(cx, expr, arg_lists[1]), ["next", "iter"] => iter_next_slice::check(cx, expr, arg_lists[1]), - ["map", "filter"] => lint_filter_map(cx, expr, false), + ["map", "filter"] => filter_map::check(cx, expr, false), ["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]), ["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1], self.msrv.as_ref()), - ["map", "find"] => lint_filter_map(cx, expr, true), + ["map", "find"] => filter_map::check(cx, expr, true), ["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", ..] => lint_flat_map_identity(cx, expr, arg_lists[0], method_spans[0]), @@ -2750,80 +2751,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -/// lint use of `filter().map()` or `find().map()` for `Iterators` -fn lint_filter_map<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, is_find: bool) { - if_chain! { - if let ExprKind::MethodCall(_, _, [map_recv, map_arg], map_span) = expr.kind; - if let ExprKind::MethodCall(_, _, [_, filter_arg], filter_span) = map_recv.kind; - if match_trait_method(cx, map_recv, &paths::ITERATOR); - - // filter(|x| ...is_some())... - if let ExprKind::Closure(_, _, filter_body_id, ..) = filter_arg.kind; - let filter_body = cx.tcx.hir().body(filter_body_id); - if let [filter_param] = filter_body.params; - // optional ref pattern: `filter(|&x| ..)` - let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind { - (ref_pat, true) - } else { - (filter_param.pat, false) - }; - // closure ends with is_some() or is_ok() - if let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind; - if let ExprKind::MethodCall(path, _, [filter_arg], _) = filter_body.value.kind; - if let Some(opt_ty) = cx.typeck_results().expr_ty(filter_arg).ty_adt_def(); - if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::option_type, opt_ty.did) { - Some(false) - } else if cx.tcx.is_diagnostic_item(sym::result_type, opt_ty.did) { - Some(true) - } else { - None - }; - if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" }; - - // ...map(|x| ...unwrap()) - if let ExprKind::Closure(_, _, map_body_id, ..) = map_arg.kind; - let map_body = cx.tcx.hir().body(map_body_id); - if let [map_param] = map_body.params; - if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind; - // closure ends with expect() or unwrap() - if let ExprKind::MethodCall(seg, _, [map_arg, ..], _) = map_body.value.kind; - if matches!(seg.ident.name, sym::expect | sym::unwrap | sym::unwrap_or); - - let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| { - // in `filter(|x| ..)`, replace `*x` with `x` - let a_path = if_chain! { - if !is_filter_param_ref; - if let ExprKind::Unary(UnOp::Deref, expr_path) = a.kind; - then { expr_path } else { a } - }; - // let the filter closure arg and the map closure arg be equal - if_chain! { - if path_to_local_id(a_path, filter_param_id); - if path_to_local_id(b, map_param_id); - if TyS::same_type(cx.typeck_results().expr_ty_adjusted(a), cx.typeck_results().expr_ty_adjusted(b)); - then { - return true; - } - } - false - }; - if SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(filter_arg, map_arg); - then { - let span = filter_span.to(map_span); - let (filter_name, lint) = if is_find { - ("find", MANUAL_FIND_MAP) - } else { - ("filter", MANUAL_FILTER_MAP) - }; - let msg = format!("`{}(..).map(..)` can be simplified as `{0}_map(..)`", filter_name); - let to_opt = if is_result { ".ok()" } else { "" }; - let sugg = format!("{}_map(|{}| {}{})", filter_name, map_param_ident, - snippet(cx, map_arg.span, ".."), to_opt); - span_lint_and_sugg(cx, lint, span, &msg, "try", sugg, Applicability::MachineApplicable); - } - } -} - const FILTER_MAP_NEXT_MSRV: RustcVersion = RustcVersion::new(1, 30, 0); /// lint use of `filter_map().next()` for `Iterators` From 805dcd12d41e72c16bbca83496f4b89ba49eed64 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:05:15 +0900 Subject: [PATCH 198/226] move filter_map_map to its own module --- clippy_lints/src/methods/filter_map_map.rs | 20 ++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 18 ++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 clippy_lints/src/methods/filter_map_map.rs diff --git a/clippy_lints/src/methods/filter_map_map.rs b/clippy_lints/src/methods/filter_map_map.rs new file mode 100644 index 0000000000000..d015b4c7b385e --- /dev/null +++ b/clippy_lints/src/methods/filter_map_map.rs @@ -0,0 +1,20 @@ +use crate::utils::{match_trait_method, paths, span_lint_and_help}; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::FILTER_MAP; + +/// lint use of `filter_map().map()` for `Iterators` +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + _filter_args: &'tcx [hir::Expr<'_>], + _map_args: &'tcx [hir::Expr<'_>], +) { + // lint if caller of `.filter_map().map()` is an Iterator + if match_trait_method(cx, expr, &paths::ITERATOR) { + let msg = "called `filter_map(..).map(..)` on an `Iterator`"; + let hint = "this is more succinctly expressed by only calling `.filter_map(..)` instead"; + span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 61d562cbc2844..2e5dc857b4419 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5,6 +5,7 @@ mod expect_used; mod filetype_is_file; mod filter_map; mod filter_map_identity; +mod filter_map_map; mod filter_next; mod from_iter_instead_of_collect; mod get_unwrap; @@ -1700,7 +1701,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["next", "skip_while"] => skip_while_next::check(cx, expr, arg_lists[1]), ["next", "iter"] => iter_next_slice::check(cx, expr, arg_lists[1]), ["map", "filter"] => filter_map::check(cx, expr, false), - ["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]), + ["map", "filter_map"] => filter_map_map::check(cx, expr, arg_lists[1], arg_lists[0]), ["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1], self.msrv.as_ref()), ["map", "find"] => filter_map::check(cx, expr, true), ["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]), @@ -2785,21 +2786,6 @@ fn lint_filter_map_next<'tcx>( } } -/// lint use of `filter_map().map()` for `Iterators` -fn lint_filter_map_map<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - _filter_args: &'tcx [hir::Expr<'_>], - _map_args: &'tcx [hir::Expr<'_>], -) { - // lint if caller of `.filter_map().map()` is an Iterator - if match_trait_method(cx, expr, &paths::ITERATOR) { - let msg = "called `filter_map(..).map(..)` on an `Iterator`"; - let hint = "this is more succinctly expressed by only calling `.filter_map(..)` instead"; - span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint); - } -} - /// lint use of `filter().flat_map()` for `Iterators` fn lint_filter_flat_map<'tcx>( cx: &LateContext<'tcx>, From 2baf043c374396dea3354eb8bc56af7539bf30b4 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:11:42 +0900 Subject: [PATCH 199/226] move filter_map_next to its own module --- clippy_lints/src/methods/filter_map_next.rs | 40 +++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 37 ++----------------- 2 files changed, 42 insertions(+), 35 deletions(-) create mode 100644 clippy_lints/src/methods/filter_map_next.rs diff --git a/clippy_lints/src/methods/filter_map_next.rs b/clippy_lints/src/methods/filter_map_next.rs new file mode 100644 index 0000000000000..a789df922ffdb --- /dev/null +++ b/clippy_lints/src/methods/filter_map_next.rs @@ -0,0 +1,40 @@ +use crate::utils::{match_trait_method, meets_msrv, paths, snippet, span_lint, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_semver::RustcVersion; + +use super::FILTER_MAP_NEXT; + +const FILTER_MAP_NEXT_MSRV: RustcVersion = RustcVersion::new(1, 30, 0); + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + filter_args: &'tcx [hir::Expr<'_>], + msrv: Option<&RustcVersion>, +) { + if match_trait_method(cx, expr, &paths::ITERATOR) { + if !meets_msrv(msrv, &FILTER_MAP_NEXT_MSRV) { + return; + } + + let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \ + `.find_map(..)` instead"; + let filter_snippet = snippet(cx, filter_args[1].span, ".."); + if filter_snippet.lines().count() <= 1 { + let iter_snippet = snippet(cx, filter_args[0].span, ".."); + span_lint_and_sugg( + cx, + FILTER_MAP_NEXT, + expr.span, + msg, + "try this", + format!("{}.find_map({})", iter_snippet, filter_snippet), + Applicability::MachineApplicable, + ); + } else { + span_lint(cx, FILTER_MAP_NEXT, expr.span, msg); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 2e5dc857b4419..fe1327564b20c 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -6,6 +6,7 @@ mod filetype_is_file; mod filter_map; mod filter_map_identity; mod filter_map_map; +mod filter_map_next; mod filter_next; mod from_iter_instead_of_collect; mod get_unwrap; @@ -1702,7 +1703,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["next", "iter"] => iter_next_slice::check(cx, expr, arg_lists[1]), ["map", "filter"] => filter_map::check(cx, expr, false), ["map", "filter_map"] => filter_map_map::check(cx, expr, arg_lists[1], arg_lists[0]), - ["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1], self.msrv.as_ref()), + ["next", "filter_map"] => filter_map_next::check(cx, expr, arg_lists[1], self.msrv.as_ref()), ["map", "find"] => filter_map::check(cx, expr, true), ["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]), @@ -2752,40 +2753,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -const FILTER_MAP_NEXT_MSRV: RustcVersion = RustcVersion::new(1, 30, 0); - -/// lint use of `filter_map().next()` for `Iterators` -fn lint_filter_map_next<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - filter_args: &'tcx [hir::Expr<'_>], - msrv: Option<&RustcVersion>, -) { - if match_trait_method(cx, expr, &paths::ITERATOR) { - if !meets_msrv(msrv, &FILTER_MAP_NEXT_MSRV) { - return; - } - - let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \ - `.find_map(..)` instead"; - let filter_snippet = snippet(cx, filter_args[1].span, ".."); - if filter_snippet.lines().count() <= 1 { - let iter_snippet = snippet(cx, filter_args[0].span, ".."); - span_lint_and_sugg( - cx, - FILTER_MAP_NEXT, - expr.span, - msg, - "try this", - format!("{}.find_map({})", iter_snippet, filter_snippet), - Applicability::MachineApplicable, - ); - } else { - span_lint(cx, FILTER_MAP_NEXT, expr.span, msg); - } - } -} - /// lint use of `filter().flat_map()` for `Iterators` fn lint_filter_flat_map<'tcx>( cx: &LateContext<'tcx>, From 6d941616f925298124eabe3ca10e48ec10bb33a9 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:19:18 +0900 Subject: [PATCH 200/226] move filter_flat_map to its own module --- clippy_lints/src/methods/filter_flat_map.rs | 21 +++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 19 ++----------------- 2 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 clippy_lints/src/methods/filter_flat_map.rs diff --git a/clippy_lints/src/methods/filter_flat_map.rs b/clippy_lints/src/methods/filter_flat_map.rs new file mode 100644 index 0000000000000..8da867fce515c --- /dev/null +++ b/clippy_lints/src/methods/filter_flat_map.rs @@ -0,0 +1,21 @@ +use crate::utils::{match_trait_method, paths, span_lint_and_help}; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::FILTER_MAP; + +/// lint use of `filter().flat_map()` for `Iterators` +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + _filter_args: &'tcx [hir::Expr<'_>], + _map_args: &'tcx [hir::Expr<'_>], +) { + // lint if caller of `.filter().flat_map()` is an Iterator + if match_trait_method(cx, expr, &paths::ITERATOR) { + let msg = "called `filter(..).flat_map(..)` on an `Iterator`"; + let hint = "this is more succinctly expressed by calling `.flat_map(..)` \ + and filtering by returning `iter::empty()`"; + span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index fe1327564b20c..3251a49da099b 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -3,6 +3,7 @@ mod bytes_nth; mod clone_on_ref_ptr; mod expect_used; mod filetype_is_file; +mod filter_flat_map; mod filter_map; mod filter_map_identity; mod filter_map_map; @@ -1705,7 +1706,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["map", "filter_map"] => filter_map_map::check(cx, expr, arg_lists[1], arg_lists[0]), ["next", "filter_map"] => filter_map_next::check(cx, expr, arg_lists[1], self.msrv.as_ref()), ["map", "find"] => filter_map::check(cx, expr, true), - ["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]), + ["flat_map", "filter"] => filter_flat_map::check(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", ..] => lint_flat_map_identity(cx, expr, arg_lists[0], method_spans[0]), ["flatten", "map"] => lint_map_flatten(cx, expr, arg_lists[1]), @@ -2753,22 +2754,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -/// lint use of `filter().flat_map()` for `Iterators` -fn lint_filter_flat_map<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - _filter_args: &'tcx [hir::Expr<'_>], - _map_args: &'tcx [hir::Expr<'_>], -) { - // lint if caller of `.filter().flat_map()` is an Iterator - if match_trait_method(cx, expr, &paths::ITERATOR) { - let msg = "called `filter(..).flat_map(..)` on an `Iterator`"; - let hint = "this is more succinctly expressed by calling `.flat_map(..)` \ - and filtering by returning `iter::empty()`"; - span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint); - } -} - /// lint use of `filter_map().flat_map()` for `Iterators` fn lint_filter_map_flat_map<'tcx>( cx: &LateContext<'tcx>, From f430384f04ee3ee62156a9e3060ba4d9054278b5 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:22:15 +0900 Subject: [PATCH 201/226] move filter_map_flat_map to its own module --- .../src/methods/filter_map_flat_map.rs | 21 +++++++++++++++++++ clippy_lints/src/methods/mod.rs | 19 ++--------------- 2 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 clippy_lints/src/methods/filter_map_flat_map.rs diff --git a/clippy_lints/src/methods/filter_map_flat_map.rs b/clippy_lints/src/methods/filter_map_flat_map.rs new file mode 100644 index 0000000000000..a6db138623a8c --- /dev/null +++ b/clippy_lints/src/methods/filter_map_flat_map.rs @@ -0,0 +1,21 @@ +use crate::utils::{match_trait_method, paths, span_lint_and_help}; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::FILTER_MAP; + +/// lint use of `filter_map().flat_map()` for `Iterators` +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + _filter_args: &'tcx [hir::Expr<'_>], + _map_args: &'tcx [hir::Expr<'_>], +) { + // lint if caller of `.filter_map().flat_map()` is an Iterator + if match_trait_method(cx, expr, &paths::ITERATOR) { + let msg = "called `filter_map(..).flat_map(..)` on an `Iterator`"; + let hint = "this is more succinctly expressed by calling `.flat_map(..)` \ + and filtering by returning `iter::empty()`"; + span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 3251a49da099b..34e1463f6305f 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5,6 +5,7 @@ mod expect_used; mod filetype_is_file; mod filter_flat_map; mod filter_map; +mod filter_map_flat_map; mod filter_map_identity; mod filter_map_map; mod filter_map_next; @@ -1707,7 +1708,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["next", "filter_map"] => filter_map_next::check(cx, expr, arg_lists[1], self.msrv.as_ref()), ["map", "find"] => filter_map::check(cx, expr, true), ["flat_map", "filter"] => filter_flat_map::check(cx, expr, arg_lists[1], arg_lists[0]), - ["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]), + ["flat_map", "filter_map"] => filter_map_flat_map::check(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", ..] => lint_flat_map_identity(cx, expr, arg_lists[0], method_spans[0]), ["flatten", "map"] => lint_map_flatten(cx, expr, arg_lists[1]), ["is_some", "find"] => lint_search_is_some(cx, expr, "find", arg_lists[1], arg_lists[0], method_spans[1]), @@ -2754,22 +2755,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -/// lint use of `filter_map().flat_map()` for `Iterators` -fn lint_filter_map_flat_map<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - _filter_args: &'tcx [hir::Expr<'_>], - _map_args: &'tcx [hir::Expr<'_>], -) { - // lint if caller of `.filter_map().flat_map()` is an Iterator - if match_trait_method(cx, expr, &paths::ITERATOR) { - let msg = "called `filter_map(..).flat_map(..)` on an `Iterator`"; - let hint = "this is more succinctly expressed by calling `.flat_map(..)` \ - and filtering by returning `iter::empty()`"; - span_lint_and_help(cx, FILTER_MAP, expr.span, msg, None, hint); - } -} - /// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient fn lint_flat_map_identity<'tcx>( cx: &LateContext<'tcx>, From 37ba779a532cd229a18e8a99342f351ba035aa30 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:30:40 +0900 Subject: [PATCH 202/226] move flat_map_identity to its own module --- clippy_lints/src/methods/flat_map_identity.rs | 57 +++++++++++++++++++ clippy_lints/src/methods/mod.rs | 52 +---------------- 2 files changed, 59 insertions(+), 50 deletions(-) create mode 100644 clippy_lints/src/methods/flat_map_identity.rs diff --git a/clippy_lints/src/methods/flat_map_identity.rs b/clippy_lints/src/methods/flat_map_identity.rs new file mode 100644 index 0000000000000..ce3194f8a2373 --- /dev/null +++ b/clippy_lints/src/methods/flat_map_identity.rs @@ -0,0 +1,57 @@ +use crate::utils::{match_qpath, match_trait_method, paths, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::source_map::Span; + +use super::FLAT_MAP_IDENTITY; + +/// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + flat_map_args: &'tcx [hir::Expr<'_>], + flat_map_span: Span, +) { + if match_trait_method(cx, expr, &paths::ITERATOR) { + let arg_node = &flat_map_args[1].kind; + + let apply_lint = |message: &str| { + span_lint_and_sugg( + cx, + FLAT_MAP_IDENTITY, + flat_map_span.with_hi(expr.span.hi()), + message, + "try", + "flatten()".to_string(), + Applicability::MachineApplicable, + ); + }; + + if_chain! { + if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node; + let body = cx.tcx.hir().body(*body_id); + + if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind; + if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = body.value.kind; + + if path.segments.len() == 1; + if path.segments[0].ident.name == binding_ident.name; + + then { + apply_lint("called `flat_map(|x| x)` on an `Iterator`"); + } + } + + if_chain! { + if let hir::ExprKind::Path(ref qpath) = arg_node; + + if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY); + + then { + apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`"); + } + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 34e1463f6305f..6a425e6e3ed0b 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -10,6 +10,7 @@ mod filter_map_identity; mod filter_map_map; mod filter_map_next; mod filter_next; +mod flat_map_identity; mod from_iter_instead_of_collect; mod get_unwrap; mod implicit_clone; @@ -1709,7 +1710,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["map", "find"] => filter_map::check(cx, expr, true), ["flat_map", "filter"] => filter_flat_map::check(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", "filter_map"] => filter_map_flat_map::check(cx, expr, arg_lists[1], arg_lists[0]), - ["flat_map", ..] => lint_flat_map_identity(cx, expr, arg_lists[0], method_spans[0]), + ["flat_map", ..] => flat_map_identity::check(cx, expr, arg_lists[0], method_spans[0]), ["flatten", "map"] => lint_map_flatten(cx, expr, arg_lists[1]), ["is_some", "find"] => lint_search_is_some(cx, expr, "find", arg_lists[1], arg_lists[0], method_spans[1]), ["is_some", "position"] => { @@ -2755,55 +2756,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -/// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient -fn lint_flat_map_identity<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - flat_map_args: &'tcx [hir::Expr<'_>], - flat_map_span: Span, -) { - if match_trait_method(cx, expr, &paths::ITERATOR) { - let arg_node = &flat_map_args[1].kind; - - let apply_lint = |message: &str| { - span_lint_and_sugg( - cx, - FLAT_MAP_IDENTITY, - flat_map_span.with_hi(expr.span.hi()), - message, - "try", - "flatten()".to_string(), - Applicability::MachineApplicable, - ); - }; - - if_chain! { - if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node; - let body = cx.tcx.hir().body(*body_id); - - if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind; - if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = body.value.kind; - - if path.segments.len() == 1; - if path.segments[0].ident.name == binding_ident.name; - - then { - apply_lint("called `flat_map(|x| x)` on an `Iterator`"); - } - } - - if_chain! { - if let hir::ExprKind::Path(ref qpath) = arg_node; - - if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY); - - then { - apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`"); - } - } - } -} - /// lint searching an Iterator followed by `is_some()` /// or calling `find()` on a string followed by `is_some()` fn lint_search_is_some<'tcx>( From 24909fabd27091a7b363dcbc549636e98ba4a898 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:41:43 +0900 Subject: [PATCH 203/226] move map_flatten and search_is_some to their own modules --- clippy_lints/src/methods/map_flatten.rs | 61 +++++++++ clippy_lints/src/methods/mod.rs | 150 +-------------------- clippy_lints/src/methods/search_is_some.rs | 101 ++++++++++++++ 3 files changed, 168 insertions(+), 144 deletions(-) create mode 100644 clippy_lints/src/methods/map_flatten.rs create mode 100644 clippy_lints/src/methods/search_is_some.rs diff --git a/clippy_lints/src/methods/map_flatten.rs b/clippy_lints/src/methods/map_flatten.rs new file mode 100644 index 0000000000000..14a14e4f9ecd1 --- /dev/null +++ b/clippy_lints/src/methods/map_flatten.rs @@ -0,0 +1,61 @@ +use crate::utils::{is_type_diagnostic_item, match_trait_method, paths, snippet, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::symbol::sym; + +use super::MAP_FLATTEN; + +/// lint use of `map().flatten()` for `Iterators` and 'Options' +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_args: &'tcx [hir::Expr<'_>]) { + // lint if caller of `.map().flatten()` is an Iterator + if match_trait_method(cx, expr, &paths::ITERATOR) { + let map_closure_ty = cx.typeck_results().expr_ty(&map_args[1]); + let is_map_to_option = match map_closure_ty.kind() { + ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(_) => { + let map_closure_sig = match map_closure_ty.kind() { + ty::Closure(_, substs) => substs.as_closure().sig(), + _ => map_closure_ty.fn_sig(cx.tcx), + }; + let map_closure_return_ty = cx.tcx.erase_late_bound_regions(map_closure_sig.output()); + is_type_diagnostic_item(cx, map_closure_return_ty, sym::option_type) + }, + _ => false, + }; + + let method_to_use = if is_map_to_option { + // `(...).map(...)` has type `impl Iterator> + "filter_map" + } else { + // `(...).map(...)` has type `impl Iterator> + "flat_map" + }; + let func_snippet = snippet(cx, map_args[1].span, ".."); + let hint = format!(".{0}({1})", method_to_use, func_snippet); + span_lint_and_sugg( + cx, + MAP_FLATTEN, + expr.span.with_lo(map_args[0].span.hi()), + "called `map(..).flatten()` on an `Iterator`", + &format!("try using `{}` instead", method_to_use), + hint, + Applicability::MachineApplicable, + ); + } + + // lint if caller of `.map().flatten()` is an Option + if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::option_type) { + let func_snippet = snippet(cx, map_args[1].span, ".."); + let hint = format!(".and_then({})", func_snippet); + span_lint_and_sugg( + cx, + MAP_FLATTEN, + expr.span.with_lo(map_args[0].span.hi()), + "called `map(..).flatten()` on an `Option`", + "try using `and_then` instead", + hint, + Applicability::MachineApplicable, + ); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 6a425e6e3ed0b..2b8bb0b4216c7 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -25,9 +25,11 @@ mod iter_nth_zero; mod iterator_step_by_zero; mod manual_saturating_arithmetic; mod map_collect_result_unit; +mod map_flatten; mod ok_expect; mod option_as_ref_deref; mod option_map_unwrap_or; +mod search_is_some; mod single_char_insert_string; mod single_char_pattern; mod single_char_push_string; @@ -1711,13 +1713,13 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["flat_map", "filter"] => filter_flat_map::check(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", "filter_map"] => filter_map_flat_map::check(cx, expr, arg_lists[1], arg_lists[0]), ["flat_map", ..] => flat_map_identity::check(cx, expr, arg_lists[0], method_spans[0]), - ["flatten", "map"] => lint_map_flatten(cx, expr, arg_lists[1]), - ["is_some", "find"] => lint_search_is_some(cx, expr, "find", arg_lists[1], arg_lists[0], method_spans[1]), + ["flatten", "map"] => map_flatten::check(cx, expr, arg_lists[1]), + ["is_some", "find"] => search_is_some::check(cx, expr, "find", arg_lists[1], arg_lists[0], method_spans[1]), ["is_some", "position"] => { - lint_search_is_some(cx, expr, "position", arg_lists[1], arg_lists[0], method_spans[1]) + search_is_some::check(cx, expr, "position", arg_lists[1], arg_lists[0], method_spans[1]) }, ["is_some", "rposition"] => { - lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) + search_is_some::check(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1]) }, ["extend", ..] => string_extend_chars::check(cx, expr, arg_lists[0]), ["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"), @@ -2566,59 +2568,6 @@ fn derefs_to_slice<'tcx>( } } -/// lint use of `map().flatten()` for `Iterators` and 'Options' -fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_args: &'tcx [hir::Expr<'_>]) { - // lint if caller of `.map().flatten()` is an Iterator - if match_trait_method(cx, expr, &paths::ITERATOR) { - let map_closure_ty = cx.typeck_results().expr_ty(&map_args[1]); - let is_map_to_option = match map_closure_ty.kind() { - ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(_) => { - let map_closure_sig = match map_closure_ty.kind() { - ty::Closure(_, substs) => substs.as_closure().sig(), - _ => map_closure_ty.fn_sig(cx.tcx), - }; - let map_closure_return_ty = cx.tcx.erase_late_bound_regions(map_closure_sig.output()); - is_type_diagnostic_item(cx, map_closure_return_ty, sym::option_type) - }, - _ => false, - }; - - let method_to_use = if is_map_to_option { - // `(...).map(...)` has type `impl Iterator> - "filter_map" - } else { - // `(...).map(...)` has type `impl Iterator> - "flat_map" - }; - let func_snippet = snippet(cx, map_args[1].span, ".."); - let hint = format!(".{0}({1})", method_to_use, func_snippet); - span_lint_and_sugg( - cx, - MAP_FLATTEN, - expr.span.with_lo(map_args[0].span.hi()), - "called `map(..).flatten()` on an `Iterator`", - &format!("try using `{}` instead", method_to_use), - hint, - Applicability::MachineApplicable, - ); - } - - // lint if caller of `.map().flatten()` is an Option - if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::option_type) { - let func_snippet = snippet(cx, map_args[1].span, ".."); - let hint = format!(".and_then({})", func_snippet); - span_lint_and_sugg( - cx, - MAP_FLATTEN, - expr.span.with_lo(map_args[0].span.hi()), - "called `map(..).flatten()` on an `Option`", - "try using `and_then` instead", - hint, - Applicability::MachineApplicable, - ); - } -} - const MAP_UNWRAP_OR_MSRV: RustcVersion = RustcVersion::new(1, 41, 0); /// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s @@ -2756,93 +2705,6 @@ fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map ); } -/// lint searching an Iterator followed by `is_some()` -/// or calling `find()` on a string followed by `is_some()` -fn lint_search_is_some<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - search_method: &str, - search_args: &'tcx [hir::Expr<'_>], - is_some_args: &'tcx [hir::Expr<'_>], - method_span: Span, -) { - // lint if caller of search is an Iterator - if match_trait_method(cx, &is_some_args[0], &paths::ITERATOR) { - let msg = format!( - "called `is_some()` after searching an `Iterator` with `{}`", - search_method - ); - let hint = "this is more succinctly expressed by calling `any()`"; - let search_snippet = snippet(cx, search_args[1].span, ".."); - if search_snippet.lines().count() <= 1 { - // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()` - // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()` - let any_search_snippet = if_chain! { - if search_method == "find"; - if let hir::ExprKind::Closure(_, _, body_id, ..) = search_args[1].kind; - let closure_body = cx.tcx.hir().body(body_id); - if let Some(closure_arg) = closure_body.params.get(0); - then { - if let hir::PatKind::Ref(..) = closure_arg.pat.kind { - Some(search_snippet.replacen('&', "", 1)) - } else if let PatKind::Binding(_, _, ident, _) = strip_pat_refs(&closure_arg.pat).kind { - let name = &*ident.name.as_str(); - Some(search_snippet.replace(&format!("*{}", name), name)) - } else { - None - } - } else { - None - } - }; - // add note if not multi-line - span_lint_and_sugg( - cx, - SEARCH_IS_SOME, - method_span.with_hi(expr.span.hi()), - &msg, - "use `any()` instead", - format!( - "any({})", - any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) - ), - Applicability::MachineApplicable, - ); - } else { - span_lint_and_help(cx, SEARCH_IS_SOME, expr.span, &msg, None, hint); - } - } - // lint if `find()` is called by `String` or `&str` - else if search_method == "find" { - let is_string_or_str_slice = |e| { - let self_ty = cx.typeck_results().expr_ty(e).peel_refs(); - if is_type_diagnostic_item(cx, self_ty, sym::string_type) { - true - } else { - *self_ty.kind() == ty::Str - } - }; - if_chain! { - if is_string_or_str_slice(&search_args[0]); - if is_string_or_str_slice(&search_args[1]); - then { - let msg = "called `is_some()` after calling `find()` on a string"; - let mut applicability = Applicability::MachineApplicable; - let find_arg = snippet_with_applicability(cx, search_args[1].span, "..", &mut applicability); - span_lint_and_sugg( - cx, - SEARCH_IS_SOME, - method_span.with_hi(expr.span.hi()), - msg, - "use `contains()` instead", - format!("contains({})", find_arg), - applicability, - ); - } - } - } -} - /// Used for `lint_binary_expr_with_method_call`. #[derive(Copy, Clone)] struct BinaryExprInfo<'a> { diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs new file mode 100644 index 0000000000000..e9e654432208d --- /dev/null +++ b/clippy_lints/src/methods/search_is_some.rs @@ -0,0 +1,101 @@ +use crate::utils::{ + is_type_diagnostic_item, match_trait_method, paths, snippet, snippet_with_applicability, span_lint_and_help, + span_lint_and_sugg, strip_pat_refs, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_hir::PatKind; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::source_map::Span; +use rustc_span::symbol::sym; + +use super::SEARCH_IS_SOME; + +/// lint searching an Iterator followed by `is_some()` +/// or calling `find()` on a string followed by `is_some()` +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + search_method: &str, + search_args: &'tcx [hir::Expr<'_>], + is_some_args: &'tcx [hir::Expr<'_>], + method_span: Span, +) { + // lint if caller of search is an Iterator + if match_trait_method(cx, &is_some_args[0], &paths::ITERATOR) { + let msg = format!( + "called `is_some()` after searching an `Iterator` with `{}`", + search_method + ); + let hint = "this is more succinctly expressed by calling `any()`"; + let search_snippet = snippet(cx, search_args[1].span, ".."); + if search_snippet.lines().count() <= 1 { + // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()` + // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()` + let any_search_snippet = if_chain! { + if search_method == "find"; + if let hir::ExprKind::Closure(_, _, body_id, ..) = search_args[1].kind; + let closure_body = cx.tcx.hir().body(body_id); + if let Some(closure_arg) = closure_body.params.get(0); + then { + if let hir::PatKind::Ref(..) = closure_arg.pat.kind { + Some(search_snippet.replacen('&', "", 1)) + } else if let PatKind::Binding(_, _, ident, _) = strip_pat_refs(&closure_arg.pat).kind { + let name = &*ident.name.as_str(); + Some(search_snippet.replace(&format!("*{}", name), name)) + } else { + None + } + } else { + None + } + }; + // add note if not multi-line + span_lint_and_sugg( + cx, + SEARCH_IS_SOME, + method_span.with_hi(expr.span.hi()), + &msg, + "use `any()` instead", + format!( + "any({})", + any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) + ), + Applicability::MachineApplicable, + ); + } else { + span_lint_and_help(cx, SEARCH_IS_SOME, expr.span, &msg, None, hint); + } + } + // lint if `find()` is called by `String` or `&str` + else if search_method == "find" { + let is_string_or_str_slice = |e| { + let self_ty = cx.typeck_results().expr_ty(e).peel_refs(); + if is_type_diagnostic_item(cx, self_ty, sym::string_type) { + true + } else { + *self_ty.kind() == ty::Str + } + }; + if_chain! { + if is_string_or_str_slice(&search_args[0]); + if is_string_or_str_slice(&search_args[1]); + then { + let msg = "called `is_some()` after calling `find()` on a string"; + let mut applicability = Applicability::MachineApplicable; + let find_arg = snippet_with_applicability(cx, search_args[1].span, "..", &mut applicability); + span_lint_and_sugg( + cx, + SEARCH_IS_SOME, + method_span.with_hi(expr.span.hi()), + msg, + "use `contains()` instead", + format!("contains({})", find_arg), + applicability, + ); + } + } + } +} From 171c4c148540846c8aab4e1f0f491e8bfb892fcf Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:45:25 +0900 Subject: [PATCH 204/226] move iter_skip_next to its own module --- clippy_lints/src/methods/iter_skip_next.rs | 24 ++++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 21 ++----------------- 2 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 clippy_lints/src/methods/iter_skip_next.rs diff --git a/clippy_lints/src/methods/iter_skip_next.rs b/clippy_lints/src/methods/iter_skip_next.rs new file mode 100644 index 0000000000000..5f5969134e490 --- /dev/null +++ b/clippy_lints/src/methods/iter_skip_next.rs @@ -0,0 +1,24 @@ +use crate::utils::{match_trait_method, paths, snippet, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::ITER_SKIP_NEXT; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[hir::Expr<'_>]) { + // lint if caller of skip is an Iterator + if match_trait_method(cx, expr, &paths::ITERATOR) { + if let [caller, n] = skip_args { + let hint = format!(".nth({})", snippet(cx, n.span, "..")); + span_lint_and_sugg( + cx, + ITER_SKIP_NEXT, + expr.span.trim_start(caller.span).unwrap(), + "called `skip(..).next()` on an iterator", + "use `nth` instead", + hint, + Applicability::MachineApplicable, + ); + } + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 2b8bb0b4216c7..927375f9e0b17 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -22,6 +22,7 @@ mod iter_count; mod iter_next_slice; mod iter_nth; mod iter_nth_zero; +mod iter_skip_next; mod iterator_step_by_zero; mod manual_saturating_arithmetic; mod map_collect_result_unit; @@ -1730,7 +1731,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["nth", "bytes"] => bytes_nth::check(cx, expr, &arg_lists[1]), ["nth", ..] => iter_nth_zero::check(cx, expr, arg_lists[0]), ["step_by", ..] => iterator_step_by_zero::check(cx, expr, arg_lists[0]), - ["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]), + ["next", "skip"] => iter_skip_next::check(cx, expr, arg_lists[1]), ["collect", "cloned"] => iter_cloned_collect::check(cx, expr, arg_lists[1]), ["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]), ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]), @@ -2510,24 +2511,6 @@ fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: } } -fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[hir::Expr<'_>]) { - // lint if caller of skip is an Iterator - if match_trait_method(cx, expr, &paths::ITERATOR) { - if let [caller, n] = skip_args { - let hint = format!(".nth({})", snippet(cx, n.span, "..")); - span_lint_and_sugg( - cx, - ITER_SKIP_NEXT, - expr.span.trim_start(caller.span).unwrap(), - "called `skip(..).next()` on an iterator", - "use `nth` instead", - hint, - Applicability::MachineApplicable, - ); - } - } -} - fn derefs_to_slice<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, From caaba8270c7de1bf3446f3345e7e794295db59fd Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:53:31 +0900 Subject: [PATCH 205/226] move clone_on_copy to its own module --- clippy_lints/src/methods/clone_on_copy.rs | 109 ++++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 106 +-------------------- 2 files changed, 112 insertions(+), 103 deletions(-) create mode 100644 clippy_lints/src/methods/clone_on_copy.rs diff --git a/clippy_lints/src/methods/clone_on_copy.rs b/clippy_lints/src/methods/clone_on_copy.rs new file mode 100644 index 0000000000000..4a130ed47db15 --- /dev/null +++ b/clippy_lints/src/methods/clone_on_copy.rs @@ -0,0 +1,109 @@ +use crate::utils::{is_copy, span_lint_and_then, sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; +use std::iter; + +use super::CLONE_DOUBLE_REF; +use super::CLONE_ON_COPY; + +/// Checks for the `CLONE_ON_COPY` lint. +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) { + let ty = cx.typeck_results().expr_ty(expr); + if let ty::Ref(_, inner, _) = arg_ty.kind() { + if let ty::Ref(_, innermost, _) = inner.kind() { + span_lint_and_then( + cx, + CLONE_DOUBLE_REF, + expr.span, + &format!( + "using `clone` on a double-reference; \ + this will copy the reference of type `{}` instead of cloning the inner type", + ty + ), + |diag| { + if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { + let mut ty = innermost; + let mut n = 0; + while let ty::Ref(_, inner, _) = ty.kind() { + ty = inner; + n += 1; + } + let refs: String = iter::repeat('&').take(n + 1).collect(); + let derefs: String = iter::repeat('*').take(n).collect(); + let explicit = format!("<{}{}>::clone({})", refs, ty, snip); + diag.span_suggestion( + expr.span, + "try dereferencing it", + format!("{}({}{}).clone()", refs, derefs, snip.deref()), + Applicability::MaybeIncorrect, + ); + diag.span_suggestion( + expr.span, + "or try being explicit if you are sure, that you want to clone a reference", + explicit, + Applicability::MaybeIncorrect, + ); + } + }, + ); + return; // don't report clone_on_copy + } + } + + if is_copy(cx, ty) { + let snip; + if let Some(snippet) = sugg::Sugg::hir_opt(cx, arg) { + let parent = cx.tcx.hir().get_parent_node(expr.hir_id); + match &cx.tcx.hir().get(parent) { + hir::Node::Expr(parent) => match parent.kind { + // &*x is a nop, &x.clone() is not + hir::ExprKind::AddrOf(..) => return, + // (*x).func() is useless, x.clone().func() can work in case func borrows mutably + hir::ExprKind::MethodCall(_, _, parent_args, _) if expr.hir_id == parent_args[0].hir_id => { + return; + }, + + _ => {}, + }, + hir::Node::Stmt(stmt) => { + if let hir::StmtKind::Local(ref loc) = stmt.kind { + if let hir::PatKind::Ref(..) = loc.pat.kind { + // let ref y = *x borrows x, let ref y = x.clone() does not + return; + } + } + }, + _ => {}, + } + + // x.clone() might have dereferenced x, possibly through Deref impls + if cx.typeck_results().expr_ty(arg) == ty { + snip = Some(("try removing the `clone` call", format!("{}", snippet))); + } else { + let deref_count = cx + .typeck_results() + .expr_adjustments(arg) + .iter() + .filter(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_))) + .count(); + let derefs: String = iter::repeat('*').take(deref_count).collect(); + snip = Some(("try dereferencing it", format!("{}{}", derefs, snippet))); + } + } else { + snip = None; + } + span_lint_and_then( + cx, + CLONE_ON_COPY, + expr.span, + &format!("using `clone` on type `{}` which implements the `Copy` trait", ty), + |diag| { + if let Some((text, snip)) = snip { + diag.span_suggestion(expr.span, text, snip, Applicability::MachineApplicable); + } + }, + ); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 927375f9e0b17..f248a09e18ef3 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1,5 +1,6 @@ mod bind_instead_of_map; mod bytes_nth; +mod clone_on_copy; mod clone_on_ref_ptr; mod expect_used; mod filetype_is_file; @@ -45,7 +46,6 @@ mod wrong_self_convention; mod zst_offset; use std::borrow::Cow; -use std::iter; use bind_instead_of_map::BindInsteadOfMap; use if_chain::if_chain; @@ -69,7 +69,7 @@ use crate::utils::{ is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, - span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg, walk_ptrs_ty_depth, SpanlessEq, + span_lint_and_help, span_lint_and_sugg, strip_pat_refs, walk_ptrs_ty_depth, SpanlessEq, }; declare_clippy_lint! { @@ -1781,7 +1781,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]); if args.len() == 1 && method_call.ident.name == sym::clone { - lint_clone_on_copy(cx, expr, &args[0], self_ty); + clone_on_copy::check(cx, expr, &args[0], self_ty); clone_on_ref_ptr::check(cx, expr, &args[0]); } if args.len() == 1 && method_call.ident.name == sym!(to_string) { @@ -2323,106 +2323,6 @@ fn lint_expect_fun_call( ); } -/// Checks for the `CLONE_ON_COPY` lint. -fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) { - let ty = cx.typeck_results().expr_ty(expr); - if let ty::Ref(_, inner, _) = arg_ty.kind() { - if let ty::Ref(_, innermost, _) = inner.kind() { - span_lint_and_then( - cx, - CLONE_DOUBLE_REF, - expr.span, - &format!( - "using `clone` on a double-reference; \ - this will copy the reference of type `{}` instead of cloning the inner type", - ty - ), - |diag| { - if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { - let mut ty = innermost; - let mut n = 0; - while let ty::Ref(_, inner, _) = ty.kind() { - ty = inner; - n += 1; - } - let refs: String = iter::repeat('&').take(n + 1).collect(); - let derefs: String = iter::repeat('*').take(n).collect(); - let explicit = format!("<{}{}>::clone({})", refs, ty, snip); - diag.span_suggestion( - expr.span, - "try dereferencing it", - format!("{}({}{}).clone()", refs, derefs, snip.deref()), - Applicability::MaybeIncorrect, - ); - diag.span_suggestion( - expr.span, - "or try being explicit if you are sure, that you want to clone a reference", - explicit, - Applicability::MaybeIncorrect, - ); - } - }, - ); - return; // don't report clone_on_copy - } - } - - if is_copy(cx, ty) { - let snip; - if let Some(snippet) = sugg::Sugg::hir_opt(cx, arg) { - let parent = cx.tcx.hir().get_parent_node(expr.hir_id); - match &cx.tcx.hir().get(parent) { - hir::Node::Expr(parent) => match parent.kind { - // &*x is a nop, &x.clone() is not - hir::ExprKind::AddrOf(..) => return, - // (*x).func() is useless, x.clone().func() can work in case func borrows mutably - hir::ExprKind::MethodCall(_, _, parent_args, _) if expr.hir_id == parent_args[0].hir_id => { - return; - }, - - _ => {}, - }, - hir::Node::Stmt(stmt) => { - if let hir::StmtKind::Local(ref loc) = stmt.kind { - if let hir::PatKind::Ref(..) = loc.pat.kind { - // let ref y = *x borrows x, let ref y = x.clone() does not - return; - } - } - }, - _ => {}, - } - - // x.clone() might have dereferenced x, possibly through Deref impls - if cx.typeck_results().expr_ty(arg) == ty { - snip = Some(("try removing the `clone` call", format!("{}", snippet))); - } else { - let deref_count = cx - .typeck_results() - .expr_adjustments(arg) - .iter() - .filter(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_))) - .count(); - let derefs: String = iter::repeat('*').take(deref_count).collect(); - snip = Some(("try dereferencing it", format!("{}{}", derefs, snippet))); - } - } else { - snip = None; - } - span_lint_and_then( - cx, - CLONE_ON_COPY, - expr.span, - &format!("using `clone` on type `{}` which implements the `Copy` trait", ty), - |diag| { - if let Some((text, snip)) = snip { - diag.span_suggestion(expr.span, text, snip, Applicability::MachineApplicable); - } - }, - ); - } -} - fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) { fn check_fold_with_op( cx: &LateContext<'_>, From 78e572c62782b4bd027c23b9d56a14b0b42ba93a Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 18:59:35 +0900 Subject: [PATCH 206/226] move useless_asref to its own module --- clippy_lints/src/methods/mod.rs | 45 +++-------------------- clippy_lints/src/methods/useless_asref.rs | 45 +++++++++++++++++++++++ 2 files changed, 50 insertions(+), 40 deletions(-) create mode 100644 clippy_lints/src/methods/useless_asref.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f248a09e18ef3..eaf247536b6e3 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -42,6 +42,7 @@ mod uninit_assumed_init; mod unnecessary_filter_map; mod unnecessary_lazy_eval; mod unwrap_used; +mod useless_asref; mod wrong_self_convention; mod zst_offset; @@ -65,11 +66,11 @@ use rustc_typeck::hir_ty_to_ty; use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::usage::mutated_variables; use crate::utils::{ - contains_return, contains_ty, get_parent_expr, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, + contains_return, contains_ty, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, - span_lint_and_help, span_lint_and_sugg, strip_pat_refs, walk_ptrs_ty_depth, SpanlessEq, + span_lint_and_help, span_lint_and_sugg, strip_pat_refs, SpanlessEq, }; declare_clippy_lint! { @@ -1733,8 +1734,8 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["step_by", ..] => iterator_step_by_zero::check(cx, expr, arg_lists[0]), ["next", "skip"] => iter_skip_next::check(cx, expr, arg_lists[1]), ["collect", "cloned"] => iter_cloned_collect::check(cx, expr, arg_lists[1]), - ["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]), - ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]), + ["as_ref"] => useless_asref::check(cx, expr, "as_ref", arg_lists[0]), + ["as_mut"] => useless_asref::check(cx, expr, "as_mut", arg_lists[0]), ["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0], method_spans[0]), ["filter_map", ..] => { unnecessary_filter_map::check(cx, expr, arg_lists[0]); @@ -2751,42 +2752,6 @@ fn get_hint_if_single_char_arg( } } -/// Checks for the `USELESS_ASREF` lint. -fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) { - // when we get here, we've already checked that the call name is "as_ref" or "as_mut" - // check if the call is to the actual `AsRef` or `AsMut` trait - if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) { - // check if the type after `as_ref` or `as_mut` is the same as before - let recvr = &as_ref_args[0]; - let rcv_ty = cx.typeck_results().expr_ty(recvr); - let res_ty = cx.typeck_results().expr_ty(expr); - let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty); - let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty); - if base_rcv_ty == base_res_ty && rcv_depth >= res_depth { - // allow the `as_ref` or `as_mut` if it is followed by another method call - if_chain! { - if let Some(parent) = get_parent_expr(cx, expr); - if let hir::ExprKind::MethodCall(_, ref span, _, _) = parent.kind; - if span != &expr.span; - then { - return; - } - } - - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - USELESS_ASREF, - expr.span, - &format!("this call to `{}` does nothing", call_name), - "try this", - snippet_with_applicability(cx, recvr.span, "..", &mut applicability).to_string(), - applicability, - ); - } - } -} - const FN_HEADER: hir::FnHeader = hir::FnHeader { unsafety: hir::Unsafety::Normal, constness: hir::Constness::NotConst, diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs new file mode 100644 index 0000000000000..e4554f8d4897e --- /dev/null +++ b/clippy_lints/src/methods/useless_asref.rs @@ -0,0 +1,45 @@ +use crate::utils::{ + get_parent_expr, match_trait_method, paths, snippet_with_applicability, span_lint_and_sugg, walk_ptrs_ty_depth, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::USELESS_ASREF; + +/// Checks for the `USELESS_ASREF` lint. +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) { + // when we get here, we've already checked that the call name is "as_ref" or "as_mut" + // check if the call is to the actual `AsRef` or `AsMut` trait + if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) { + // check if the type after `as_ref` or `as_mut` is the same as before + let recvr = &as_ref_args[0]; + let rcv_ty = cx.typeck_results().expr_ty(recvr); + let res_ty = cx.typeck_results().expr_ty(expr); + let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty); + let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty); + if base_rcv_ty == base_res_ty && rcv_depth >= res_depth { + // allow the `as_ref` or `as_mut` if it is followed by another method call + if_chain! { + if let Some(parent) = get_parent_expr(cx, expr); + if let hir::ExprKind::MethodCall(_, ref span, _, _) = parent.kind; + if span != &expr.span; + then { + return; + } + } + + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + USELESS_ASREF, + expr.span, + &format!("this call to `{}` does nothing", call_name), + "try this", + snippet_with_applicability(cx, recvr.span, "..", &mut applicability).to_string(), + applicability, + ); + } + } +} From bbed852f6fb82aa85f72fc8b2aeffdb90f409495 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 19:05:51 +0900 Subject: [PATCH 207/226] unnecessary_fold to its own module --- clippy_lints/src/methods/mod.rs | 100 ++---------------- clippy_lints/src/methods/unnecessary_fold.rs | 101 +++++++++++++++++++ 2 files changed, 107 insertions(+), 94 deletions(-) create mode 100644 clippy_lints/src/methods/unnecessary_fold.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index eaf247536b6e3..702c8e76f4992 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -40,6 +40,7 @@ mod string_extend_chars; mod suspicious_map; mod uninit_assumed_init; mod unnecessary_filter_map; +mod unnecessary_fold; mod unnecessary_lazy_eval; mod unwrap_used; mod useless_asref; @@ -53,7 +54,7 @@ use if_chain::if_chain; use rustc_ast::ast; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::{PatKind, TraitItem, TraitItemKind}; +use rustc_hir::{TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass, Lint, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, TraitRef, Ty, TyS}; @@ -67,10 +68,9 @@ use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::usage::mutated_variables; use crate::utils::{ contains_return, contains_ty, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, - is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method, - match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, remove_blocks, return_ty, - single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, - span_lint_and_help, span_lint_and_sugg, strip_pat_refs, SpanlessEq, + is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_type, meets_msrv, + method_calls, method_chain_args, paths, return_ty, single_segment_path, snippet, snippet_with_applicability, + snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, SpanlessEq, }; declare_clippy_lint! { @@ -1736,7 +1736,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["collect", "cloned"] => iter_cloned_collect::check(cx, expr, arg_lists[1]), ["as_ref"] => useless_asref::check(cx, expr, "as_ref", arg_lists[0]), ["as_mut"] => useless_asref::check(cx, expr, "as_mut", arg_lists[0]), - ["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0], method_spans[0]), + ["fold", ..] => unnecessary_fold::check(cx, expr, arg_lists[0], method_spans[0]), ["filter_map", ..] => { unnecessary_filter_map::check(cx, expr, arg_lists[0]); filter_map_identity::check(cx, expr, arg_lists[0], method_spans[0]); @@ -2324,94 +2324,6 @@ fn lint_expect_fun_call( ); } -fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) { - fn check_fold_with_op( - cx: &LateContext<'_>, - expr: &hir::Expr<'_>, - fold_args: &[hir::Expr<'_>], - fold_span: Span, - op: hir::BinOpKind, - replacement_method_name: &str, - replacement_has_args: bool, - ) { - if_chain! { - // Extract the body of the closure passed to fold - if let hir::ExprKind::Closure(_, _, body_id, _, _) = fold_args[2].kind; - let closure_body = cx.tcx.hir().body(body_id); - let closure_expr = remove_blocks(&closure_body.value); - - // Check if the closure body is of the form `acc some_expr(x)` - if let hir::ExprKind::Binary(ref bin_op, ref left_expr, ref right_expr) = closure_expr.kind; - if bin_op.node == op; - - // Extract the names of the two arguments to the closure - if let [param_a, param_b] = closure_body.params; - if let PatKind::Binding(_, first_arg_id, ..) = strip_pat_refs(¶m_a.pat).kind; - if let PatKind::Binding(_, second_arg_id, second_arg_ident, _) = strip_pat_refs(¶m_b.pat).kind; - - if path_to_local_id(left_expr, first_arg_id); - if replacement_has_args || path_to_local_id(right_expr, second_arg_id); - - then { - let mut applicability = Applicability::MachineApplicable; - let sugg = if replacement_has_args { - format!( - "{replacement}(|{s}| {r})", - replacement = replacement_method_name, - s = second_arg_ident, - r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), - ) - } else { - format!( - "{replacement}()", - replacement = replacement_method_name, - ) - }; - - span_lint_and_sugg( - cx, - UNNECESSARY_FOLD, - fold_span.with_hi(expr.span.hi()), - // TODO #2371 don't suggest e.g., .any(|x| f(x)) if we can suggest .any(f) - "this `.fold` can be written more succinctly using another method", - "try", - sugg, - applicability, - ); - } - } - } - - // Check that this is a call to Iterator::fold rather than just some function called fold - if !match_trait_method(cx, expr, &paths::ITERATOR) { - return; - } - - assert!( - fold_args.len() == 3, - "Expected fold_args to have three entries - the receiver, the initial value and the closure" - ); - - // Check if the first argument to .fold is a suitable literal - if let hir::ExprKind::Lit(ref lit) = fold_args[1].kind { - match lit.node { - ast::LitKind::Bool(false) => { - check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Or, "any", true) - }, - ast::LitKind::Bool(true) => { - check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::And, "all", true) - }, - ast::LitKind::Int(0, _) => { - check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Add, "sum", false) - }, - ast::LitKind::Int(1, _) => { - check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Mul, "product", false) - }, - _ => (), - } - } -} - fn derefs_to_slice<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs new file mode 100644 index 0000000000000..a26443f4ee944 --- /dev/null +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -0,0 +1,101 @@ +use crate::utils::{ + match_trait_method, path_to_local_id, paths, remove_blocks, snippet_with_applicability, span_lint_and_sugg, + strip_pat_refs, +}; +use if_chain::if_chain; +use rustc_ast::ast; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_hir::PatKind; +use rustc_lint::LateContext; +use rustc_span::source_map::Span; + +use super::UNNECESSARY_FOLD; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) { + fn check_fold_with_op( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + fold_args: &[hir::Expr<'_>], + fold_span: Span, + op: hir::BinOpKind, + replacement_method_name: &str, + replacement_has_args: bool, + ) { + if_chain! { + // Extract the body of the closure passed to fold + if let hir::ExprKind::Closure(_, _, body_id, _, _) = fold_args[2].kind; + let closure_body = cx.tcx.hir().body(body_id); + let closure_expr = remove_blocks(&closure_body.value); + + // Check if the closure body is of the form `acc some_expr(x)` + if let hir::ExprKind::Binary(ref bin_op, ref left_expr, ref right_expr) = closure_expr.kind; + if bin_op.node == op; + + // Extract the names of the two arguments to the closure + if let [param_a, param_b] = closure_body.params; + if let PatKind::Binding(_, first_arg_id, ..) = strip_pat_refs(¶m_a.pat).kind; + if let PatKind::Binding(_, second_arg_id, second_arg_ident, _) = strip_pat_refs(¶m_b.pat).kind; + + if path_to_local_id(left_expr, first_arg_id); + if replacement_has_args || path_to_local_id(right_expr, second_arg_id); + + then { + let mut applicability = Applicability::MachineApplicable; + let sugg = if replacement_has_args { + format!( + "{replacement}(|{s}| {r})", + replacement = replacement_method_name, + s = second_arg_ident, + r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), + ) + } else { + format!( + "{replacement}()", + replacement = replacement_method_name, + ) + }; + + span_lint_and_sugg( + cx, + UNNECESSARY_FOLD, + fold_span.with_hi(expr.span.hi()), + // TODO #2371 don't suggest e.g., .any(|x| f(x)) if we can suggest .any(f) + "this `.fold` can be written more succinctly using another method", + "try", + sugg, + applicability, + ); + } + } + } + + // Check that this is a call to Iterator::fold rather than just some function called fold + if !match_trait_method(cx, expr, &paths::ITERATOR) { + return; + } + + assert!( + fold_args.len() == 3, + "Expected fold_args to have three entries - the receiver, the initial value and the closure" + ); + + // Check if the first argument to .fold is a suitable literal + if let hir::ExprKind::Lit(ref lit) = fold_args[1].kind { + match lit.node { + ast::LitKind::Bool(false) => { + check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Or, "any", true) + }, + ast::LitKind::Bool(true) => { + check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::And, "all", true) + }, + ast::LitKind::Int(0, _) => { + check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Add, "sum", false) + }, + ast::LitKind::Int(1, _) => { + check_fold_with_op(cx, expr, fold_args, fold_span, hir::BinOpKind::Mul, "product", false) + }, + _ => (), + } + } +} From 5557596926b493f1fdb85aef6bd78941f231f962 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 19:11:52 +0900 Subject: [PATCH 208/226] move option_map_or_none to its own module --- clippy_lints/src/methods/mod.rs | 73 +---------------- .../src/methods/option_map_or_none.rs | 78 +++++++++++++++++++ 2 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 clippy_lints/src/methods/option_map_or_none.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 702c8e76f4992..0c67c3b892b24 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -30,6 +30,7 @@ mod map_collect_result_unit; mod map_flatten; mod ok_expect; mod option_as_ref_deref; +mod option_map_or_none; mod option_map_unwrap_or; mod search_is_some; mod single_char_insert_string; @@ -1692,7 +1693,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "unwrap_or"); } }, - ["map_or", ..] => lint_map_or_none(cx, expr, arg_lists[0]), + ["map_or", ..] => option_map_or_none::check(cx, expr, arg_lists[0]), ["and_then", ..] => { let biom_option_linted = bind_instead_of_map::OptionAndThenSome::check(cx, expr, arg_lists[0]); let biom_result_linted = bind_instead_of_map::ResultAndThenOk::check(cx, expr, arg_lists[0]); @@ -2431,76 +2432,6 @@ fn lint_map_unwrap_or_else<'tcx>( false } -/// lint use of `_.map_or(None, _)` for `Option`s and `Result`s -fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_or_args: &'tcx [hir::Expr<'_>]) { - let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_or_args[0]), sym::option_type); - let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_or_args[0]), sym::result_type); - - // There are two variants of this `map_or` lint: - // (1) using `map_or` as an adapter from `Result` to `Option` - // (2) using `map_or` as a combinator instead of `and_then` - // - // (For this lint) we don't care if any other type calls `map_or` - if !is_option && !is_result { - return; - } - - let (lint_name, msg, instead, hint) = { - let default_arg_is_none = if let hir::ExprKind::Path(ref qpath) = map_or_args[1].kind { - match_qpath(qpath, &paths::OPTION_NONE) - } else { - return; - }; - - if !default_arg_is_none { - // nothing to lint! - return; - } - - let f_arg_is_some = if let hir::ExprKind::Path(ref qpath) = map_or_args[2].kind { - match_qpath(qpath, &paths::OPTION_SOME) - } else { - false - }; - - if is_option { - let self_snippet = snippet(cx, map_or_args[0].span, ".."); - let func_snippet = snippet(cx, map_or_args[2].span, ".."); - let msg = "called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling \ - `and_then(..)` instead"; - ( - OPTION_MAP_OR_NONE, - msg, - "try using `and_then` instead", - format!("{0}.and_then({1})", self_snippet, func_snippet), - ) - } else if f_arg_is_some { - let msg = "called `map_or(None, Some)` on a `Result` value. This can be done more directly by calling \ - `ok()` instead"; - let self_snippet = snippet(cx, map_or_args[0].span, ".."); - ( - RESULT_MAP_OR_INTO_OPTION, - msg, - "try using `ok` instead", - format!("{0}.ok()", self_snippet), - ) - } else { - // nothing to lint! - return; - } - }; - - span_lint_and_sugg( - cx, - lint_name, - expr.span, - msg, - instead, - hint, - Applicability::MachineApplicable, - ); -} - /// Used for `lint_binary_expr_with_method_call`. #[derive(Copy, Clone)] struct BinaryExprInfo<'a> { diff --git a/clippy_lints/src/methods/option_map_or_none.rs b/clippy_lints/src/methods/option_map_or_none.rs new file mode 100644 index 0000000000000..64f6ebc5062ef --- /dev/null +++ b/clippy_lints/src/methods/option_map_or_none.rs @@ -0,0 +1,78 @@ +use crate::utils::{is_type_diagnostic_item, match_qpath, paths, snippet, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +use super::OPTION_MAP_OR_NONE; +use super::RESULT_MAP_OR_INTO_OPTION; + +/// lint use of `_.map_or(None, _)` for `Option`s and `Result`s +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_or_args: &'tcx [hir::Expr<'_>]) { + let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_or_args[0]), sym::option_type); + let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_or_args[0]), sym::result_type); + + // There are two variants of this `map_or` lint: + // (1) using `map_or` as an adapter from `Result` to `Option` + // (2) using `map_or` as a combinator instead of `and_then` + // + // (For this lint) we don't care if any other type calls `map_or` + if !is_option && !is_result { + return; + } + + let (lint_name, msg, instead, hint) = { + let default_arg_is_none = if let hir::ExprKind::Path(ref qpath) = map_or_args[1].kind { + match_qpath(qpath, &paths::OPTION_NONE) + } else { + return; + }; + + if !default_arg_is_none { + // nothing to lint! + return; + } + + let f_arg_is_some = if let hir::ExprKind::Path(ref qpath) = map_or_args[2].kind { + match_qpath(qpath, &paths::OPTION_SOME) + } else { + false + }; + + if is_option { + let self_snippet = snippet(cx, map_or_args[0].span, ".."); + let func_snippet = snippet(cx, map_or_args[2].span, ".."); + let msg = "called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling \ + `and_then(..)` instead"; + ( + OPTION_MAP_OR_NONE, + msg, + "try using `and_then` instead", + format!("{0}.and_then({1})", self_snippet, func_snippet), + ) + } else if f_arg_is_some { + let msg = "called `map_or(None, Some)` on a `Result` value. This can be done more directly by calling \ + `ok()` instead"; + let self_snippet = snippet(cx, map_or_args[0].span, ".."); + ( + RESULT_MAP_OR_INTO_OPTION, + msg, + "try using `ok` instead", + format!("{0}.ok()", self_snippet), + ) + } else { + // nothing to lint! + return; + } + }; + + span_lint_and_sugg( + cx, + lint_name, + expr.span, + msg, + instead, + hint, + Applicability::MachineApplicable, + ); +} From b0824bf75fba159f40e498dd88386174feea5cf5 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 19:31:46 +0900 Subject: [PATCH 209/226] move map_unwrap_or to its own module --- clippy_lints/src/methods/map_unwrap_or.rs | 76 +++++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 75 ++-------------------- 2 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 clippy_lints/src/methods/map_unwrap_or.rs diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs new file mode 100644 index 0000000000000..63b2cf87f32ad --- /dev/null +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -0,0 +1,76 @@ +use crate::utils::usage::mutated_variables; +use crate::utils::{is_type_diagnostic_item, meets_msrv, snippet, span_lint, span_lint_and_sugg}; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_semver::RustcVersion; +use rustc_span::symbol::sym; + +use super::MAP_UNWRAP_OR; + +const MAP_UNWRAP_OR_MSRV: RustcVersion = RustcVersion::new(1, 41, 0); + +/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s +/// Return true if lint triggered +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + map_args: &'tcx [hir::Expr<'_>], + unwrap_args: &'tcx [hir::Expr<'_>], + msrv: Option<&RustcVersion>, +) -> bool { + if !meets_msrv(msrv, &MAP_UNWRAP_OR_MSRV) { + return false; + } + // lint if the caller of `map()` is an `Option` + let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::option_type); + let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::result_type); + + if is_option || is_result { + // Don't make a suggestion that may fail to compile due to mutably borrowing + // the same variable twice. + let map_mutated_vars = mutated_variables(&map_args[0], cx); + let unwrap_mutated_vars = mutated_variables(&unwrap_args[1], cx); + if let (Some(map_mutated_vars), Some(unwrap_mutated_vars)) = (map_mutated_vars, unwrap_mutated_vars) { + if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() { + return false; + } + } else { + return false; + } + + // lint message + let msg = if is_option { + "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling \ + `map_or_else(, )` instead" + } else { + "called `map().unwrap_or_else()` on a `Result` value. This can be done more directly by calling \ + `.map_or_else(, )` instead" + }; + // get snippets for args to map() and unwrap_or_else() + let map_snippet = snippet(cx, map_args[1].span, ".."); + let unwrap_snippet = snippet(cx, unwrap_args[1].span, ".."); + // lint, with note if neither arg is > 1 line and both map() and + // unwrap_or_else() have the same span + let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; + let same_span = map_args[1].span.ctxt() == unwrap_args[1].span.ctxt(); + if same_span && !multiline { + let var_snippet = snippet(cx, map_args[0].span, ".."); + span_lint_and_sugg( + cx, + MAP_UNWRAP_OR, + expr.span, + msg, + "try this", + format!("{}.map_or_else({}, {})", var_snippet, unwrap_snippet, map_snippet), + Applicability::MachineApplicable, + ); + return true; + } else if same_span && multiline { + span_lint(cx, MAP_UNWRAP_OR, expr.span, msg); + return true; + } + } + + false +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 0c67c3b892b24..5f62942530c40 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -28,6 +28,7 @@ mod iterator_step_by_zero; mod manual_saturating_arithmetic; mod map_collect_result_unit; mod map_flatten; +mod map_unwrap_or; mod ok_expect; mod option_as_ref_deref; mod option_map_or_none; @@ -66,11 +67,10 @@ use rustc_span::symbol::{sym, Symbol, SymbolStr}; use rustc_typeck::hir_ty_to_ty; use crate::utils::eager_or_lazy::is_lazyness_candidate; -use crate::utils::usage::mutated_variables; use crate::utils::{ contains_return, contains_ty, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, - is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_type, meets_msrv, - method_calls, method_chain_args, paths, return_ty, single_segment_path, snippet, snippet_with_applicability, + is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_type, method_calls, + method_chain_args, paths, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, SpanlessEq, }; @@ -1689,7 +1689,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ["expect", ..] => expect_used::check(cx, expr, arg_lists[0]), ["unwrap_or", "map"] => option_map_unwrap_or::check(cx, expr, arg_lists[1], arg_lists[0], method_spans[1]), ["unwrap_or_else", "map"] => { - if !lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0], self.msrv.as_ref()) { + if !map_unwrap_or::check(cx, expr, arg_lists[1], arg_lists[0], self.msrv.as_ref()) { unnecessary_lazy_eval::check(cx, expr, arg_lists[0], "unwrap_or"); } }, @@ -2365,73 +2365,6 @@ fn derefs_to_slice<'tcx>( } } -const MAP_UNWRAP_OR_MSRV: RustcVersion = RustcVersion::new(1, 41, 0); - -/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s -/// Return true if lint triggered -fn lint_map_unwrap_or_else<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - map_args: &'tcx [hir::Expr<'_>], - unwrap_args: &'tcx [hir::Expr<'_>], - msrv: Option<&RustcVersion>, -) -> bool { - if !meets_msrv(msrv, &MAP_UNWRAP_OR_MSRV) { - return false; - } - // lint if the caller of `map()` is an `Option` - let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::option_type); - let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::result_type); - - if is_option || is_result { - // Don't make a suggestion that may fail to compile due to mutably borrowing - // the same variable twice. - let map_mutated_vars = mutated_variables(&map_args[0], cx); - let unwrap_mutated_vars = mutated_variables(&unwrap_args[1], cx); - if let (Some(map_mutated_vars), Some(unwrap_mutated_vars)) = (map_mutated_vars, unwrap_mutated_vars) { - if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() { - return false; - } - } else { - return false; - } - - // lint message - let msg = if is_option { - "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling \ - `map_or_else(, )` instead" - } else { - "called `map().unwrap_or_else()` on a `Result` value. This can be done more directly by calling \ - `.map_or_else(, )` instead" - }; - // get snippets for args to map() and unwrap_or_else() - let map_snippet = snippet(cx, map_args[1].span, ".."); - let unwrap_snippet = snippet(cx, unwrap_args[1].span, ".."); - // lint, with note if neither arg is > 1 line and both map() and - // unwrap_or_else() have the same span - let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; - let same_span = map_args[1].span.ctxt() == unwrap_args[1].span.ctxt(); - if same_span && !multiline { - let var_snippet = snippet(cx, map_args[0].span, ".."); - span_lint_and_sugg( - cx, - MAP_UNWRAP_OR, - expr.span, - msg, - "try this", - format!("{}.map_or_else({}, {})", var_snippet, unwrap_snippet, map_snippet), - Applicability::MachineApplicable, - ); - return true; - } else if same_span && multiline { - span_lint(cx, MAP_UNWRAP_OR, expr.span, msg); - return true; - } - } - - false -} - /// Used for `lint_binary_expr_with_method_call`. #[derive(Copy, Clone)] struct BinaryExprInfo<'a> { From f49349bf333001166e3a215b7b2eb5b5cb1c9989 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 19:40:34 +0900 Subject: [PATCH 210/226] move or_fun_call to its own module --- clippy_lints/src/methods/mod.rs | 168 +---------------------- clippy_lints/src/methods/or_fun_call.rs | 173 ++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 163 deletions(-) create mode 100644 clippy_lints/src/methods/or_fun_call.rs diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 5f62942530c40..857c1bf0ec08a 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -33,6 +33,7 @@ mod ok_expect; mod option_as_ref_deref; mod option_map_or_none; mod option_map_unwrap_or; +mod or_fun_call; mod search_is_some; mod single_char_insert_string; mod single_char_pattern; @@ -66,12 +67,11 @@ use rustc_span::source_map::Span; use rustc_span::symbol::{sym, Symbol, SymbolStr}; use rustc_typeck::hir_ty_to_ty; -use crate::utils::eager_or_lazy::is_lazyness_candidate; use crate::utils::{ contains_return, contains_ty, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, - is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_type, method_calls, - method_chain_args, paths, return_ty, single_segment_path, snippet, snippet_with_applicability, - snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, SpanlessEq, + is_type_diagnostic_item, iter_input_pats, match_def_path, match_qpath, method_calls, method_chain_args, paths, + return_ty, single_segment_path, snippet, snippet_with_applicability, span_lint, span_lint_and_help, + span_lint_and_sugg, SpanlessEq, }; declare_clippy_lint! { @@ -1778,7 +1778,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } }, hir::ExprKind::MethodCall(ref method_call, ref method_span, ref args, _) => { - lint_or_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args); + or_fun_call::check(cx, expr, *method_span, &method_call.ident.as_str(), args); lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args); let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]); @@ -1973,164 +1973,6 @@ impl<'tcx> LateLintPass<'tcx> for Methods { extract_msrv_attr!(LateContext); } -/// Checks for the `OR_FUN_CALL` lint. -#[allow(clippy::too_many_lines)] -fn lint_or_fun_call<'tcx>( - cx: &LateContext<'tcx>, - expr: &hir::Expr<'_>, - method_span: Span, - name: &str, - args: &'tcx [hir::Expr<'_>], -) { - /// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`. - fn check_unwrap_or_default( - cx: &LateContext<'_>, - name: &str, - fun: &hir::Expr<'_>, - self_expr: &hir::Expr<'_>, - arg: &hir::Expr<'_>, - or_has_args: bool, - span: Span, - ) -> bool { - if_chain! { - if !or_has_args; - if name == "unwrap_or"; - if let hir::ExprKind::Path(ref qpath) = fun.kind; - let path = &*last_path_segment(qpath).ident.as_str(); - if ["default", "new"].contains(&path); - let arg_ty = cx.typeck_results().expr_ty(arg); - if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT); - if implements_trait(cx, arg_ty, default_trait_id, &[]); - - then { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - OR_FUN_CALL, - span, - &format!("use of `{}` followed by a call to `{}`", name, path), - "try this", - format!( - "{}.unwrap_or_default()", - snippet_with_applicability(cx, self_expr.span, "..", &mut applicability) - ), - applicability, - ); - - true - } else { - false - } - } - } - - /// Checks for `*or(foo())`. - #[allow(clippy::too_many_arguments)] - fn check_general_case<'tcx>( - cx: &LateContext<'tcx>, - name: &str, - method_span: Span, - self_expr: &hir::Expr<'_>, - arg: &'tcx hir::Expr<'_>, - span: Span, - // None if lambda is required - fun_span: Option, - ) { - // (path, fn_has_argument, methods, suffix) - static KNOW_TYPES: [(&[&str], bool, &[&str], &str); 4] = [ - (&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"), - (&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"), - (&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"), - (&paths::RESULT, true, &["or", "unwrap_or"], "else"), - ]; - - if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = &arg.kind { - if path.ident.as_str() == "len" { - let ty = cx.typeck_results().expr_ty(&args[0]).peel_refs(); - - match ty.kind() { - ty::Slice(_) | ty::Array(_, _) => return, - _ => (), - } - - if is_type_diagnostic_item(cx, ty, sym::vec_type) { - return; - } - } - } - - if_chain! { - if KNOW_TYPES.iter().any(|k| k.2.contains(&name)); - - if is_lazyness_candidate(cx, arg); - if !contains_return(&arg); - - let self_ty = cx.typeck_results().expr_ty(self_expr); - - if let Some(&(_, fn_has_arguments, poss, suffix)) = - KNOW_TYPES.iter().find(|&&i| match_type(cx, self_ty, i.0)); - - if poss.contains(&name); - - then { - let macro_expanded_snipped; - let sugg: Cow<'_, str> = { - let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) { - (false, Some(fun_span)) => (fun_span, false), - _ => (arg.span, true), - }; - let snippet = { - let not_macro_argument_snippet = snippet_with_macro_callsite(cx, snippet_span, ".."); - if not_macro_argument_snippet == "vec![]" { - macro_expanded_snipped = snippet(cx, snippet_span, ".."); - match macro_expanded_snipped.strip_prefix("$crate::vec::") { - Some(stripped) => Cow::from(stripped), - None => macro_expanded_snipped - } - } - else { - not_macro_argument_snippet - } - }; - - if use_lambda { - let l_arg = if fn_has_arguments { "_" } else { "" }; - format!("|{}| {}", l_arg, snippet).into() - } else { - snippet - } - }; - let span_replace_word = method_span.with_hi(span.hi()); - span_lint_and_sugg( - cx, - OR_FUN_CALL, - span_replace_word, - &format!("use of `{}` followed by a function call", name), - "try this", - format!("{}_{}({})", name, suffix, sugg), - Applicability::HasPlaceholders, - ); - } - } - } - - if args.len() == 2 { - match args[1].kind { - hir::ExprKind::Call(ref fun, ref or_args) => { - let or_has_args = !or_args.is_empty(); - if !check_unwrap_or_default(cx, name, fun, &args[0], &args[1], or_has_args, expr.span) { - let fun_span = if or_has_args { None } else { Some(fun.span) }; - check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, fun_span); - } - }, - hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => { - check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None); - }, - _ => {}, - } - } -} - /// Checks for the `EXPECT_FUN_CALL` lint. #[allow(clippy::too_many_lines)] fn lint_expect_fun_call( diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs new file mode 100644 index 0000000000000..5f7fc431d2248 --- /dev/null +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -0,0 +1,173 @@ +use crate::utils::eager_or_lazy::is_lazyness_candidate; +use crate::utils::{ + contains_return, get_trait_def_id, implements_trait, is_type_diagnostic_item, last_path_segment, match_type, paths, + snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint_and_sugg, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::source_map::Span; +use rustc_span::symbol::sym; +use std::borrow::Cow; + +use super::OR_FUN_CALL; + +/// Checks for the `OR_FUN_CALL` lint. +#[allow(clippy::too_many_lines)] +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &hir::Expr<'_>, + method_span: Span, + name: &str, + args: &'tcx [hir::Expr<'_>], +) { + /// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`. + fn check_unwrap_or_default( + cx: &LateContext<'_>, + name: &str, + fun: &hir::Expr<'_>, + self_expr: &hir::Expr<'_>, + arg: &hir::Expr<'_>, + or_has_args: bool, + span: Span, + ) -> bool { + if_chain! { + if !or_has_args; + if name == "unwrap_or"; + if let hir::ExprKind::Path(ref qpath) = fun.kind; + let path = &*last_path_segment(qpath).ident.as_str(); + if ["default", "new"].contains(&path); + let arg_ty = cx.typeck_results().expr_ty(arg); + if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT); + if implements_trait(cx, arg_ty, default_trait_id, &[]); + + then { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + OR_FUN_CALL, + span, + &format!("use of `{}` followed by a call to `{}`", name, path), + "try this", + format!( + "{}.unwrap_or_default()", + snippet_with_applicability(cx, self_expr.span, "..", &mut applicability) + ), + applicability, + ); + + true + } else { + false + } + } + } + + /// Checks for `*or(foo())`. + #[allow(clippy::too_many_arguments)] + fn check_general_case<'tcx>( + cx: &LateContext<'tcx>, + name: &str, + method_span: Span, + self_expr: &hir::Expr<'_>, + arg: &'tcx hir::Expr<'_>, + span: Span, + // None if lambda is required + fun_span: Option, + ) { + // (path, fn_has_argument, methods, suffix) + static KNOW_TYPES: [(&[&str], bool, &[&str], &str); 4] = [ + (&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"), + (&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"), + (&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"), + (&paths::RESULT, true, &["or", "unwrap_or"], "else"), + ]; + + if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = &arg.kind { + if path.ident.as_str() == "len" { + let ty = cx.typeck_results().expr_ty(&args[0]).peel_refs(); + + match ty.kind() { + ty::Slice(_) | ty::Array(_, _) => return, + _ => (), + } + + if is_type_diagnostic_item(cx, ty, sym::vec_type) { + return; + } + } + } + + if_chain! { + if KNOW_TYPES.iter().any(|k| k.2.contains(&name)); + + if is_lazyness_candidate(cx, arg); + if !contains_return(&arg); + + let self_ty = cx.typeck_results().expr_ty(self_expr); + + if let Some(&(_, fn_has_arguments, poss, suffix)) = + KNOW_TYPES.iter().find(|&&i| match_type(cx, self_ty, i.0)); + + if poss.contains(&name); + + then { + let macro_expanded_snipped; + let sugg: Cow<'_, str> = { + let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) { + (false, Some(fun_span)) => (fun_span, false), + _ => (arg.span, true), + }; + let snippet = { + let not_macro_argument_snippet = snippet_with_macro_callsite(cx, snippet_span, ".."); + if not_macro_argument_snippet == "vec![]" { + macro_expanded_snipped = snippet(cx, snippet_span, ".."); + match macro_expanded_snipped.strip_prefix("$crate::vec::") { + Some(stripped) => Cow::from(stripped), + None => macro_expanded_snipped + } + } + else { + not_macro_argument_snippet + } + }; + + if use_lambda { + let l_arg = if fn_has_arguments { "_" } else { "" }; + format!("|{}| {}", l_arg, snippet).into() + } else { + snippet + } + }; + let span_replace_word = method_span.with_hi(span.hi()); + span_lint_and_sugg( + cx, + OR_FUN_CALL, + span_replace_word, + &format!("use of `{}` followed by a function call", name), + "try this", + format!("{}_{}({})", name, suffix, sugg), + Applicability::HasPlaceholders, + ); + } + } + } + + if args.len() == 2 { + match args[1].kind { + hir::ExprKind::Call(ref fun, ref or_args) => { + let or_has_args = !or_args.is_empty(); + if !check_unwrap_or_default(cx, name, fun, &args[0], &args[1], or_has_args, expr.span) { + let fun_span = if or_has_args { None } else { Some(fun.span) }; + check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, fun_span); + } + }, + hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => { + check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None); + }, + _ => {}, + } + } +} From c711de28ee903c78ad465f6af99afdb977ab8dfe Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sat, 6 Mar 2021 22:26:29 +0900 Subject: [PATCH 211/226] move expect_fun_call to its own module --- clippy_lints/src/methods/expect_fun_call.rs | 199 +++++++++++++++++++ clippy_lints/src/methods/mod.rs | 206 +------------------- 2 files changed, 204 insertions(+), 201 deletions(-) create mode 100644 clippy_lints/src/methods/expect_fun_call.rs diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs new file mode 100644 index 0000000000000..6866e9c652ab3 --- /dev/null +++ b/clippy_lints/src/methods/expect_fun_call.rs @@ -0,0 +1,199 @@ +use crate::utils::{is_expn_of, is_type_diagnostic_item, snippet, snippet_with_applicability, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::source_map::Span; +use rustc_span::symbol::sym; +use std::borrow::Cow; + +use super::EXPECT_FUN_CALL; + +/// Checks for the `EXPECT_FUN_CALL` lint. +#[allow(clippy::too_many_lines)] +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_span: Span, name: &str, args: &[hir::Expr<'_>]) { + // Strip `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or + // `&str` + fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { + let mut arg_root = arg; + loop { + arg_root = match &arg_root.kind { + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr, + hir::ExprKind::MethodCall(method_name, _, call_args, _) => { + if call_args.len() == 1 + && (method_name.ident.name == sym::as_str || method_name.ident.name == sym!(as_ref)) + && { + let arg_type = cx.typeck_results().expr_ty(&call_args[0]); + let base_type = arg_type.peel_refs(); + *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::string_type) + } + { + &call_args[0] + } else { + break; + } + }, + _ => break, + }; + } + arg_root + } + + // Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be + // converted to string. + fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { + let arg_ty = cx.typeck_results().expr_ty(arg); + if is_type_diagnostic_item(cx, arg_ty, sym::string_type) { + return false; + } + if let ty::Ref(_, ty, ..) = arg_ty.kind() { + if *ty.kind() == ty::Str && can_be_static_str(cx, arg) { + return false; + } + }; + true + } + + // Check if an expression could have type `&'static str`, knowing that it + // has type `&str` for some lifetime. + fn can_be_static_str(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { + match arg.kind { + hir::ExprKind::Lit(_) => true, + hir::ExprKind::Call(fun, _) => { + if let hir::ExprKind::Path(ref p) = fun.kind { + match cx.qpath_res(p, fun.hir_id) { + hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!( + cx.tcx.fn_sig(def_id).output().skip_binder().kind(), + ty::Ref(ty::ReStatic, ..) + ), + _ => false, + } + } else { + false + } + }, + hir::ExprKind::MethodCall(..) => { + cx.typeck_results() + .type_dependent_def_id(arg.hir_id) + .map_or(false, |method_id| { + matches!( + cx.tcx.fn_sig(method_id).output().skip_binder().kind(), + ty::Ref(ty::ReStatic, ..) + ) + }) + }, + hir::ExprKind::Path(ref p) => matches!( + cx.qpath_res(p, arg.hir_id), + hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) + ), + _ => false, + } + } + + fn generate_format_arg_snippet( + cx: &LateContext<'_>, + a: &hir::Expr<'_>, + applicability: &mut Applicability, + ) -> Vec { + if_chain! { + if let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref format_arg) = a.kind; + if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.kind; + if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.kind; + + then { + format_arg_expr_tup + .iter() + .map(|a| snippet_with_applicability(cx, a.span, "..", applicability).into_owned()) + .collect() + } else { + unreachable!() + } + } + } + + fn is_call(node: &hir::ExprKind<'_>) -> bool { + match node { + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => { + is_call(&expr.kind) + }, + hir::ExprKind::Call(..) + | hir::ExprKind::MethodCall(..) + // These variants are debatable or require further examination + | hir::ExprKind::If(..) + | hir::ExprKind::Match(..) + | hir::ExprKind::Block{ .. } => true, + _ => false, + } + } + + if args.len() != 2 || name != "expect" || !is_call(&args[1].kind) { + return; + } + + let receiver_type = cx.typeck_results().expr_ty_adjusted(&args[0]); + let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym::option_type) { + "||" + } else if is_type_diagnostic_item(cx, receiver_type, sym::result_type) { + "|_|" + } else { + return; + }; + + let arg_root = get_arg_root(cx, &args[1]); + + let span_replace_word = method_span.with_hi(expr.span.hi()); + + let mut applicability = Applicability::MachineApplicable; + + //Special handling for `format!` as arg_root + if_chain! { + if let hir::ExprKind::Block(block, None) = &arg_root.kind; + if block.stmts.len() == 1; + if let hir::StmtKind::Local(local) = &block.stmts[0].kind; + if let Some(arg_root) = &local.init; + if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = arg_root.kind; + if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1; + if let hir::ExprKind::Call(_, format_args) = &inner_args[0].kind; + then { + let fmt_spec = &format_args[0]; + let fmt_args = &format_args[1]; + + let mut args = vec![snippet(cx, fmt_spec.span, "..").into_owned()]; + + args.extend(generate_format_arg_snippet(cx, fmt_args, &mut applicability)); + + let sugg = args.join(", "); + + span_lint_and_sugg( + cx, + EXPECT_FUN_CALL, + span_replace_word, + &format!("use of `{}` followed by a function call", name), + "try this", + format!("unwrap_or_else({} panic!({}))", closure_args, sugg), + applicability, + ); + + return; + } + } + + let mut arg_root_snippet: Cow<'_, _> = snippet_with_applicability(cx, arg_root.span, "..", &mut applicability); + if requires_to_string(cx, arg_root) { + arg_root_snippet.to_mut().push_str(".to_string()"); + } + + span_lint_and_sugg( + cx, + EXPECT_FUN_CALL, + span_replace_word, + &format!("use of `{}` followed by a function call", name), + "try this", + format!( + "unwrap_or_else({} {{ panic!(\"{{}}\", {}) }})", + closure_args, arg_root_snippet + ), + applicability, + ); +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 857c1bf0ec08a..180620e860a5f 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2,6 +2,7 @@ mod bind_instead_of_map; mod bytes_nth; mod clone_on_copy; mod clone_on_ref_ptr; +mod expect_fun_call; mod expect_used; mod filetype_is_file; mod filter_flat_map; @@ -50,8 +51,6 @@ mod useless_asref; mod wrong_self_convention; mod zst_offset; -use std::borrow::Cow; - use bind_instead_of_map::BindInsteadOfMap; use if_chain::if_chain; use rustc_ast::ast; @@ -68,10 +67,9 @@ use rustc_span::symbol::{sym, Symbol, SymbolStr}; use rustc_typeck::hir_ty_to_ty; use crate::utils::{ - contains_return, contains_ty, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, - is_type_diagnostic_item, iter_input_pats, match_def_path, match_qpath, method_calls, method_chain_args, paths, - return_ty, single_segment_path, snippet, snippet_with_applicability, span_lint, span_lint_and_help, - span_lint_and_sugg, SpanlessEq, + contains_return, contains_ty, get_trait_def_id, implements_trait, in_macro, is_copy, is_type_diagnostic_item, + iter_input_pats, match_def_path, match_qpath, method_calls, method_chain_args, paths, return_ty, + single_segment_path, snippet_with_applicability, span_lint, span_lint_and_help, span_lint_and_sugg, SpanlessEq, }; declare_clippy_lint! { @@ -1779,7 +1777,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { }, hir::ExprKind::MethodCall(ref method_call, ref method_span, ref args, _) => { or_fun_call::check(cx, expr, *method_span, &method_call.ident.as_str(), args); - lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args); + expect_fun_call::check(cx, expr, *method_span, &method_call.ident.as_str(), args); let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]); if args.len() == 1 && method_call.ident.name == sym::clone { @@ -1973,200 +1971,6 @@ impl<'tcx> LateLintPass<'tcx> for Methods { extract_msrv_attr!(LateContext); } -/// Checks for the `EXPECT_FUN_CALL` lint. -#[allow(clippy::too_many_lines)] -fn lint_expect_fun_call( - cx: &LateContext<'_>, - expr: &hir::Expr<'_>, - method_span: Span, - name: &str, - args: &[hir::Expr<'_>], -) { - // Strip `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or - // `&str` - fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { - let mut arg_root = arg; - loop { - arg_root = match &arg_root.kind { - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr, - hir::ExprKind::MethodCall(method_name, _, call_args, _) => { - if call_args.len() == 1 - && (method_name.ident.name == sym::as_str || method_name.ident.name == sym!(as_ref)) - && { - let arg_type = cx.typeck_results().expr_ty(&call_args[0]); - let base_type = arg_type.peel_refs(); - *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::string_type) - } - { - &call_args[0] - } else { - break; - } - }, - _ => break, - }; - } - arg_root - } - - // Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be - // converted to string. - fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { - let arg_ty = cx.typeck_results().expr_ty(arg); - if is_type_diagnostic_item(cx, arg_ty, sym::string_type) { - return false; - } - if let ty::Ref(_, ty, ..) = arg_ty.kind() { - if *ty.kind() == ty::Str && can_be_static_str(cx, arg) { - return false; - } - }; - true - } - - // Check if an expression could have type `&'static str`, knowing that it - // has type `&str` for some lifetime. - fn can_be_static_str(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { - match arg.kind { - hir::ExprKind::Lit(_) => true, - hir::ExprKind::Call(fun, _) => { - if let hir::ExprKind::Path(ref p) = fun.kind { - match cx.qpath_res(p, fun.hir_id) { - hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!( - cx.tcx.fn_sig(def_id).output().skip_binder().kind(), - ty::Ref(ty::ReStatic, ..) - ), - _ => false, - } - } else { - false - } - }, - hir::ExprKind::MethodCall(..) => { - cx.typeck_results() - .type_dependent_def_id(arg.hir_id) - .map_or(false, |method_id| { - matches!( - cx.tcx.fn_sig(method_id).output().skip_binder().kind(), - ty::Ref(ty::ReStatic, ..) - ) - }) - }, - hir::ExprKind::Path(ref p) => matches!( - cx.qpath_res(p, arg.hir_id), - hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) - ), - _ => false, - } - } - - fn generate_format_arg_snippet( - cx: &LateContext<'_>, - a: &hir::Expr<'_>, - applicability: &mut Applicability, - ) -> Vec { - if_chain! { - if let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref format_arg) = a.kind; - if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.kind; - if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.kind; - - then { - format_arg_expr_tup - .iter() - .map(|a| snippet_with_applicability(cx, a.span, "..", applicability).into_owned()) - .collect() - } else { - unreachable!() - } - } - } - - fn is_call(node: &hir::ExprKind<'_>) -> bool { - match node { - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => { - is_call(&expr.kind) - }, - hir::ExprKind::Call(..) - | hir::ExprKind::MethodCall(..) - // These variants are debatable or require further examination - | hir::ExprKind::If(..) - | hir::ExprKind::Match(..) - | hir::ExprKind::Block{ .. } => true, - _ => false, - } - } - - if args.len() != 2 || name != "expect" || !is_call(&args[1].kind) { - return; - } - - let receiver_type = cx.typeck_results().expr_ty_adjusted(&args[0]); - let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym::option_type) { - "||" - } else if is_type_diagnostic_item(cx, receiver_type, sym::result_type) { - "|_|" - } else { - return; - }; - - let arg_root = get_arg_root(cx, &args[1]); - - let span_replace_word = method_span.with_hi(expr.span.hi()); - - let mut applicability = Applicability::MachineApplicable; - - //Special handling for `format!` as arg_root - if_chain! { - if let hir::ExprKind::Block(block, None) = &arg_root.kind; - if block.stmts.len() == 1; - if let hir::StmtKind::Local(local) = &block.stmts[0].kind; - if let Some(arg_root) = &local.init; - if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = arg_root.kind; - if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1; - if let hir::ExprKind::Call(_, format_args) = &inner_args[0].kind; - then { - let fmt_spec = &format_args[0]; - let fmt_args = &format_args[1]; - - let mut args = vec![snippet(cx, fmt_spec.span, "..").into_owned()]; - - args.extend(generate_format_arg_snippet(cx, fmt_args, &mut applicability)); - - let sugg = args.join(", "); - - span_lint_and_sugg( - cx, - EXPECT_FUN_CALL, - span_replace_word, - &format!("use of `{}` followed by a function call", name), - "try this", - format!("unwrap_or_else({} panic!({}))", closure_args, sugg), - applicability, - ); - - return; - } - } - - let mut arg_root_snippet: Cow<'_, _> = snippet_with_applicability(cx, arg_root.span, "..", &mut applicability); - if requires_to_string(cx, arg_root) { - arg_root_snippet.to_mut().push_str(".to_string()"); - } - - span_lint_and_sugg( - cx, - EXPECT_FUN_CALL, - span_replace_word, - &format!("use of `{}` followed by a function call", name), - "try this", - format!( - "unwrap_or_else({} {{ panic!(\"{{}}\", {}) }})", - closure_args, arg_root_snippet - ), - applicability, - ); -} - fn derefs_to_slice<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, From 99f860768cdd71c371cdaf7827c377dbaa4fe396 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 11 Mar 2021 20:02:29 +0900 Subject: [PATCH 212/226] remove unused imports --- clippy_lints/src/methods/into_iter_on_ref.rs | 3 ++- clippy_lints/src/methods/mod.rs | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/methods/into_iter_on_ref.rs b/clippy_lints/src/methods/into_iter_on_ref.rs index d94b243404c36..1e8315dbee25e 100644 --- a/clippy_lints/src/methods/into_iter_on_ref.rs +++ b/clippy_lints/src/methods/into_iter_on_ref.rs @@ -4,6 +4,7 @@ use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; use rustc_span::source_map::Span; +use rustc_span::symbol::Symbol; use super::INTO_ITER_ON_REF; @@ -27,7 +28,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty< } } -fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(&'static str, &'static str)> { +fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(Symbol, &'static str)> { has_iter_method(cx, self_ref_ty).map(|ty_name| { let mutbl = match self_ref_ty.kind() { ty::Ref(_, _, mutbl) => mutbl, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 180620e860a5f..7fd14c4f9b11c 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -62,8 +62,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, TraitRef, Ty, TyS}; use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; -use rustc_span::symbol::{sym, Symbol, SymbolStr}; +use rustc_span::symbol::{sym, SymbolStr}; use rustc_typeck::hir_ty_to_ty; use crate::utils::{ From 83a955335f986c503ac114cf5009ff965bb21741 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 11 Mar 2021 20:18:33 +0900 Subject: [PATCH 213/226] fix interning-defined-symbol error --- clippy_lints/src/methods/get_unwrap.rs | 4 ++-- clippy_lints/src/methods/iter_nth.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/methods/get_unwrap.rs b/clippy_lints/src/methods/get_unwrap.rs index 2684c50e01b7d..e157db2712a9a 100644 --- a/clippy_lints/src/methods/get_unwrap.rs +++ b/clippy_lints/src/methods/get_unwrap.rs @@ -27,10 +27,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args } else if is_type_diagnostic_item(cx, expr_ty, sym::vec_type) { needs_ref = get_args_str.parse::().is_ok(); "Vec" - } else if is_type_diagnostic_item(cx, expr_ty, sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, expr_ty, sym::vecdeque_type) { needs_ref = get_args_str.parse::().is_ok(); "VecDeque" - } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym!(hashmap_type)) { + } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::hashmap_type) { needs_ref = true; "HashMap" } else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) { diff --git a/clippy_lints/src/methods/iter_nth.rs b/clippy_lints/src/methods/iter_nth.rs index c8adea9536b2d..cc3e56ea87277 100644 --- a/clippy_lints/src/methods/iter_nth.rs +++ b/clippy_lints/src/methods/iter_nth.rs @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( "slice" } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) { "Vec" - } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vecdeque_type) { "VecDeque" } else { let nth_args = nth_and_iter_args[0]; From 2546e6f006da4acc79dbed3711674e7d7b73f1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 6 Mar 2021 10:06:52 +0100 Subject: [PATCH 214/226] lintcheck: move out of clippy-dev into own crate --- .cargo/config | 2 +- clippy_dev/Cargo.toml | 9 --- clippy_dev/src/lib.rs | 1 - clippy_dev/src/main.rs | 45 +---------- lintcheck/Cargo.toml | 19 +++++ lintcheck/README.md | 77 +++++++++++++++++++ lintcheck/lintcheck_crates.toml | 35 +++++++++ .../src/lintcheck.rs => lintcheck/src/main.rs | 70 +++++++++++++++-- 8 files changed, 199 insertions(+), 59 deletions(-) create mode 100644 lintcheck/Cargo.toml create mode 100644 lintcheck/README.md create mode 100644 lintcheck/lintcheck_crates.toml rename clippy_dev/src/lintcheck.rs => lintcheck/src/main.rs (93%) diff --git a/.cargo/config b/.cargo/config index 1142cc470fe82..ffa9a5bce85cc 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,7 +1,7 @@ [alias] uitest = "test --test compile-test" dev = "run --target-dir clippy_dev/target --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --" -dev-lintcheck = "run --target-dir clippy_dev/target --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck" +dev-lintcheck = "run --target-dir lintcheck/target --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml -- " [build] rustflags = ["-Zunstable-options"] diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml index 5cfd5056f5882..b1844e29b3273 100644 --- a/clippy_dev/Cargo.toml +++ b/clippy_dev/Cargo.toml @@ -7,20 +7,11 @@ edition = "2018" [dependencies] bytecount = "0.6" clap = "2.33" -flate2 = { version = "1.0.19", optional = true } -fs_extra = { version = "1.2.0", optional = true } itertools = "0.9" opener = "0.4" regex = "1" -serde = { version = "1.0", features = ["derive"], optional = true } -serde_json = { version = "1.0", optional = true } shell-escape = "0.1" -tar = { version = "0.4.30", optional = true } -toml = { version = "0.5", optional = true } -ureq = { version = "2.0.0-rc3", optional = true } -rayon = { version = "1.5.0", optional = true } walkdir = "2" [features] -lintcheck = ["flate2", "serde_json", "tar", "toml", "ureq", "serde", "fs_extra", "rayon"] deny-warnings = [] diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index 0244ff2b6c27b..a95abfaceaae0 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -12,7 +12,6 @@ use walkdir::WalkDir; pub mod bless; pub mod fmt; -pub mod lintcheck; pub mod new_lint; pub mod ra_setup; pub mod serve; diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index 33fef18d553af..2a9f3e5348c41 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -2,10 +2,6 @@ use clap::{App, Arg, ArgMatches, SubCommand}; use clippy_dev::{bless, fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints}; - -#[cfg(feature = "lintcheck")] -use clippy_dev::lintcheck; - fn main() { let matches = get_clap_config(); @@ -13,10 +9,6 @@ fn main() { ("bless", Some(matches)) => { bless::bless(matches.is_present("ignore-timestamp")); }, - #[cfg(feature = "lintcheck")] - ("lintcheck", Some(matches)) => { - lintcheck::run(&matches); - }, ("fmt", Some(matches)) => { fmt::run(matches.is_present("check"), matches.is_present("verbose")); }, @@ -53,34 +45,7 @@ fn main() { } fn get_clap_config<'a>() -> ArgMatches<'a> { - #[cfg(feature = "lintcheck")] - let lintcheck_sbcmd = SubCommand::with_name("lintcheck") - .about("run clippy on a set of crates and check output") - .arg( - Arg::with_name("only") - .takes_value(true) - .value_name("CRATE") - .long("only") - .help("only process a single crate of the list"), - ) - .arg( - Arg::with_name("crates-toml") - .takes_value(true) - .value_name("CRATES-SOURCES-TOML-PATH") - .long("crates-toml") - .help("set the path for a crates.toml where lintcheck should read the sources from"), - ) - .arg( - Arg::with_name("threads") - .takes_value(true) - .value_name("N") - .short("j") - .long("jobs") - .help("number of threads to use, 0 automatic choice"), - ) - .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply")); - - let app = App::new("Clippy developer tooling") + App::new("Clippy developer tooling") .subcommand( SubCommand::with_name("bless") .about("bless the test output changes") @@ -197,10 +162,6 @@ fn get_clap_config<'a>() -> ArgMatches<'a> { .validator_os(serve::validate_port), ) .arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")), - ); - - #[cfg(feature = "lintcheck")] - let app = app.subcommand(lintcheck_sbcmd); - - app.get_matches() + ) + .get_matches() } diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml new file mode 100644 index 0000000000000..071c1f896153f --- /dev/null +++ b/lintcheck/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "lintcheck" +version = "0.0.1" +authors = ["Matthias Krüger "] +edition = "2018" + +[dependencies] +clap = "2.33" +flate2 = {version = "1.0.19"} +fs_extra = {version = "1.2.0"} +rayon = {version = "1.5.0"} +serde = {version = "1.0", features = ["derive"]} +serde_json = {version = "1.0"} +tar = {version = "0.4.30"} +toml = {version = "0.5"} +ureq = {version = "2.0.0-rc3"} + +[features] +deny-warnings = [] diff --git a/lintcheck/README.md b/lintcheck/README.md new file mode 100644 index 0000000000000..a5ed9e27bd2bc --- /dev/null +++ b/lintcheck/README.md @@ -0,0 +1,77 @@ +# Clippy Dev Tool + +The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s +`x.py`. + +Functionalities (incomplete): + +## `lintcheck` + +Runs clippy on a fixed set of crates read from +`clippy_dev/lintcheck_crates.toml` and saves logs of the lint warnings into the +repo. We can then check the diff and spot new or disappearing warnings. + +From the repo root, run: + +``` +cargo run --target-dir clippy_dev/target --package clippy_dev \ +--bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck +``` + +or + +``` +cargo dev-lintcheck +``` + +By default the logs will be saved into +`lintcheck-logs/lintcheck_crates_logs.txt`. + +You can set a custom sources.toml by adding `--crates-toml custom.toml` or using +`LINTCHECK_TOML="custom.toml"` where `custom.toml` must be a relative path from +the repo root. + +The results will then be saved to `lintcheck-logs/custom_logs.toml`. + +### Configuring the Crate Sources + +The sources to check are saved in a `toml` file. There are three types of +sources. + +1. Crates-io Source + + ```toml + bitflags = {name = "bitflags", versions = ['1.2.1']} + ``` + Requires a "name" and one or multiple "versions" to be checked. + +2. `git` Source + ````toml + puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} + ```` + Requires a name, the url to the repo and unique identifier of a commit, + branch or tag which is checked out before linting. There is no way to always + check `HEAD` because that would lead to changing lint-results as the repo + would get updated. If `git_url` or `git_hash` is missing, an error will be + thrown. + +3. Local Dependency + ```toml + clippy = {name = "clippy", path = "/home/user/clippy"} + ``` + For when you want to add a repository that is not published yet. + +#### Command Line Options (optional) + +```toml +bitflags = {name = "bitflags", versions = ['1.2.1'], options = ['-Wclippy::pedantic', '-Wclippy::cargo']} +``` + +It is possible to specify command line options for each crate. This makes it +possible to only check a crate for certain lint groups. If no options are +specified, the lint groups `clippy::all`, `clippy::pedantic`, and +`clippy::cargo` are checked. If an empty array is specified only `clippy::all` +is checked. + +**Note:** `-Wclippy::all` is always enabled by default, unless `-Aclippy::all` +is explicitly specified in the options. diff --git a/lintcheck/lintcheck_crates.toml b/lintcheck/lintcheck_crates.toml new file mode 100644 index 0000000000000..dfee28f1a8712 --- /dev/null +++ b/lintcheck/lintcheck_crates.toml @@ -0,0 +1,35 @@ +[crates] +# some of these are from cargotest +cargo = {name = "cargo", versions = ['0.49.0']} +iron = {name = "iron", versions = ['0.6.1']} +ripgrep = {name = "ripgrep", versions = ['12.1.1']} +xsv = {name = "xsv", versions = ['0.13.0']} +# commented out because of 173K clippy::match_same_arms msgs in language_type.rs +#tokei = { name = "tokei", versions = ['12.0.4']} +rayon = {name = "rayon", versions = ['1.5.0']} +serde = {name = "serde", versions = ['1.0.118']} +# top 10 crates.io dls +bitflags = {name = "bitflags", versions = ['1.2.1']} +# crash = {name = "clippy_crash", path = "/tmp/clippy_crash"} +libc = {name = "libc", versions = ['0.2.81']} +log = {name = "log", versions = ['0.4.11']} +proc-macro2 = {name = "proc-macro2", versions = ['1.0.24']} +quote = {name = "quote", versions = ['1.0.7']} +rand = {name = "rand", versions = ['0.7.3']} +rand_core = {name = "rand_core", versions = ['0.6.0']} +regex = {name = "regex", versions = ['1.3.2']} +syn = {name = "syn", versions = ['1.0.54']} +unicode-xid = {name = "unicode-xid", versions = ['0.2.1']} +# some more of dtolnays crates +anyhow = {name = "anyhow", versions = ['1.0.38']} +async-trait = {name = "async-trait", versions = ['0.1.42']} +cxx = {name = "cxx", versions = ['1.0.32']} +ryu = {name = "ryu", version = ['1.0.5']} +serde_yaml = {name = "serde_yaml", versions = ['0.8.17']} +thiserror = {name = "thiserror", versions = ['1.0.24']} +# some embark crates, there are other interesting crates but +# unfortunately adding them increases lintcheck runtime drastically +cfg-expr = {name = "cfg-expr", versions = ['0.7.1']} +puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} +rpmalloc = {name = "rpmalloc", versions = ['0.2.0']} +tame-oidc = {name = "tame-oidc", versions = ['0.1.0']} diff --git a/clippy_dev/src/lintcheck.rs b/lintcheck/src/main.rs similarity index 93% rename from clippy_dev/src/lintcheck.rs rename to lintcheck/src/main.rs index 765d3349ec01f..f5a54cfa8dc5f 100644 --- a/clippy_dev/src/lintcheck.rs +++ b/lintcheck/src/main.rs @@ -1,14 +1,11 @@ // Run clippy on a fixed set of crates and collect the warnings. -// This helps observing the impact clippy changs have on a set of real-world code. +// This helps observing the impact clippy changes have on a set of real-world code (and not just our testsuite). // // When a new lint is introduced, we can search the results for new warnings and check for false // positives. -#![cfg(feature = "lintcheck")] #![allow(clippy::filter_map, clippy::collapsible_else_if)] -use crate::clippy_project_root; - use std::process::Command; use std::sync::atomic::{AtomicUsize, Ordering}; use std::{collections::HashMap, io::ErrorKind}; @@ -18,7 +15,7 @@ use std::{ path::{Path, PathBuf}, }; -use clap::ArgMatches; +use clap::{App, Arg, ArgMatches, SubCommand}; use rayon::prelude::*; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -564,7 +561,9 @@ fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool { /// # Panics /// /// This function panics if the clippy binaries don't exist. -pub fn run(clap_config: &ArgMatches) { +pub fn main() { + let clap_config = &get_clap_config(); + let config = LintcheckConfig::from_clap(clap_config); println!("Compiling clippy..."); @@ -800,6 +799,65 @@ fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) { }); } +fn get_clap_config<'a>() -> ArgMatches<'a> { + let lintcheck_sbcmd = SubCommand::with_name("lintcheck") + .about("run clippy on a set of crates and check output") + .arg( + Arg::with_name("only") + .takes_value(true) + .value_name("CRATE") + .long("only") + .help("only process a single crate of the list"), + ) + .arg( + Arg::with_name("crates-toml") + .takes_value(true) + .value_name("CRATES-SOURCES-TOML-PATH") + .long("crates-toml") + .help("set the path for a crates.toml where lintcheck should read the sources from"), + ) + .arg( + Arg::with_name("threads") + .takes_value(true) + .value_name("N") + .short("j") + .long("jobs") + .help("number of threads to use, 0 automatic choice"), + ) + .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply")); + + let app = App::new("Clippy developer tooling"); + + let app = app.subcommand(lintcheck_sbcmd); + + app.get_matches() +} + +/// Returns the path to the Clippy project directory +/// +/// # Panics +/// +/// Panics if the current directory could not be retrieved, there was an error reading any of the +/// Cargo.toml files or ancestor directory is the clippy root directory +#[must_use] +pub fn clippy_project_root() -> PathBuf { + let current_dir = std::env::current_dir().unwrap(); + for path in current_dir.ancestors() { + let result = std::fs::read_to_string(path.join("Cargo.toml")); + if let Err(err) = &result { + if err.kind() == std::io::ErrorKind::NotFound { + continue; + } + } + + let content = result.unwrap(); + if content.contains("[package]\nname = \"clippy\"") { + return path.to_path_buf(); + } + } + panic!("error: Can't determine root of project. Please run inside a Clippy working dir."); +} + #[test] fn lintcheck_test() { let args = [ From a846945b82f1bfe5f01aff6688927ddb5f4b2514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 9 Mar 2021 14:06:42 +0100 Subject: [PATCH 215/226] lintcheck: make sure we lauch from the repo root This will terminate the program if run via "cargo run". "cargo run" does currently not work because at least a bunch of paths do not take that into account. --- lintcheck/src/main.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index f5a54cfa8dc5f..e6b2d49cfef04 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -1,5 +1,6 @@ // Run clippy on a fixed set of crates and collect the warnings. -// This helps observing the impact clippy changes have on a set of real-world code (and not just our testsuite). +// This helps observing the impact clippy changes have on a set of real-world code (and not just our +// testsuite). // // When a new lint is introduced, we can search the results for new warnings and check for false // positives. @@ -556,12 +557,29 @@ fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool { logs_modified < clippy_modified } +fn is_in_clippy_root() -> bool { + if let Ok(pb) = std::env::current_dir() { + if let Some(file) = pb.file_name() { + return file == PathBuf::from("rust-clippy"); + } + } + + false +} + /// lintchecks `main()` function /// /// # Panics /// -/// This function panics if the clippy binaries don't exist. +/// This function panics if the clippy binaries don't exist +/// or if lintcheck is executed from the wrong directory (aka none-repo-root) pub fn main() { + // assert that we launch lintcheck from the repo root (via cargo dev-lintcheck) + if !is_in_clippy_root() { + eprintln!("lintcheck needs to be run from clippys repo root!\nUse `cargo dev-lintcheck` alternatively."); + std::process::exit(3); + } + let clap_config = &get_clap_config(); let config = LintcheckConfig::from_clap(clap_config); From c76015098941c1bb582893fe7fbf9227d0ef796f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 9 Mar 2021 14:08:26 +0100 Subject: [PATCH 216/226] gitignore: add lintchecks target dir --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 139129d55e330..376528e30853a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ out /clippy_utils/target /clippy_workspace_tests/target /clippy_dev/target +/lintcheck/target /rustc_tools_util/target # Generated by dogfood From fac6da1cfb3f00081934b9c2df874f09cd55259a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 9 Mar 2021 14:40:59 +0100 Subject: [PATCH 217/226] move testfiles to "lintcheck" and fix more paths --- .cargo/config | 2 +- clippy_dev/lintcheck_crates.toml | 35 ------------------- lintcheck/src/main.rs | 37 ++++++++------------- {clippy_dev => lintcheck}/test_sources.toml | 0 4 files changed, 14 insertions(+), 60 deletions(-) delete mode 100644 clippy_dev/lintcheck_crates.toml rename {clippy_dev => lintcheck}/test_sources.toml (100%) diff --git a/.cargo/config b/.cargo/config index ffa9a5bce85cc..9b5add4df1c12 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,7 +1,7 @@ [alias] uitest = "test --test compile-test" dev = "run --target-dir clippy_dev/target --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --" -dev-lintcheck = "run --target-dir lintcheck/target --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml -- " +lintcheck = "run --target-dir lintcheck/target --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml -- " [build] rustflags = ["-Zunstable-options"] diff --git a/clippy_dev/lintcheck_crates.toml b/clippy_dev/lintcheck_crates.toml deleted file mode 100644 index dfee28f1a8712..0000000000000 --- a/clippy_dev/lintcheck_crates.toml +++ /dev/null @@ -1,35 +0,0 @@ -[crates] -# some of these are from cargotest -cargo = {name = "cargo", versions = ['0.49.0']} -iron = {name = "iron", versions = ['0.6.1']} -ripgrep = {name = "ripgrep", versions = ['12.1.1']} -xsv = {name = "xsv", versions = ['0.13.0']} -# commented out because of 173K clippy::match_same_arms msgs in language_type.rs -#tokei = { name = "tokei", versions = ['12.0.4']} -rayon = {name = "rayon", versions = ['1.5.0']} -serde = {name = "serde", versions = ['1.0.118']} -# top 10 crates.io dls -bitflags = {name = "bitflags", versions = ['1.2.1']} -# crash = {name = "clippy_crash", path = "/tmp/clippy_crash"} -libc = {name = "libc", versions = ['0.2.81']} -log = {name = "log", versions = ['0.4.11']} -proc-macro2 = {name = "proc-macro2", versions = ['1.0.24']} -quote = {name = "quote", versions = ['1.0.7']} -rand = {name = "rand", versions = ['0.7.3']} -rand_core = {name = "rand_core", versions = ['0.6.0']} -regex = {name = "regex", versions = ['1.3.2']} -syn = {name = "syn", versions = ['1.0.54']} -unicode-xid = {name = "unicode-xid", versions = ['0.2.1']} -# some more of dtolnays crates -anyhow = {name = "anyhow", versions = ['1.0.38']} -async-trait = {name = "async-trait", versions = ['0.1.42']} -cxx = {name = "cxx", versions = ['1.0.32']} -ryu = {name = "ryu", version = ['1.0.5']} -serde_yaml = {name = "serde_yaml", versions = ['0.8.17']} -thiserror = {name = "thiserror", versions = ['1.0.24']} -# some embark crates, there are other interesting crates but -# unfortunately adding them increases lintcheck runtime drastically -cfg-expr = {name = "cfg-expr", versions = ['0.7.1']} -puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} -rpmalloc = {name = "rpmalloc", versions = ['0.2.0']} -tame-oidc = {name = "tame-oidc", versions = ['0.1.0']} diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index e6b2d49cfef04..c027f11dfe9c1 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -16,7 +16,7 @@ use std::{ path::{Path, PathBuf}, }; -use clap::{App, Arg, ArgMatches, SubCommand}; +use clap::{App, Arg, ArgMatches}; use rayon::prelude::*; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -337,12 +337,12 @@ impl LintcheckConfig { fn from_clap(clap_config: &ArgMatches) -> Self { // first, check if we got anything passed via the LINTCHECK_TOML env var, // if not, ask clap if we got any value for --crates-toml - // if not, use the default "clippy_dev/lintcheck_crates.toml" + // if not, use the default "lintcheck/lintcheck_crates.toml" let sources_toml = env::var("LINTCHECK_TOML").unwrap_or_else(|_| { clap_config .value_of("crates-toml") .clone() - .unwrap_or("clippy_dev/lintcheck_crates.toml") + .unwrap_or("lintcheck/lintcheck_crates.toml") .to_string() }); @@ -576,7 +576,7 @@ fn is_in_clippy_root() -> bool { pub fn main() { // assert that we launch lintcheck from the repo root (via cargo dev-lintcheck) if !is_in_clippy_root() { - eprintln!("lintcheck needs to be run from clippys repo root!\nUse `cargo dev-lintcheck` alternatively."); + eprintln!("lintcheck needs to be run from clippys repo root!\nUse `cargo lintcheck` alternatively."); std::process::exit(3); } @@ -638,7 +638,7 @@ pub fn main() { name == only_one_crate }) { eprintln!( - "ERROR: could not find crate '{}' in clippy_dev/lintcheck_crates.toml", + "ERROR: could not find crate '{}' in lintcheck/lintcheck_crates.toml", only_one_crate ); std::process::exit(1); @@ -818,7 +818,7 @@ fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) { } fn get_clap_config<'a>() -> ArgMatches<'a> { - let lintcheck_sbcmd = SubCommand::with_name("lintcheck") + App::new("lintcheck") .about("run clippy on a set of crates and check output") .arg( Arg::with_name("only") @@ -842,13 +842,8 @@ fn get_clap_config<'a>() -> ArgMatches<'a> { .long("jobs") .help("number of threads to use, 0 automatic choice"), ) - .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply")); - - let app = App::new("Clippy developer tooling"); - - let app = app.subcommand(lintcheck_sbcmd); - - app.get_matches() + .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply")) + .get_matches() } /// Returns the path to the Clippy project directory @@ -881,24 +876,18 @@ fn lintcheck_test() { let args = [ "run", "--target-dir", - "clippy_dev/target", - "--package", - "clippy_dev", - "--bin", - "clippy_dev", + "lintcheck/target", "--manifest-path", - "clippy_dev/Cargo.toml", - "--features", - "lintcheck", + "./lintcheck/Cargo.toml", "--", - "lintcheck", "--crates-toml", - "clippy_dev/test_sources.toml", + "lintcheck/test_sources.toml", ]; let status = std::process::Command::new("cargo") .args(&args) - .current_dir("../" /* repo root */) + .current_dir("..") // repo root .status(); + //.output(); assert!(status.unwrap().success()); } diff --git a/clippy_dev/test_sources.toml b/lintcheck/test_sources.toml similarity index 100% rename from clippy_dev/test_sources.toml rename to lintcheck/test_sources.toml From d859a17cdda292906ecfeb6488998fc434c8fb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 9 Mar 2021 23:20:04 +0100 Subject: [PATCH 218/226] lintcheck: update readme and remove the now redundant readme from clippy-dev --- clippy_dev/README.md | 77 -------------------------------------------- lintcheck/Cargo.toml | 2 +- lintcheck/README.md | 16 +++------ 3 files changed, 5 insertions(+), 90 deletions(-) delete mode 100644 clippy_dev/README.md diff --git a/clippy_dev/README.md b/clippy_dev/README.md deleted file mode 100644 index a5ed9e27bd2bc..0000000000000 --- a/clippy_dev/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Clippy Dev Tool - -The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s -`x.py`. - -Functionalities (incomplete): - -## `lintcheck` - -Runs clippy on a fixed set of crates read from -`clippy_dev/lintcheck_crates.toml` and saves logs of the lint warnings into the -repo. We can then check the diff and spot new or disappearing warnings. - -From the repo root, run: - -``` -cargo run --target-dir clippy_dev/target --package clippy_dev \ ---bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck -``` - -or - -``` -cargo dev-lintcheck -``` - -By default the logs will be saved into -`lintcheck-logs/lintcheck_crates_logs.txt`. - -You can set a custom sources.toml by adding `--crates-toml custom.toml` or using -`LINTCHECK_TOML="custom.toml"` where `custom.toml` must be a relative path from -the repo root. - -The results will then be saved to `lintcheck-logs/custom_logs.toml`. - -### Configuring the Crate Sources - -The sources to check are saved in a `toml` file. There are three types of -sources. - -1. Crates-io Source - - ```toml - bitflags = {name = "bitflags", versions = ['1.2.1']} - ``` - Requires a "name" and one or multiple "versions" to be checked. - -2. `git` Source - ````toml - puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} - ```` - Requires a name, the url to the repo and unique identifier of a commit, - branch or tag which is checked out before linting. There is no way to always - check `HEAD` because that would lead to changing lint-results as the repo - would get updated. If `git_url` or `git_hash` is missing, an error will be - thrown. - -3. Local Dependency - ```toml - clippy = {name = "clippy", path = "/home/user/clippy"} - ``` - For when you want to add a repository that is not published yet. - -#### Command Line Options (optional) - -```toml -bitflags = {name = "bitflags", versions = ['1.2.1'], options = ['-Wclippy::pedantic', '-Wclippy::cargo']} -``` - -It is possible to specify command line options for each crate. This makes it -possible to only check a crate for certain lint groups. If no options are -specified, the lint groups `clippy::all`, `clippy::pedantic`, and -`clippy::cargo` are checked. If an empty array is specified only `clippy::all` -is checked. - -**Note:** `-Wclippy::all` is always enabled by default, unless `-Aclippy::all` -is explicitly specified in the options. diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml index 071c1f896153f..5eb9e4aacae98 100644 --- a/lintcheck/Cargo.toml +++ b/lintcheck/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "lintcheck" version = "0.0.1" -authors = ["Matthias Krüger "] +authors = ["The Rust Clippy Developers"] edition = "2018" [dependencies] diff --git a/lintcheck/README.md b/lintcheck/README.md index a5ed9e27bd2bc..68dbf56401441 100644 --- a/lintcheck/README.md +++ b/lintcheck/README.md @@ -1,27 +1,19 @@ -# Clippy Dev Tool - -The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s -`x.py`. - -Functionalities (incomplete): - -## `lintcheck` +## `cargo lintcheck` Runs clippy on a fixed set of crates read from -`clippy_dev/lintcheck_crates.toml` and saves logs of the lint warnings into the +`lintcheck/lintcheck_crates.toml` and saves logs of the lint warnings into the repo. We can then check the diff and spot new or disappearing warnings. From the repo root, run: ``` -cargo run --target-dir clippy_dev/target --package clippy_dev \ ---bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck +cargo run --target-dir lintcheck/target --manifest-path lintcheck/Cargo.toml ``` or ``` -cargo dev-lintcheck +cargo lintcheck ``` By default the logs will be saved into From 3e60ba073b1d7f6a44c0ad146a951445c1ae4a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 11 Mar 2021 14:29:00 +0100 Subject: [PATCH 219/226] lintcheck: fix bug where lint messages about macros coming from crate deps would sneak in absolute paths to registry sources. make the path a relative path that starts at the CARGO_HOME to not print the users home location in the log --- lintcheck/src/main.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index c027f11dfe9c1..1964afd36095d 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -7,6 +7,7 @@ #![allow(clippy::filter_map, clippy::collapsible_else_if)] +use std::ffi::OsStr; use std::process::Command; use std::sync::atomic::{AtomicUsize, Ordering}; use std::{collections::HashMap, io::ErrorKind}; @@ -486,13 +487,32 @@ fn read_crates(toml_path: &Path) -> Vec { fn parse_json_message(json_message: &str, krate: &Crate) -> ClippyWarning { let jmsg: Value = serde_json::from_str(&json_message).unwrap_or_else(|e| panic!("Failed to parse json:\n{:?}", e)); + let file: String = jmsg["message"]["spans"][0]["file_name"] + .to_string() + .trim_matches('"') + .into(); + + let file = if file.contains(".cargo") { + // if we deal with macros, a filename may show the origin of a macro which can be inside a dep from + // the registry. + // don't show the full path in that case. + + // /home/matthias/.cargo/registry/src/github.com-1ecc6299db9ec823/syn-1.0.63/src/custom_keyword.rs + let path = PathBuf::from(file); + let mut piter = path.into_iter(); + // consume all elements until we find ".cargo", so that "/home/matthias" is skipped + let _: Option<&OsStr> = piter.find(|x| x == &std::ffi::OsString::from(".cargo")); + // collect the remaining segments + let file = piter.collect::(); + format!("{}", file.display()) + } else { + file + }; + ClippyWarning { crate_name: krate.name.to_string(), crate_version: krate.version.to_string(), - file: jmsg["message"]["spans"][0]["file_name"] - .to_string() - .trim_matches('"') - .into(), + file, line: jmsg["message"]["spans"][0]["line_start"] .to_string() .trim_matches('"') From b29ef183fb9b8a25c4a904d63428c8e37dd9696b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 11 Mar 2021 15:05:13 +0100 Subject: [PATCH 220/226] lintcheck: update logs --- lintcheck-logs/lintcheck_crates_logs.txt | 449 +++++++++++++++-------- 1 file changed, 306 insertions(+), 143 deletions(-) diff --git a/lintcheck-logs/lintcheck_crates_logs.txt b/lintcheck-logs/lintcheck_crates_logs.txt index 47453f362547a..3439b1e2c43d4 100644 --- a/lintcheck-logs/lintcheck_crates_logs.txt +++ b/lintcheck-logs/lintcheck_crates_logs.txt @@ -1,8 +1,9 @@ -clippy 0.1.52 (37c4b11a8 2021-03-04) +clippy 0.1.52 (94d1c0a96 2021-03-11) target/lintcheck/sources/anyhow-1.0.38/build.rs:1:null clippy::cargo_common_metadata "package `anyhow` is missing `package.keywords` metadata" target/lintcheck/sources/anyhow-1.0.38/src/error.rs:350:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/anyhow-1.0.38/src/lib.rs:1:null clippy::cargo_common_metadata "package `anyhow` is missing `package.keywords` metadata" +target/lintcheck/sources/async-trait-0.1.42/registry/src/github.com-1ecc6299db9ec823/syn-1.0.63/src/custom_keyword.rs:201:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:130:1 clippy::too_many_lines "this function has too many lines (104/100)" target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:156:26 clippy::default_trait_access "calling `syn::token::Where::default()` is more clear than this expression" target/lintcheck/sources/async-trait-0.1.42/src/expand.rs:259:1 clippy::too_many_lines "this function has too many lines (204/100)" @@ -25,19 +26,19 @@ target/lintcheck/sources/cargo-0.49.0/build.rs:1:null clippy::cargo_common_metad target/lintcheck/sources/cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:104:34 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:121:5 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:157:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:157:30 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:184:41 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:196:42 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:200:39 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:196:42 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:200:39 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:231:1 clippy::struct_excessive_bools "more than 3 bools in a struct" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:23:56 clippy::implicit_clone "implicitly cloning a `String` by calling `to_owned` on its dereferenced type" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:245:22 clippy::cast_possible_truncation "casting `u64` to `u32` may truncate the value" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:247:47 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:257:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:247:47 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:257:22 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:26:20 clippy::redundant_else "redundant else block" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/cli.rs:7:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/bench.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/bench.rs:76:59 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/bench.rs:76:59 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/build.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/check.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/clean.rs:1:5 clippy::wildcard_imports "usage of wildcard import" @@ -58,23 +59,23 @@ target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/mod.rs:1:5 clippy:: target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/new.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/new.rs:20:24 clippy::option_if_let_else "use Option::map_or instead of an if let/else" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:38:43 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:39:43 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:40:43 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:43:30 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:46:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:38:43 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:39:43 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:40:43 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:43:30 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/owner.rs:46:30 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/package.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/pkgid.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/publish.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/publish.rs:40:47 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/publish.rs:40:47 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/read_manifest.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/run.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/rustc.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/rustdoc.rs:3:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/search.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/test.rs:127:54 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/test.rs:127:54 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/test.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/tree.rs:149:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/tree.rs:149:49 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/tree.rs:2:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/uninstall.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/update.rs:1:5 clippy::wildcard_imports "usage of wildcard import" @@ -83,26 +84,25 @@ target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/vendor.rs:96:16 cli target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/verify_project.rs:1:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/version.rs:2:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:1:5 clippy::wildcard_imports "usage of wildcard import" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:32:36 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:33:35 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:34:36 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:35:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:32:36 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:33:35 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:34:36 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/commands/yank.rs:35:36 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:100:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:118:41 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:137:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:118:41 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:137:43 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:148:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:174:57 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:174:57 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:18:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `crossbeam-utils`: 0.6.6, 0.7.2" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:72:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:72:22 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:79:40 clippy::manual_map "manual implementation of `Option::map`" target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:94:13 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:96:41 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:98:60 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/bin/cargo/main.rs:98:60 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:155:13 clippy::enum_glob_use "usage of wildcard import for enum variants" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:170:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_config.rs:175:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -122,8 +122,8 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/targ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:420:69 clippy::doc_markdown "you should put `mode/target_kind` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:423:19 clippy::doc_markdown "you should put `CrateTypes` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:424:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:469:58 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:603:19 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:469:58 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:603:19 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:665:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:697:12 clippy::inconsistent_struct_constructor "inconsistent struct constructor" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:82:31 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" @@ -139,7 +139,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150 target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:169:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:185:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:193:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:194:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:194:49 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:198:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:314:16 clippy::doc_markdown "you should put `rustc_tool` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/compilation.rs:91:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -156,7 +156,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilatio target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:277:22 clippy::doc_markdown "you should put `OUT_DIR` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:324:66 clippy::doc_markdown "you should put `FileType` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:393:37 clippy::match_same_arms "this `match` has identical arm bodies" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:426:71 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:426:71 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::too_many_lines "this function has too many lines (107/100)" @@ -195,7 +195,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:48 target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:481:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:48:56 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:561:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:567:20 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:567:20 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:576:28 clippy::shadow_unrelated "`mut value` is being shadowed" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:606:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:688:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" @@ -203,7 +203,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:75 target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:762:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:762:5 clippy::unnecessary_wraps "this function's return value is unnecessary" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:823:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1021:51 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1021:51 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1656:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1664:5 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/fingerprint.rs:1787:5 clippy::similar_names "binding's name is too similar to existing binding" @@ -256,18 +256,18 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:890:9 target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/job_queue.rs:93:24 clippy::doc_markdown "you should put `JobQueue` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/links.rs:8:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1016:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1094:19 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1094:19 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1131:1 clippy::unnecessary_wraps "this function's return value is unnecessary" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1268:34 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:1277:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:179:1 clippy::too_many_lines "this function has too many lines (162/100)" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:198:78 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:198:78 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:201:25 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:267:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:324:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:364:5 clippy::unnecessary_wraps "this function's return value is unnecessary" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:392:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:392:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:415:23 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:464:18 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/mod.rs:488:61 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do" @@ -285,7 +285,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:57:1 cl target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/rustdoc.rs:72:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:134:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:16:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:30:28 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:30:28 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/compiler/timings.rs:16:1 clippy::struct_excessive_bools "more than 3 bools in a struct" @@ -324,8 +324,8 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:291:5 clippy: target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:305:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:311:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:319:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:337:75 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:397:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:337:75 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:397:56 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:403:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:408:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/dependency.rs:415:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -347,25 +347,25 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:362:25 clippy:: target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:380:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:401:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:409:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:412:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:412:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:416:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:419:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:419:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:424:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:431:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:477:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:509:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:518:5 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:542:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:543:37 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:547:60 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:543:37 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:547:60 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:556:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/features.rs:563:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:116:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:118:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:118:58 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:130:13 clippy::enum_glob_use "usage of wildcard import for enum variants" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:159:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:162:34 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:162:34 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:169:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:17:5 clippy::wildcard_imports "usage of wildcard import" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:189:1 clippy::struct_excessive_bools "more than 3 bools in a struct" @@ -434,7 +434,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:776:5 clippy::m target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:780:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:787:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:798:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:800:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:800:56 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:805:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:809:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:818:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -446,7 +446,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:839:5 clippy::m target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:85:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:888:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/manifest.rs:936:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:1075:28 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:1075:28 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:160:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:170:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:174:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -461,9 +461,9 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:206:5 clippy::mu target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:210:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:217:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:221:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:222:35 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:222:35 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:226:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:227:35 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:227:35 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:230:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:239:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:249:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -472,7 +472,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:385:5 clippy::mi target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:421:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:425:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:452:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:453:60 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:453:60 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:459:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:473:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package.rs:587:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -495,7 +495,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:157:5 clippy: target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:161:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:169:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id.rs:174:1 clippy::module_name_repetitions "item name starts with its containing module's name" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:101:39 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:101:39 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:143:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/package_id_spec.rs:151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -538,18 +538,18 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:168:5 clippy::m target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:240:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:26:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:344:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:344:49 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:369:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:424:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:49:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:520:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:763:53 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:765:53 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:807:14 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:814:53 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/conflict_cache.rs:197:29 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:763:53 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:765:53 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:807:14 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/registry.rs:814:53 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/conflict_cache.rs:197:29 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/conflict_cache.rs:41:38 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/context.rs:274:53 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/context.rs:274:53 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/context.rs:42:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/context.rs:74:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -557,21 +557,21 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 cl target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:339:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:438:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:449:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:529:34 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:602:59 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:529:34 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:602:59 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:623:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:652:27 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:674:51 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:103:22 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:104:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/encode.rs:674:51 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:103:22 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:104:22 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:206:9 clippy::if_not_else "unnecessary boolean `not` operation" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:257:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:257:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:27:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:305:17 clippy::single_char_add_str "calling `push_str()` using a single-character string literal" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/errors.rs:70:1 clippy::too_many_lines "this function has too many lines (207/100)" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:104:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:111:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:162:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:162:56 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:179:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:186:23 clippy::doc_markdown "you should put `RequestedFeatures` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:187:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -580,7 +580,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:200:5 target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:221:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:231:21 clippy::doc_markdown "you should put `pkg_id/is_build` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:233:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:247:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:247:58 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:278:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:394:27 clippy::doc_markdown "you should put `FeatureValue` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:460:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" @@ -589,9 +589,9 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:496:24 target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:58:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/features.rs:67:1 clippy::struct_excessive_bools "more than 3 bools in a struct" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:1017:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:1045:57 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:1045:57 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:122:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:142:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:142:44 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:180:1 clippy::too_many_lines "this function has too many lines (225/100)" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:311:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/resolver/mod.rs:421:52 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" @@ -673,7 +673,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:74:5 clippy:: target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/mod.rs:83:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:128:50 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:128:50 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/source/source_id.rs:162:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -757,7 +757,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:378:5 clippy::mu target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:386:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:387:13 clippy::enum_glob_use "usage of wildcard import for enum variants" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:407:13 clippy::enum_glob_use "usage of wildcard import for enum variants" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:69:34 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:69:34 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:75:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:78:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/summary.rs:81:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -785,7 +785,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:440:9 clippy:: target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:511:32 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:561:25 clippy::non_ascii_literal "literal non-ASCII character detected" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:613:13 clippy::filter_map "called `filter_map(..).map(..)` on an `Iterator`" -target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:615:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:615:22 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:762:27 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:784:17 clippy::if_not_else "unnecessary boolean `not` operation" target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:849:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -795,20 +795,20 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:906:24 clippy: target/lintcheck/sources/cargo-0.49.0/src/cargo/core/workspace.rs:932:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata" target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata" target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `crossbeam-utils`: 0.6.6, 0.7.2" target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `hex`: 0.3.2, 0.4.0" target/lintcheck/sources/cargo-0.49.0/src/cargo/lib.rs:1:null clippy::multiple_crate_versions "multiple versions for dependency `humantime`: 1.3.0, 2.0.0" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_clean.rs:205:23 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_clean.rs:205:23 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_clean.rs:27:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_clean.rs:27:1 clippy::too_many_lines "this function has too many lines (120/100)" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:1078:14 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:1078:14 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:109:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:119:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:1227:17 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" @@ -842,10 +842,10 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:692:49 clip target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:703:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:729:1 clippy::too_many_lines "this function has too many lines (205/100)" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:82:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:874:69 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_compile.rs:874:69 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_doc.rs:20:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_fetch.rs:15:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_fetch.rs:27:46 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_fetch.rs:27:46 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:160:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:175:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:22:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -856,13 +856,13 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:13:5 clippy target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:148:1 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:148:1 clippy::too_many_lines "this function has too many lines (316/100)" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:178:24 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:202:17 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:202:17 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:236:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:312:64 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:312:64 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:32:13 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:339:12 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:454:22 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:454:22 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:483:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:683:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_install.rs:708:5 clippy::manual_flatten "unnecessary `if let` since only the `Some` variant of the iterator element is used" @@ -878,15 +878,15 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:572:34 clippy:: target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:623:1 clippy::too_many_lines "this function has too many lines (130/100)" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:781:5 clippy::filter_map_next "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_new.rs:800:16 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:163:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:163:36 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:27:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:45:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_output_metadata.rs:45:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:144:1 clippy::too_many_lines "this function has too many lines (112/100)" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:207:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:25:1 clippy::struct_excessive_bools "more than 3 bools in a struct" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:307:54 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:307:54 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:394:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:425:61 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:425:61 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:459:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:66:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_package.rs:69:9 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" @@ -896,8 +896,8 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:14:1 target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:171:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:57:49 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:69:37 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:57:49 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:69:37 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:25:24 clippy::if_not_else "unnecessary boolean `not` operation" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:35:9 clippy::if_not_else "unnecessary boolean `not` operation" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/cargo_run.rs:37:16 clippy::redundant_else "redundant else block" @@ -918,7 +918,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_unins target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:370:5 clippy::unnecessary_wraps "this function's return value is unnecessary" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:505:8 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:525:10 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:542:27 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:542:27 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:542:5 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:561:20 clippy::redundant_else "redundant else block" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/common_for_install_and_uninstall.rs:613:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" @@ -930,7 +930,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:424:20 clippy::map_un target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:455:13 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:506:17 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:608:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:619:48 clippy::manual_strip "stripping a prefix manually" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:66:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/fix.rs:66:1 clippy::struct_excessive_bools "more than 3 bools in a struct" @@ -944,11 +944,11 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:35:1 clippy::mod target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:87:1 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:8:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/lockfile.rs:8:1 clippy::module_name_repetitions "item name ends with its containing module's name" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:150:21 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:150:21 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:188:1 clippy::too_many_lines "this function has too many lines (130/100)" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:212:32 clippy::if_not_else "unnecessary `!=` operation" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:222:53 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:224:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:222:53 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:224:44 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:31:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:346:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/registry.rs:346:1 clippy::module_name_repetitions "item name starts with its containing module's name" @@ -1018,14 +1018,14 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/ops/vendor.rs:70:1 clippy::too_m target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:102:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:111:28 clippy::needless_question_mark "question mark operator is useless here" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:133:48 clippy::needless_question_mark "question mark operator is useless here" -target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:135:67 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:135:67 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:206:36 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:282:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:70:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:81:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/config.rs:97:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/directory.rs:14:1 clippy::module_name_repetitions "item name starts with its containing module's name" -target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/directory.rs:90:56 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/directory.rs:90:56 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:25:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/source.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -1058,18 +1058,16 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/git/utils.rs:858:1 clipp target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:129:44 clippy::match_same_arms "this `match` has identical arm bodies" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:143:44 clippy::match_same_arms "this `match` has identical arm bodies" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" -target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:282:50 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:282:50 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:313:21 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:314:21 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:319:21 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:339:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:339:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:380:9 clippy::unused_self "unused `self` argument" -target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:419:50 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:419:50 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:429:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:460:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:473:43 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:482:43 clippy::redundant_closure_for_method_calls "redundant closure found" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:63:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/path.rs:98:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1077,7 +1075,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:117:23 target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:121:70 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:167:1 clippy::module_name_repetitions "item name ends with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:215:1 clippy::module_name_repetitions "item name starts with its containing module's name" -target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:324:23 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:324:23 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:468:40 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:590:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/sources/registry/index.rs:648:17 clippy::similar_names "binding's name is too similar to existing binding" @@ -1123,14 +1121,14 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:387:5 cl target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:39:20 clippy::doc_markdown "you should put `arg_package_spec` between ticks in the documentation" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:504:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:516:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:530:40 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:531:43 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:530:40 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:531:43 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:536:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:556:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:575:49 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:575:49 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:580:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:631:18 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:638:18 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:631:18 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:638:18 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:647:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:651:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/command_prelude.rs:662:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -1208,7 +1206,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:595:20 clippy target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:689:20 clippy::unused_self "unused `self` argument" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::fn_params_excessive_bools "more than 3 bools in function parameters" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:748:30 clippy::manual_map "manual implementation of `Option::map`" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/mod.rs:816:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/config/path.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name" @@ -1224,7 +1222,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:11:5 clippy::missing target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:22:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:82:25 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/cpu.rs:82:9 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:109:27 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:109:27 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/dependency_queue.rs:156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -1274,7 +1272,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missi target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/flock.rs:96:17 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/graph.rs:10:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/graph.rs:41:51 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/graph.rs:41:51 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/graph.rs:45:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hasher.rs:12:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/hasher.rs:9:1 clippy::module_name_repetitions "item name ends with its containing module's name" @@ -1332,7 +1330,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:312:1 clippy::miss target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:346:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:415:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:445:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:459:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:459:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/paths.rs:514:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" @@ -1382,7 +1380,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:35:1 cl target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:45:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:89:21 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:89:21 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/restricted_names.rs:8:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" @@ -1398,7 +1396,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/sha256.rs:40:24 clippy::uns target/lintcheck/sources/cargo-0.49.0/src/cargo/util/to_semver.rs:5:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1005:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1005:5 clippy::too_many_lines "this function has too many lines (282/100)" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1094:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1094:36 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1121:13 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:1197:32 clippy::map_unwrap_or "called `map().unwrap_or_else()` on an `Option` value. This can be done more directly by calling `map_or_else(, )` instead" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:124:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1424,7 +1422,7 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:536:5 clippy::m target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:783:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:824:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:834:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:83:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:83:42 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::too_many_lines "this function has too many lines (138/100)" @@ -1432,13 +1430,12 @@ target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:962:9 clippy::i target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:979:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:98:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/mod.rs:999:23 clippy::default_trait_access "calling `util::toml::DetailedTomlDependency::default()` is more clear than this expression" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:112:27 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:112:27 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:325:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:586:21 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:593:42 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:605:19 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:756:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:586:21 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:593:42 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:605:19 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/cargo-0.49.0/src/cargo/util/toml/targets.rs:612:42 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:10:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:33:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/cargo-0.49.0/src/cargo/util/vcs.rs:37:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" @@ -1561,14 +1558,32 @@ target/lintcheck/sources/iron-0.6.1/src/request/url.rs:73:5 clippy::must_use_can target/lintcheck/sources/iron-0.6.1/src/request/url.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/iron-0.6.1/src/request/url.rs:96:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/iron-0.6.1/src/response.rs:121:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/iron-0.6.1/src/response.rs:125:43 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/iron-0.6.1/src/response.rs:139:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/iron-0.6.1/src/response.rs:125:43 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/iron-0.6.1/src/response.rs:139:41 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/iron-0.6.1/src/response.rs:24:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" target/lintcheck/sources/iron-0.6.1/src/response.rs:95:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/iron-0.6.1/src/response.rs:95:5 clippy::new_without_default "you should consider adding a `Default` implementation for `response::Response`" target/lintcheck/sources/libc-0.2.81/build.rs:114:19 clippy::map_unwrap_or "called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead" target/lintcheck/sources/libc-0.2.81/build.rs:124:5 clippy::question_mark "this block may be rewritten with the `?` operator" target/lintcheck/sources/libc-0.2.81/build.rs:133:5 clippy::question_mark "this block may be rewritten with the `?` operator" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:120:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" target/lintcheck/sources/libc-0.2.81/src/macros.rs:243:17 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" @@ -1607,6 +1622,144 @@ target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_can target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" target/lintcheck/sources/libc-0.2.81/src/macros.rs:259:null clippy::must_use_candidate "this function could have a `#[must_use]` attribute" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/macros.rs:84:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:428:29 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:429:30 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs:431:30 clippy::unreadable_literal "long literal lacking separators" @@ -1712,6 +1865,7 @@ target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:299:11 target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:302:5 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:312:11 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:328:9 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:352:20 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:355:13 clippy::missing_safety_doc "unsafe function's docs miss `# Safety` section" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/gnu/mod.rs:355:13 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -1918,6 +2072,7 @@ target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2664:25 cl target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2665:16 clippy::identity_op "the operation is ineffective. Consider reducing it to `(minor & 0x000000ff)`" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2665:25 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:2666:25 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:42:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/linux/mod.rs:954:34 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1000:31 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1001:32 clippy::unreadable_literal "long literal lacking separators" @@ -1995,6 +2150,7 @@ target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1127:29 clippy:: target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1128:31 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1179:32 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1180:31 clippy::unreadable_literal "long literal lacking separators" +target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:11:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1218:27 clippy::identity_op "the operation is ineffective. Consider reducing it to `IPOPT_CONTROL`" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1314:9 clippy::precedence "operator precedence can trip the unwary" target/lintcheck/sources/libc-0.2.81/src/unix/linux_like/mod.rs:1321:13 clippy::ptr_as_ptr "`as` casting between raw pointers without changing its mutability" @@ -2036,7 +2192,10 @@ target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:282:40 clippy::unreadable_l target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:284:41 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:285:36 clippy::unreadable_literal "long literal lacking separators" target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:34:10 clippy::upper_case_acronyms "name `DIR` contains a capitalized acronym" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:36:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:386:10 clippy::upper_case_acronyms "name `FILE` contains a capitalized acronym" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:388:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" +target/lintcheck/sources/libc-0.2.81/src/unix/mod.rs:396:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type" target/lintcheck/sources/log-0.4.11/src/lib.rs:1047:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/log-0.4.11/src/lib.rs:1053:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/log-0.4.11/src/lib.rs:1059:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -2375,7 +2534,7 @@ target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:57:1 clippy::module_name_ target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:80:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section" target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:80:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:80:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute" -target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:81:35 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:81:35 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:93:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u32`. This is usually a bad idea" target/lintcheck/sources/rand-0.7.3/src/rngs/thread.rs:98:5 clippy::inline_always "you have declared `#[inline(always)]` on `next_u64`. This is usually a bad idea" target/lintcheck/sources/rand-0.7.3/src/seq/index.rs:127:1 clippy::module_name_repetitions "item name starts with its containing module's name" @@ -2734,10 +2893,10 @@ target/lintcheck/sources/regex-1.3.2/src/compile.rs:1040:38 clippy::cast_possibl target/lintcheck/sources/regex-1.3.2/src/compile.rs:1051:25 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" target/lintcheck/sources/regex-1.3.2/src/compile.rs:1071:8 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type" target/lintcheck/sources/regex-1.3.2/src/compile.rs:112:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section" -target/lintcheck/sources/regex-1.3.2/src/compile.rs:154:30 clippy::redundant_closure_for_method_calls "redundant closure found" -target/lintcheck/sources/regex-1.3.2/src/compile.rs:156:30 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:154:30 clippy::redundant_closure_for_method_calls "redundant closure" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:156:30 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/regex-1.3.2/src/compile.rs:185:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" -target/lintcheck/sources/regex-1.3.2/src/compile.rs:187:40 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/regex-1.3.2/src/compile.rs:187:40 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/regex-1.3.2/src/compile.rs:201:53 clippy::doc_markdown "you should put `MaybeInsts` between ticks in the documentation" target/lintcheck/sources/regex-1.3.2/src/compile.rs:241:63 clippy::doc_markdown "you should put `c_concat` between ticks in the documentation" target/lintcheck/sources/regex-1.3.2/src/compile.rs:245:5 clippy::too_many_lines "this function has too many lines (111/100)" @@ -2961,7 +3120,7 @@ target/lintcheck/sources/regex-1.3.2/src/input.rs:271:13 clippy::enum_glob_use " target/lintcheck/sources/regex-1.3.2/src/input.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/input.rs:362:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/input.rs:370:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/regex-1.3.2/src/input.rs:371:42 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/regex-1.3.2/src/input.rs:371:42 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/regex-1.3.2/src/input.rs:37:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/input.rs:388:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/input.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -3067,21 +3226,25 @@ target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:55:47 clippy::redundant_fie target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:572:29 clippy::doc_markdown "you should put `is_match` between ticks in the documentation" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:720:13 clippy::redundant_field_names "redundant field names in struct initialization" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:817:5 clippy::doc_markdown "you should put `CaptureLocations` between ticks in the documentation" -target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:843:1 clippy::len_without_is_empty "item `re_bytes::CaptureLocations` has a public `len` method but no corresponding `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:849:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:858:5 clippy::len_without_is_empty "struct `CaptureLocations` has a public `len` method, but no `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:858:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:869:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:891:1 clippy::len_without_is_empty "item `re_bytes::Captures<'t>` has a public `len` method but no corresponding `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:911:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:917:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:926:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:955:5 clippy::len_without_is_empty "struct `Captures` has a public `len` method, but no `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_bytes.rs:955:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:179:13 clippy::redundant_field_names "redundant field names in struct initialization" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:179:13 clippy::redundant_field_names "redundant field names in struct initialization" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:206:5 clippy::len_without_is_empty "struct `RegexSet` has a public `len` method, but no `is_empty` method" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:206:5 clippy::len_without_is_empty "struct `RegexSet` has a public `len` method, but no `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:251:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:251:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:268:5 clippy::len_without_is_empty "struct `SetMatches` has a public `len` method, but no `is_empty` method" +target/lintcheck/sources/regex-1.3.2/src/re_set.rs:268:5 clippy::len_without_is_empty "struct `SetMatches` has a public `len` method, but no `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:268:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_set.rs:277:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" @@ -3107,14 +3270,14 @@ target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:631:29 clippy::doc_markdo target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:64:33 clippy::redundant_field_names "redundant field names in struct initialization" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:64:47 clippy::redundant_field_names "redundant field names in struct initialization" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:834:5 clippy::doc_markdown "you should put `CaptureLocations` between ticks in the documentation" -target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:860:1 clippy::len_without_is_empty "item `re_unicode::CaptureLocations` has a public `len` method but no corresponding `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:866:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:875:5 clippy::len_without_is_empty "struct `CaptureLocations` has a public `len` method, but no `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:875:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:886:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" -target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:908:1 clippy::len_without_is_empty "item `re_unicode::Captures<'t>` has a public `len` method but no corresponding `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:928:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:934:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:943:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" +target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:972:5 clippy::len_without_is_empty "struct `Captures` has a public `len` method, but no `is_empty` method" target/lintcheck/sources/regex-1.3.2/src/re_unicode.rs:972:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute" target/lintcheck/sources/regex-1.3.2/src/sparse.rs:10:37 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link" target/lintcheck/sources/regex-1.3.2/src/sparse.rs:15:1 clippy::module_name_repetitions "item name starts with its containing module's name" @@ -3146,7 +3309,7 @@ target/lintcheck/sources/regex-1.3.2/src/utf8.rs:92:9 clippy::unusual_byte_group target/lintcheck/sources/regex-1.3.2/src/utf8.rs:97:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four" target/lintcheck/sources/ripgrep-12.1.1/build.rs:133:19 clippy::option_as_ref_deref "called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `githash.as_deref()` instead" target/lintcheck/sources/ripgrep-12.1.1/build.rs:18:18 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/ripgrep-12.1.1/build.rs:225:14 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/build.rs:225:14 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/ripgrep-12.1.1/build.rs:92:19 clippy::option_as_ref_deref "called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `githash.as_deref()` instead" target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1408:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" target/lintcheck/sources/ripgrep-12.1.1/crates/core/app.rs:1408:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope" @@ -3188,10 +3351,10 @@ target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1209:74 clippy::if_s target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1282:13 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1430:22 clippy::unused_self "unused `self` argument" target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1438:21 clippy::doc_markdown "you should put `OsStr` between ticks in the documentation" -target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1520:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1520:44 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1524:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`" target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1635:14 clippy::doc_markdown "you should put `values_of_lossy` between ticks in the documentation" -target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1693:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1693:41 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1770:17 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:1829:5 clippy::let_underscore_drop "non-binding `let` on a type that implements `Drop`" target/lintcheck/sources/ripgrep-12.1.1/crates/core/args.rs:287:13 clippy::similar_names "binding's name is too similar to existing binding" @@ -3228,14 +3391,14 @@ target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:377:12 clippy::non target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:423:13 clippy::enum_glob_use "usage of wildcard import for enum variants" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:447:13 clippy::enum_glob_use "usage of wildcard import for enum variants" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:472:24 clippy::map_clone "you are using an explicit closure for cloning elements" -target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:472:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:472:41 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:480:24 clippy::map_clone "you are using an explicit closure for cloning elements" -target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:480:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:480:41 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:49:1 clippy::module_name_repetitions "item name starts with its containing module's name" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:509:24 clippy::map_clone "you are using an explicit closure for cloning elements" -target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:509:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:509:41 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:517:24 clippy::map_clone "you are using an explicit closure for cloning elements" -target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:517:41 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:517:41 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:533:36 clippy::cast_lossless "casting `u32` to `f64` may become silently lossy if you later change the type" target/lintcheck/sources/ripgrep-12.1.1/crates/core/search.rs:533:5 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)" target/lintcheck/sources/ripgrep-12.1.1/crates/core/subject.rs:20:1 clippy::module_name_repetitions "item name starts with its containing module's name" @@ -3291,7 +3454,7 @@ target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:68:10 clippy::doc_markdown target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:70:28 clippy::doc_markdown "you should put `ID_Continue` between ticks in the documentation" target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:70:72 clippy::doc_markdown "you should put `NFKx` between ticks in the documentation" target/lintcheck/sources/unicode-xid-0.2.1/src/lib.rs:71:24 clippy::wrong_self_convention "methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name" -target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:101:34 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:101:34 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:42:1 clippy::struct_excessive_bools "more than 3 bools in a struct" target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:53:9 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/xsv-0.13.0/src/cmd/cat.rs:7:16 clippy::redundant_static_lifetimes "statics have by default a `'static` lifetime" @@ -3337,7 +3500,7 @@ target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:308:9 clippy::unused_self "u target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:342:38 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:342:46 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore" target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:347:9 clippy::if_not_else "unnecessary boolean `not` operation" -target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:372:44 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:372:44 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:375:33 clippy::similar_names "binding's name is too similar to existing binding" target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:392:13 clippy::redundant_field_names "redundant field names in struct initialization" target/lintcheck/sources/xsv-0.13.0/src/cmd/join.rs:403:29 clippy::explicit_into_iter_loop "it is more concise to loop over containers instead of using explicit iteration methods" @@ -3377,7 +3540,7 @@ target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:61:9 clippy::similar_names target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:94:5 clippy::unnecessary_wraps "this function's return value is unnecessary" target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:96:14 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" target/lintcheck/sources/xsv-0.13.0/src/cmd/split.rs:99:13 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" -target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:110:36 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:110:36 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:127:14 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:138:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:139:43 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers" @@ -3406,11 +3569,11 @@ target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:301:21 clippy::option_map_u target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:302:21 clippy::option_map_unit_fn "called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:308:18 clippy::wrong_self_convention "methods called `to_*` usually take self by reference; consider choosing a less ambiguous name" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:318:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:322:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:322:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:322:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:327:9 clippy::if_not_else "unnecessary boolean `not` operation" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:330:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`" -target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:338:45 clippy::redundant_closure_for_method_calls "redundant closure found" +target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:338:45 clippy::redundant_closure_for_method_calls "redundant closure" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:402:16 clippy::redundant_pattern_matching "redundant pattern matching, consider using `is_ok()`" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:403:16 clippy::redundant_pattern_matching "redundant pattern matching, consider using `is_ok()`" target/lintcheck/sources/xsv-0.13.0/src/cmd/stats.rs:407:18 clippy::trivially_copy_pass_by_ref "this argument (1 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)" @@ -3492,7 +3655,6 @@ clippy::used_underscore_binding 1 clippy::verbose_bit_mask 1 clippy::while_let_on_iterator 1 clippy::comparison_to_empty 2 -clippy::expl_impl_clone_on_copy 2 clippy::filter_map 2 clippy::from_over_into 2 clippy::len_zero 2 @@ -3520,7 +3682,6 @@ clippy::too_many_arguments 4 clippy::explicit_iter_loop 5 clippy::field_reassign_with_default 5 clippy::identity_op 5 -clippy::len_without_is_empty 5 clippy::match_like_matches_macro 5 clippy::needless_return 5 clippy::new_without_default 5 @@ -3538,6 +3699,7 @@ clippy::upper_case_acronyms 7 clippy::invalid_upcast_comparisons 8 clippy::needless_question_mark 8 clippy::wrong_self_convention 8 +clippy::len_without_is_empty 9 clippy::multiple_crate_versions 9 clippy::manual_range_contains 10 clippy::match_wildcard_for_single_variants 10 @@ -3576,10 +3738,11 @@ clippy::match_same_arms 62 clippy::similar_names 83 clippy::cast_possible_truncation 95 clippy::redundant_field_names 111 -clippy::redundant_closure_for_method_calls 135 +clippy::redundant_closure_for_method_calls 131 clippy::items_after_statements 143 clippy::module_name_repetitions 146 clippy::wildcard_imports 164 +clippy::expl_impl_clone_on_copy 165 clippy::doc_markdown 184 clippy::missing_errors_doc 356 clippy::unreadable_literal 365 From b068b742ee9dac585cdaf781a09bbdabba9c27a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 11 Mar 2021 15:18:56 +0100 Subject: [PATCH 221/226] lintcheck: fix --fix and document it in the readme. also hook lintcheck into clippy-dev so that `clippy dev fmt` formats it. --- clippy_dev/src/fmt.rs | 1 + lintcheck/README.md | 6 ++++++ lintcheck/src/main.rs | 6 +++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/clippy_dev/src/fmt.rs b/clippy_dev/src/fmt.rs index 4d0fdadbd85d1..a26d6aba10d20 100644 --- a/clippy_dev/src/fmt.rs +++ b/clippy_dev/src/fmt.rs @@ -54,6 +54,7 @@ pub fn run(check: bool, verbose: bool) { success &= cargo_fmt(context, project_root.as_path())?; success &= cargo_fmt(context, &project_root.join("clippy_dev"))?; success &= cargo_fmt(context, &project_root.join("rustc_tools_util"))?; + success &= cargo_fmt(context, &project_root.join("lintcheck"))?; for entry in WalkDir::new(project_root.join("tests")) { let entry = entry?; diff --git a/lintcheck/README.md b/lintcheck/README.md index 68dbf56401441..983f59efdbd22 100644 --- a/lintcheck/README.md +++ b/lintcheck/README.md @@ -67,3 +67,9 @@ is checked. **Note:** `-Wclippy::all` is always enabled by default, unless `-Aclippy::all` is explicitly specified in the options. + +### Fix mode +You can run `./lintcheck/target/debug/lintcheck --fix` which will run Clippy with `-Zunstable-options --fix` and print a warning if Clippys suggestions fail to apply (if the resulting code does not build). +This lets us spot bad suggestions or false positives automatically in some cases. + +Please note that the target dir should be cleaned afterwards since clippy will modify the downloaded sources which can lead to unexpected results when running lintcheck again afterwards. \ No newline at end of file diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 1964afd36095d..4028be0bf6564 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -862,7 +862,11 @@ fn get_clap_config<'a>() -> ArgMatches<'a> { .long("jobs") .help("number of threads to use, 0 automatic choice"), ) - .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply")) + .arg( + Arg::with_name("fix") + .long("--fix") + .help("runs cargo clippy --fix and checks if all suggestions apply"), + ) .get_matches() } From 528e464b4f4f48613f8ad22fdd4dc77c93e5546d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 11 Mar 2021 15:25:43 +0100 Subject: [PATCH 222/226] lintcheck: fix clippy warnings --- lintcheck/Cargo.toml | 6 ++++++ lintcheck/src/main.rs | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml index 5eb9e4aacae98..8db6d28e5acae 100644 --- a/lintcheck/Cargo.toml +++ b/lintcheck/Cargo.toml @@ -2,7 +2,13 @@ name = "lintcheck" version = "0.0.1" authors = ["The Rust Clippy Developers"] +description = "tool to monitor impact of changes in Clippys lints on a part of the ecosystem" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/rust-clippy" +categories = ["development-tools"] edition = "2018" +publish = false [dependencies] clap = "2.33" diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 4028be0bf6564..581b47647eb18 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -499,7 +499,7 @@ fn parse_json_message(json_message: &str, krate: &Crate) -> ClippyWarning { // /home/matthias/.cargo/registry/src/github.com-1ecc6299db9ec823/syn-1.0.63/src/custom_keyword.rs let path = PathBuf::from(file); - let mut piter = path.into_iter(); + let mut piter = path.iter(); // consume all elements until we find ".cargo", so that "/home/matthias" is skipped let _: Option<&OsStr> = piter.find(|x| x == &std::ffi::OsString::from(".cargo")); // collect the remaining segments @@ -594,7 +594,7 @@ fn is_in_clippy_root() -> bool { /// This function panics if the clippy binaries don't exist /// or if lintcheck is executed from the wrong directory (aka none-repo-root) pub fn main() { - // assert that we launch lintcheck from the repo root (via cargo dev-lintcheck) + // assert that we launch lintcheck from the repo root (via cargo lintcheck) if !is_in_clippy_root() { eprintln!("lintcheck needs to be run from clippys repo root!\nUse `cargo lintcheck` alternatively."); std::process::exit(3); From ac935781f5c7bf49a4366a63050a0e180f4a16c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 11 Mar 2021 15:37:10 +0100 Subject: [PATCH 223/226] docs: basics.md: mention lintcheck --- doc/basics.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/basics.md b/doc/basics.md index a9416f3b20b7a..426271db43785 100644 --- a/doc/basics.md +++ b/doc/basics.md @@ -11,8 +11,9 @@ the codebase take a look at [Adding Lints] or [Common Tools]. - [Get the Code](#get-the-code) - [Building and Testing](#building-and-testing) - [`cargo dev`](#cargo-dev) - - [Common Abbreviations](#common-abbreviations) + - [lintcheck](#lintcheck) - [PR](#pr) + - [Common Abbreviations](#common-abbreviations) ## Get the Code @@ -91,6 +92,13 @@ cargo dev new_lint cargo dev ra_setup ``` +## lintcheck +`cargo lintcheck` will build and run clippy on a fixed set of crates and generate a log of the results. You can `git diff` the updated log against its previous version and see what impact your lint made on a small set of crates. +If you add a new lint, please audit the resulting warnings and make sure there are no false positives and that the suggestions are valid. + +Refer to the tools [README] for more details. + +[README]: https://github.com/rust-lang/rust-clippy/blob/master/lintcheck/README.md ## PR We follow a rustc no merge-commit policy. From 0af90fd15a48352232d03d7f68bc4f2f2b194f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 11 Mar 2021 15:47:51 +0100 Subject: [PATCH 224/226] doc line length fixes --- doc/basics.md | 7 +++++-- lintcheck/README.md | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/basics.md b/doc/basics.md index 426271db43785..c56e84e2e32a2 100644 --- a/doc/basics.md +++ b/doc/basics.md @@ -93,8 +93,11 @@ cargo dev ra_setup ``` ## lintcheck -`cargo lintcheck` will build and run clippy on a fixed set of crates and generate a log of the results. You can `git diff` the updated log against its previous version and see what impact your lint made on a small set of crates. -If you add a new lint, please audit the resulting warnings and make sure there are no false positives and that the suggestions are valid. +`cargo lintcheck` will build and run clippy on a fixed set of crates and generate a log of the results. +You can `git diff` the updated log against its previous version and +see what impact your lint made on a small set of crates. +If you add a new lint, please audit the resulting warnings and make sure +there are no false positives and that the suggestions are valid. Refer to the tools [README] for more details. diff --git a/lintcheck/README.md b/lintcheck/README.md index 983f59efdbd22..52bbcc0a8317d 100644 --- a/lintcheck/README.md +++ b/lintcheck/README.md @@ -69,7 +69,9 @@ is checked. is explicitly specified in the options. ### Fix mode -You can run `./lintcheck/target/debug/lintcheck --fix` which will run Clippy with `-Zunstable-options --fix` and print a warning if Clippys suggestions fail to apply (if the resulting code does not build). +You can run `./lintcheck/target/debug/lintcheck --fix` which will run Clippy with `-Zunstable-options --fix` and +print a warning if Clippys suggestions fail to apply (if the resulting code does not build). This lets us spot bad suggestions or false positives automatically in some cases. -Please note that the target dir should be cleaned afterwards since clippy will modify the downloaded sources which can lead to unexpected results when running lintcheck again afterwards. \ No newline at end of file +Please note that the target dir should be cleaned afterwards since clippy will modify +the downloaded sources which can lead to unexpected results when running lintcheck again afterwards. From 412ebc3972374d2a506457b077a58cc5b56664e4 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 12 Mar 2021 15:31:11 +0100 Subject: [PATCH 225/226] Update Cargo.lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 2c9eaebb5fdc2..64e8811a8724c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,6 +570,7 @@ dependencies = [ "clippy_lints", "compiletest_rs 0.6.0", "derive-new", + "regex", "rustc-workspace-hack", "rustc_tools_util 0.2.0", "semver 0.11.0", From 99d05196d6d366e2b23a736232c8d53826738d43 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 12 Mar 2021 15:32:04 +0100 Subject: [PATCH 226/226] Clippy: HACK! Fix bootstrap error This will be removed in the next sync, once beta is at 1.52. Until then this hack avoids to put `cfg(bootstrap)` into Clippy. --- src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs index fad96c2d5c04c..11660a8fe0dfb 100644 --- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs +++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs @@ -203,8 +203,11 @@ struct MinifyingSugg<'a>(Sugg<'a>); impl<'a> MinifyingSugg<'a> { fn as_str(&self) -> &str { - let (Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s)) = &self.0; - s.as_ref() + // HACK: Don't sync to Clippy! Required because something with the `or_patterns` feature + // changed and this would now require parentheses. + match &self.0 { + Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) => s.as_ref(), + } } fn into_sugg(self) -> Sugg<'a> {