From 8d24facccbccd893176c38e7fc8460a22f860774 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 11 Aug 2019 09:24:03 +0200 Subject: [PATCH 01/30] docs: Explain how to update the changelog --- CHANGELOG.md | 2 ++ doc/changelog_update.md | 59 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 doc/changelog_update.md diff --git a/CHANGELOG.md b/CHANGELOG.md index e4a1a602c439..ec8e8929bfd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Change Log All notable changes to this project will be documented in this file. +See [Changelog Update](doc/changelog_update.md) if you want to update this +document. ## Unreleased / In Rust Beta or Nightly diff --git a/doc/changelog_update.md b/doc/changelog_update.md new file mode 100644 index 000000000000..b54143e23574 --- /dev/null +++ b/doc/changelog_update.md @@ -0,0 +1,59 @@ +# Changelog Update + +If you want to help with updating the [changelog][changelog], you're in the right place. + +## When to update + +The changelog is ideally updated during the week before an upcoming stable +release. Typos and other small fixes/additions are always welcome. You can find +the release dates on the [Rust Forge][forge]. + +Most of the time we only need to update the changelog for minor Rust releases. It's +been very rare that Clippy changes were included in a patch release. + +## How to update + +### 1. Finding the relevant Clippy commits + +Each Rust release ships with its own version of Clippy. The Clippy submodule can +be found in the [tools][tools] directory of the Rust repository. + +To find the Clippy commit hash for a specific Rust release you select the Rust +release tag from the dropdown and then check the commit of the Clippy directory: + +TODO: Include screenshot + +### 2. Fetching the PRs between those commits + +You'll want to run `util/fetch_prs_between.sh commit1 commit2 > changes.txt` +and open that file in your editor of choice. + +* `commit1` is the Clippy commit hash of the previous stable release +* `commit2` is the Clippy commit hash of the release you want to write the changelog for. + +When updating the changelog it's also a good idea to make sure that `commit1` is +already correct in the current changelog. + +### 3. Authoring the final changelog + +The above script should have dumped all the relevant PRs to the file you +specified. It should have filtered out most of the irrelevant PRs +already, but it's a good idea to do a manual cleanup pass where you look for +more irrelevant PRs. If you're not sure about some PRs, just leave them in for +the review and ask for feedback. + +With PRs filtered, you can start to take each PR and move the +`changelog: ` content to `CHANGELOG.md`. Adapt the wording as you see fit but +try to keep it somewhat coherent. + +The order should roughly be: + +1. New lints +2. Changes that expand what code existing lints cover +3. ICE fixes +4. False positive fixes +5. Suggestion fixes/improvements + +[changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md +[forge]: https://forge.rust-lang.org/ +[tools]: https://github.com/rust-lang/rust/tree/master/src/tools From c90eb4f4b3778a3b3d1e3c804dfce279380bf6f1 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Mon, 12 Aug 2019 06:56:54 +0200 Subject: [PATCH 02/30] Add image --- doc/changelog_update.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog_update.md b/doc/changelog_update.md index b54143e23574..2198029bf781 100644 --- a/doc/changelog_update.md +++ b/doc/changelog_update.md @@ -21,7 +21,7 @@ be found in the [tools][tools] directory of the Rust repository. To find the Clippy commit hash for a specific Rust release you select the Rust release tag from the dropdown and then check the commit of the Clippy directory: -TODO: Include screenshot +![Explanation of how to find the commit hash](https://user-images.githubusercontent.com/2042399/62846160-1f8b0480-bcce-11e9-9da8-7964ca034e7a.png) ### 2. Fetching the PRs between those commits From 38c1971b435ce67d2f47960dcb7dbf03a3d67447 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Mon, 12 Aug 2019 19:19:46 +0200 Subject: [PATCH 03/30] Further text improvements --- doc/changelog_update.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/changelog_update.md b/doc/changelog_update.md index 2198029bf781..4eb97b48b9cb 100644 --- a/doc/changelog_update.md +++ b/doc/changelog_update.md @@ -4,9 +4,12 @@ If you want to help with updating the [changelog][changelog], you're in the righ ## When to update -The changelog is ideally updated during the week before an upcoming stable -release. Typos and other small fixes/additions are always welcome. You can find -the release dates on the [Rust Forge][forge]. +Typos and other small fixes/additions are _always_ welcome. + +Special care needs to be taken when it comes to updating the changelog for a new +Rust release. For that purpose, the changelog is ideally updated during the week +before an upcoming stable release. You can find the release dates on the [Rust +Forge][forge]. Most of the time we only need to update the changelog for minor Rust releases. It's been very rare that Clippy changes were included in a patch release. @@ -42,7 +45,7 @@ already, but it's a good idea to do a manual cleanup pass where you look for more irrelevant PRs. If you're not sure about some PRs, just leave them in for the review and ask for feedback. -With PRs filtered, you can start to take each PR and move the +With the PRs filtered, you can start to take each PR and move the `changelog: ` content to `CHANGELOG.md`. Adapt the wording as you see fit but try to keep it somewhat coherent. @@ -54,6 +57,9 @@ The order should roughly be: 4. False positive fixes 5. Suggestion fixes/improvements +Please also be sure to update the Beta/Unreleased sections at the top with the +relevant commit ranges. + [changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md [forge]: https://forge.rust-lang.org/ [tools]: https://github.com/rust-lang/rust/tree/master/src/tools From f4f31a4ff40a6763bb9adf7413773f3a6e701dd9 Mon Sep 17 00:00:00 2001 From: Jeremy Stucki Date: Thu, 15 Aug 2019 22:56:16 +0200 Subject: [PATCH 04/30] Implement lint 'suspicious_map' --- CHANGELOG.md | 1 + README.md | 2 +- clippy_lints/src/lib.rs | 1 + clippy_lints/src/methods/mod.rs | 28 ++++++++++++++++++++++++++++ src/lintlist/mod.rs | 9 ++++++++- 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e9013985eaf..7e5dfa112cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1152,6 +1152,7 @@ Released 2018-09-13 [`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl [`suspicious_assignment_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_assignment_formatting [`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting +[`suspicious_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_map [`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl [`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment [`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr diff --git a/README.md b/README.md index 8bcfd8a8430c..389fe316ade2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 309 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are 310 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index c8dbf77704c9..2108b65dbd8a 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -657,6 +657,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { methods::OPTION_MAP_UNWRAP_OR, methods::OPTION_MAP_UNWRAP_OR_ELSE, methods::RESULT_MAP_UNWRAP_OR_ELSE, + methods::SUSPICIOUS_MAP, misc::USED_UNDERSCORE_BINDING, misc_early::UNSEPARATED_LITERAL_SUFFIX, mut_mut::MUT_MUT, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 0020dbd233d9..fc2d23415332 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -889,6 +889,23 @@ declare_clippy_lint! { "using `.into_iter()` on a reference" } +declare_clippy_lint! { + /// **What it does:** Checks for calls to `map` followed by a `count`. + /// + /// **Why is this bad?** It looks suspicious. Maybe `map` was confused with `filter`. + /// + /// **Known problems:** None + /// + /// **Example:** + /// + /// ```rust + /// let _ = (0..3).map(|x| x + 2).count(); + /// ``` + pub SUSPICIOUS_MAP, + pedantic, + "suspicious usage of map" +} + declare_lint_pass!(Methods => [ OPTION_UNWRAP_USED, RESULT_UNWRAP_USED, @@ -927,6 +944,7 @@ declare_lint_pass!(Methods => [ UNNECESSARY_FILTER_MAP, INTO_ITER_ON_ARRAY, INTO_ITER_ON_REF, + SUSPICIOUS_MAP, ]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { @@ -972,6 +990,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]), ["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0]), ["filter_map", ..] => unnecessary_filter_map::lint(cx, expr, arg_lists[0]), + ["count", "map"] => lint_suspicious_map(cx, expr), _ => {}, } @@ -2519,6 +2538,15 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: Ty<'_ } } +fn lint_suspicious_map(cx: &LateContext<'_, '_>, expr: &hir::Expr) { + span_lint( + cx, + SUSPICIOUS_MAP, + expr.span, + "Make sure you did not confuse `map` with `filter`.", + ); +} + /// Given a `Result` type, return its error type (`E`). fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option> { if let ty::Adt(_, substs) = ty.sty { diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index c02cdcdbd45a..2d4520fb2281 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -6,7 +6,7 @@ pub use lint::Lint; pub use lint::LINT_LEVELS; // begin lint list, do not remove this comment, it’s used in `update_lints` -pub const ALL_LINTS: [Lint; 309] = [ +pub const ALL_LINTS: [Lint; 310] = [ Lint { name: "absurd_extreme_comparisons", group: "correctness", @@ -1736,6 +1736,13 @@ pub const ALL_LINTS: [Lint; 309] = [ deprecation: None, module: "formatting", }, + Lint { + name: "suspicious_map", + group: "pedantic", + desc: "suspicious usage of map", + deprecation: None, + module: "methods", + }, Lint { name: "suspicious_op_assign_impl", group: "correctness", From 72e4e4ac6cb18e4e15c789cc0e9786b1d1d54d36 Mon Sep 17 00:00:00 2001 From: Jeremy Stucki Date: Thu, 15 Aug 2019 22:56:27 +0200 Subject: [PATCH 05/30] Add ui test --- tests/ui/suspicious_map.rs | 5 +++++ tests/ui/suspicious_map.stderr | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 tests/ui/suspicious_map.rs create mode 100644 tests/ui/suspicious_map.stderr diff --git a/tests/ui/suspicious_map.rs b/tests/ui/suspicious_map.rs new file mode 100644 index 000000000000..d838d8fde210 --- /dev/null +++ b/tests/ui/suspicious_map.rs @@ -0,0 +1,5 @@ +#![warn(clippy::suspicious_map)] + +fn main() { + let _ = (0..3).map(|x| x + 2).count(); +} diff --git a/tests/ui/suspicious_map.stderr b/tests/ui/suspicious_map.stderr new file mode 100644 index 000000000000..434ea089fedf --- /dev/null +++ b/tests/ui/suspicious_map.stderr @@ -0,0 +1,10 @@ +error: Make sure you did not confuse `map` with `filter`. + --> $DIR/suspicious_map.rs:4:13 + | +LL | let _ = (0..3).map(|x| x + 2).count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::suspicious-map` implied by `-D warnings` + +error: aborting due to previous error + From c1e57402d314d24dd1eaa20b13f082707288cce1 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sat, 17 Aug 2019 11:45:05 +0100 Subject: [PATCH 06/30] Made lint pedantic --- clippy_lints/src/trait_bounds.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index bf4c5d65db63..edb91d617ee4 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// pub fn foo(t: T) where T: Copy + Clone {} /// ``` pub TYPE_REPETITION_IN_BOUNDS, - complexity, + pedantic, "Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`" } From b17cb32bcb2b70697a80512846cf10f434e6173f Mon Sep 17 00:00:00 2001 From: BO41 Date: Sat, 17 Aug 2019 13:09:03 +0000 Subject: [PATCH 07/30] Add "could be written as" example to MANUAL_MEMCPY --- clippy_lints/src/loops.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 7b36fa7e284b..62c9e904f7a1 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -48,6 +48,12 @@ declare_clippy_lint! { /// dst[i + 64] = src[i]; /// } /// ``` + /// Could be written as: + /// ```rust + /// # let src = vec![1]; + /// # let mut dst = vec![0; 65]; + /// dst[64..(src.len() + 64)].clone_from_slice(&src[..]); + /// ``` pub MANUAL_MEMCPY, perf, "manually copying items between slices" From c8fb62148e1339a8361c297d1166beae802a85bc Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Sat, 17 Aug 2019 17:10:10 +1200 Subject: [PATCH 08/30] Add autofixable suggestion for unseparated integer literal suffices --- clippy_lints/src/misc_early.rs | 36 ++++++++++++++++++++++++++++------ tests/ui/literals.stderr | 12 ++++++------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index b998d3f8a331..aabd5ace3317 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -396,11 +396,23 @@ impl MiscEarlyLints { if char::to_digit(firstch, 10).is_some(); then { let mut prev = '\0'; - for ch in src.chars() { + for (idx, ch) in src.chars().enumerate() { if ch == 'i' || ch == 'u' { if prev != '_' { - span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span, - "integer type suffix should be separated by an underscore"); + span_lint_and_then( + cx, + UNSEPARATED_LITERAL_SUFFIX, + lit.span, + "integer type suffix should be separated by an underscore", + |db| { + db.span_suggestion( + lit.span, + "add an underscore", + format!("{}_{}", &src[0..idx], &src[idx..]), + Applicability::MachineApplicable, + ); + }, + ); } break; } @@ -451,11 +463,23 @@ impl MiscEarlyLints { if char::to_digit(firstch, 10).is_some(); then { let mut prev = '\0'; - for ch in src.chars() { + for (idx, ch) in src.chars().enumerate() { if ch == 'f' { if prev != '_' { - span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span, - "float type suffix should be separated by an underscore"); + span_lint_and_then( + cx, + UNSEPARATED_LITERAL_SUFFIX, + lit.span, + "float type suffix should be separated by an underscore", + |db| { + db.span_suggestion( + lit.span, + "add an underscore", + format!("{}_{}", &src[0..idx], &src[idx..]), + Applicability::MachineApplicable, + ); + }, + ); } break; } diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr index 22692160d73a..c140bd88e815 100644 --- a/tests/ui/literals.stderr +++ b/tests/ui/literals.stderr @@ -22,7 +22,7 @@ error: integer type suffix should be separated by an underscore --> $DIR/literals.rs:16:27 | LL | let fail_multi_zero = 000_123usize; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: add an underscore: `000_123_usize` | = note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings` @@ -46,31 +46,31 @@ error: integer type suffix should be separated by an underscore --> $DIR/literals.rs:21:17 | LL | let fail3 = 1234i32; - | ^^^^^^^ + | ^^^^^^^ help: add an underscore: `1234_i32` error: integer type suffix should be separated by an underscore --> $DIR/literals.rs:22:17 | LL | let fail4 = 1234u32; - | ^^^^^^^ + | ^^^^^^^ help: add an underscore: `1234_u32` error: integer type suffix should be separated by an underscore --> $DIR/literals.rs:23:17 | LL | let fail5 = 1234isize; - | ^^^^^^^^^ + | ^^^^^^^^^ help: add an underscore: `1234_isize` error: integer type suffix should be separated by an underscore --> $DIR/literals.rs:24:17 | LL | let fail6 = 1234usize; - | ^^^^^^^^^ + | ^^^^^^^^^ help: add an underscore: `1234_usize` error: float type suffix should be separated by an underscore --> $DIR/literals.rs:25:17 | LL | let fail7 = 1.5f32; - | ^^^^^^ + | ^^^^^^ help: add an underscore: `1.5_f32` error: this is a decimal constant --> $DIR/literals.rs:29:17 From 9c39c02b758c96d94ea1ba648ef77efff2631b86 Mon Sep 17 00:00:00 2001 From: Jeremy Stucki Date: Sun, 18 Aug 2019 16:49:11 +0200 Subject: [PATCH 09/30] Change lint type to 'complexity' --- clippy_lints/src/lib.rs | 3 ++- clippy_lints/src/methods/mod.rs | 10 ++++++---- src/lintlist/mod.rs | 2 +- tests/ui/suspicious_map.stderr | 3 ++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 308c3e918e85..705ec2e9fd8e 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -657,7 +657,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { methods::OPTION_MAP_UNWRAP_OR, methods::OPTION_MAP_UNWRAP_OR_ELSE, methods::RESULT_MAP_UNWRAP_OR_ELSE, - methods::SUSPICIOUS_MAP, misc::USED_UNDERSCORE_BINDING, misc_early::UNSEPARATED_LITERAL_SUFFIX, mut_mut::MUT_MUT, @@ -801,6 +800,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { methods::SHOULD_IMPLEMENT_TRAIT, methods::SINGLE_CHAR_PATTERN, methods::STRING_EXTEND_CHARS, + methods::SUSPICIOUS_MAP, methods::TEMPORARY_CSTRING_AS_PTR, methods::UNNECESSARY_FILTER_MAP, methods::UNNECESSARY_FOLD, @@ -1034,6 +1034,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { methods::FILTER_NEXT, methods::FLAT_MAP_IDENTITY, methods::SEARCH_IS_SOME, + methods::SUSPICIOUS_MAP, methods::UNNECESSARY_FILTER_MAP, methods::USELESS_ASREF, misc::SHORT_CIRCUIT_STATEMENT, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index fc2d23415332..c8e3ca14ab11 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -18,7 +18,6 @@ use syntax::ast; use syntax::source_map::Span; use syntax::symbol::LocalInternedString; -use crate::utils::paths; use crate::utils::sugg; use crate::utils::usage::mutated_variables; use crate::utils::{ @@ -28,6 +27,7 @@ use crate::utils::{ snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq, }; +use crate::utils::{paths, span_help_and_lint}; declare_clippy_lint! { /// **What it does:** Checks for `.unwrap()` calls on `Option`s. @@ -893,6 +893,7 @@ declare_clippy_lint! { /// **What it does:** Checks for calls to `map` followed by a `count`. /// /// **Why is this bad?** It looks suspicious. Maybe `map` was confused with `filter`. + /// If the `map` call is intentional, this should be rewritten. /// /// **Known problems:** None /// @@ -902,7 +903,7 @@ declare_clippy_lint! { /// let _ = (0..3).map(|x| x + 2).count(); /// ``` pub SUSPICIOUS_MAP, - pedantic, + complexity, "suspicious usage of map" } @@ -2539,11 +2540,12 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: Ty<'_ } fn lint_suspicious_map(cx: &LateContext<'_, '_>, expr: &hir::Expr) { - span_lint( + span_help_and_lint( cx, SUSPICIOUS_MAP, expr.span, - "Make sure you did not confuse `map` with `filter`.", + "this call to `map()` won't have an effect on the call to `count()`", + "make sure you did not confuse `map` with `filter`", ); } diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 36a45f705e78..ff7db0a3da77 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1738,7 +1738,7 @@ pub const ALL_LINTS: [Lint; 310] = [ }, Lint { name: "suspicious_map", - group: "pedantic", + group: "complexity", desc: "suspicious usage of map", deprecation: None, module: "methods", diff --git a/tests/ui/suspicious_map.stderr b/tests/ui/suspicious_map.stderr index 434ea089fedf..e6588f4691a1 100644 --- a/tests/ui/suspicious_map.stderr +++ b/tests/ui/suspicious_map.stderr @@ -1,10 +1,11 @@ -error: Make sure you did not confuse `map` with `filter`. +error: this call to `map()` won't have an effect on the call to `count()` --> $DIR/suspicious_map.rs:4:13 | LL | let _ = (0..3).map(|x| x + 2).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::suspicious-map` implied by `-D warnings` + = help: make sure you did not confuse `map` with `filter` error: aborting due to previous error From 802a6d33dae32a116881990566bb1d5d7e62a9ab Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Mon, 19 Aug 2019 02:52:59 +1200 Subject: [PATCH 10/30] run-rustfix for unseparated-prefix-literals --- tests/ui/unseparated_prefix_literals.fixed | 20 +++++++++ tests/ui/unseparated_prefix_literals.rs | 20 +++++++++ tests/ui/unseparated_prefix_literals.stderr | 46 +++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 tests/ui/unseparated_prefix_literals.fixed create mode 100644 tests/ui/unseparated_prefix_literals.rs create mode 100644 tests/ui/unseparated_prefix_literals.stderr diff --git a/tests/ui/unseparated_prefix_literals.fixed b/tests/ui/unseparated_prefix_literals.fixed new file mode 100644 index 000000000000..1948b18d1639 --- /dev/null +++ b/tests/ui/unseparated_prefix_literals.fixed @@ -0,0 +1,20 @@ +// run-rustfix + +#![warn(clippy::unseparated_literal_suffix)] +#![allow(dead_code)] + +fn main() { + let _ok1 = 1234_i32; + let _ok2 = 1234_isize; + let _ok3 = 0x123_isize; + let _fail1 = 1234_i32; + let _fail2 = 1234_u32; + let _fail3 = 1234_isize; + let _fail4 = 1234_usize; + let _fail5 = 0x123_isize; + + let _okf1 = 1.5_f32; + let _okf2 = 1_f32; + let _failf1 = 1.5_f32; + let _failf2 = 1_f32; +} diff --git a/tests/ui/unseparated_prefix_literals.rs b/tests/ui/unseparated_prefix_literals.rs new file mode 100644 index 000000000000..d70b1cf29f53 --- /dev/null +++ b/tests/ui/unseparated_prefix_literals.rs @@ -0,0 +1,20 @@ +// run-rustfix + +#![warn(clippy::unseparated_literal_suffix)] +#![allow(dead_code)] + +fn main() { + let _ok1 = 1234_i32; + let _ok2 = 1234_isize; + let _ok3 = 0x123_isize; + let _fail1 = 1234i32; + let _fail2 = 1234u32; + let _fail3 = 1234isize; + let _fail4 = 1234usize; + let _fail5 = 0x123isize; + + let _okf1 = 1.5_f32; + let _okf2 = 1_f32; + let _failf1 = 1.5f32; + let _failf2 = 1f32; +} diff --git a/tests/ui/unseparated_prefix_literals.stderr b/tests/ui/unseparated_prefix_literals.stderr new file mode 100644 index 000000000000..2b8121db3fc0 --- /dev/null +++ b/tests/ui/unseparated_prefix_literals.stderr @@ -0,0 +1,46 @@ +error: integer type suffix should be separated by an underscore + --> $DIR/unseparated_prefix_literals.rs:10:18 + | +LL | let _fail1 = 1234i32; + | ^^^^^^^ help: add an underscore: `1234_i32` + | + = note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings` + +error: integer type suffix should be separated by an underscore + --> $DIR/unseparated_prefix_literals.rs:11:18 + | +LL | let _fail2 = 1234u32; + | ^^^^^^^ help: add an underscore: `1234_u32` + +error: integer type suffix should be separated by an underscore + --> $DIR/unseparated_prefix_literals.rs:12:18 + | +LL | let _fail3 = 1234isize; + | ^^^^^^^^^ help: add an underscore: `1234_isize` + +error: integer type suffix should be separated by an underscore + --> $DIR/unseparated_prefix_literals.rs:13:18 + | +LL | let _fail4 = 1234usize; + | ^^^^^^^^^ help: add an underscore: `1234_usize` + +error: integer type suffix should be separated by an underscore + --> $DIR/unseparated_prefix_literals.rs:14:18 + | +LL | let _fail5 = 0x123isize; + | ^^^^^^^^^^ help: add an underscore: `0x123_isize` + +error: float type suffix should be separated by an underscore + --> $DIR/unseparated_prefix_literals.rs:18:19 + | +LL | let _failf1 = 1.5f32; + | ^^^^^^ help: add an underscore: `1.5_f32` + +error: float type suffix should be separated by an underscore + --> $DIR/unseparated_prefix_literals.rs:19:19 + | +LL | let _failf2 = 1f32; + | ^^^^ help: add an underscore: `1_f32` + +error: aborting due to 7 previous errors + From 76598adafb2c3032a87544b260584fb526a6f2a5 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sun, 18 Aug 2019 16:59:31 +0100 Subject: [PATCH 11/30] Run update_lints --- clippy_lints/src/lib.rs | 3 +-- src/lintlist/mod.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 3054f11c1769..8f5dc88e6de9 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -666,6 +666,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { replace_consts::REPLACE_CONSTS, shadow::SHADOW_UNRELATED, strings::STRING_ADD_ASSIGN, + trait_bounds::TYPE_REPETITION_IN_BOUNDS, types::CAST_POSSIBLE_TRUNCATION, types::CAST_POSSIBLE_WRAP, types::CAST_PRECISION_LOSS, @@ -870,7 +871,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { swap::ALMOST_SWAPPED, swap::MANUAL_SWAP, temporary_assignment::TEMPORARY_ASSIGNMENT, - trait_bounds::TYPE_REPETITION_IN_BOUNDS, transmute::CROSSPOINTER_TRANSMUTE, transmute::TRANSMUTE_BYTES_TO_STR, transmute::TRANSMUTE_INT_TO_BOOL, @@ -1056,7 +1056,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reference::REF_IN_DEREF, swap::MANUAL_SWAP, temporary_assignment::TEMPORARY_ASSIGNMENT, - trait_bounds::TYPE_REPETITION_IN_BOUNDS, transmute::CROSSPOINTER_TRANSMUTE, transmute::TRANSMUTE_BYTES_TO_STR, transmute::TRANSMUTE_INT_TO_BOOL, diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 0df8370936c8..7d36825df0ab 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1857,7 +1857,7 @@ pub const ALL_LINTS: [Lint; 309] = [ }, Lint { name: "type_repetition_in_bounds", - group: "complexity", + group: "pedantic", desc: "Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`", deprecation: None, module: "trait_bounds", From 4ee9d02efa1be614482fe6082851302eb2f330f6 Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Mon, 19 Aug 2019 14:18:05 +1200 Subject: [PATCH 12/30] Requested changes --- clippy_lints/src/misc_early.rs | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index aabd5ace3317..c8ac26044ebc 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -1,4 +1,6 @@ -use crate::utils::{constants, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then}; +use crate::utils::{ + constants, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, +}; use if_chain::if_chain; use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; @@ -399,19 +401,14 @@ impl MiscEarlyLints { for (idx, ch) in src.chars().enumerate() { if ch == 'i' || ch == 'u' { if prev != '_' { - span_lint_and_then( + span_lint_and_sugg( cx, UNSEPARATED_LITERAL_SUFFIX, lit.span, "integer type suffix should be separated by an underscore", - |db| { - db.span_suggestion( - lit.span, - "add an underscore", - format!("{}_{}", &src[0..idx], &src[idx..]), - Applicability::MachineApplicable, - ); - }, + "add an underscore", + format!("{}_{}", &src[0..idx], &src[idx..]), + Applicability::MachineApplicable, ); } break; @@ -466,19 +463,14 @@ impl MiscEarlyLints { for (idx, ch) in src.chars().enumerate() { if ch == 'f' { if prev != '_' { - span_lint_and_then( + span_lint_and_sugg( cx, UNSEPARATED_LITERAL_SUFFIX, lit.span, "float type suffix should be separated by an underscore", - |db| { - db.span_suggestion( - lit.span, - "add an underscore", - format!("{}_{}", &src[0..idx], &src[idx..]), - Applicability::MachineApplicable, - ); - }, + "add an underscore", + format!("{}_{}", &src[0..idx], &src[idx..]), + Applicability::MachineApplicable, ); } break; From 7065239da55420e26adb7cb647fc7eb4e9c8798e Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 15 Aug 2019 10:53:11 +0700 Subject: [PATCH 13/30] Add option_and_then_some lint --- CHANGELOG.md | 1 + README.md | 2 +- clippy_dev/src/lib.rs | 6 +- clippy_lints/src/lib.rs | 2 + clippy_lints/src/methods/mod.rs | 129 +++++++++++++++++++++++++-- src/lintlist/mod.rs | 9 +- tests/ui/option_and_then_some.fixed | 21 +++++ tests/ui/option_and_then_some.rs | 21 +++++ tests/ui/option_and_then_some.stderr | 20 +++++ 9 files changed, 201 insertions(+), 10 deletions(-) create mode 100644 tests/ui/option_and_then_some.fixed create mode 100644 tests/ui/option_and_then_some.rs create mode 100644 tests/ui/option_and_then_some.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e5dfa112cfb..59dfde0b6f4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1088,6 +1088,7 @@ Released 2018-09-13 [`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref [`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect [`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref +[`option_and_then_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_and_then_some [`option_map_or_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_none [`option_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unit_fn [`option_map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or diff --git a/README.md b/README.md index 389fe316ade2..e5da763607bd 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 310 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are 311 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index db407565b19b..b53a55799713 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -123,13 +123,13 @@ pub fn gen_deprecated(lints: &[Lint]) -> Vec { lints .iter() .filter_map(|l| { - l.clone().deprecation.and_then(|depr_text| { - Some(vec![ + l.clone().deprecation.map(|depr_text| { + vec![ " store.register_removed(".to_string(), format!(" \"clippy::{}\",", l.name), format!(" \"{}\",", depr_text), " );".to_string(), - ]) + ] }) }) .flatten() diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 7e9a251d4bd3..4d568a8a8b09 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -795,6 +795,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { methods::ITER_SKIP_NEXT, methods::NEW_RET_NO_SELF, methods::OK_EXPECT, + methods::OPTION_AND_THEN_SOME, methods::OPTION_MAP_OR_NONE, methods::OR_FUN_CALL, methods::SEARCH_IS_SOME, @@ -1033,6 +1034,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { methods::CLONE_ON_COPY, methods::FILTER_NEXT, methods::FLAT_MAP_IDENTITY, + methods::OPTION_AND_THEN_SOME, methods::SEARCH_IS_SOME, methods::SUSPICIOUS_MAP, methods::UNNECESSARY_FILTER_MAP, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c8e3ca14ab11..8d062bd897cb 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -21,11 +21,11 @@ use syntax::symbol::LocalInternedString; use crate::utils::sugg; use crate::utils::usage::mutated_variables; use crate::utils::{ - get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, is_copy, - is_ctor_function, is_expn_of, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method, - match_type, match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, - snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_sugg, - span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq, + get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, in_macro_or_desugar, + is_copy, is_ctor_function, is_expn_of, iter_input_pats, last_path_segment, match_def_path, match_qpath, + match_trait_method, match_type, match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, + single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, + span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq, }; use crate::utils::{paths, span_help_and_lint}; @@ -264,6 +264,32 @@ declare_clippy_lint! { "using `Option.map_or(None, f)`, which is more succinctly expressed as `and_then(f)`" } +declare_clippy_lint! { + /// **What it does:** Checks for usage of `_.and_then(|x| Some(y))`. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.map(|x| y)`. + /// + /// **Known problems:** None + /// + /// **Example:** + /// + /// ```rust + /// let x = Some("foo"); + /// let _ = x.and_then(|s| Some(s.len())); + /// ``` + /// + /// The correct use would be: + /// + /// ```rust + /// let x = Some("foo"); + /// let _ = x.map(|s| s.len()); + /// ``` + pub OPTION_AND_THEN_SOME, + complexity, + "using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`" +} + declare_clippy_lint! { /// **What it does:** Checks for usage of `_.filter(_).next()`. /// @@ -918,6 +944,7 @@ declare_lint_pass!(Methods => [ OPTION_MAP_UNWRAP_OR_ELSE, RESULT_MAP_UNWRAP_OR_ELSE, OPTION_MAP_OR_NONE, + OPTION_AND_THEN_SOME, OR_FUN_CALL, EXPECT_FUN_CALL, CHARS_NEXT_CMP, @@ -967,6 +994,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { ["unwrap_or", "map"] => option_map_unwrap_or::lint(cx, expr, arg_lists[1], arg_lists[0]), ["unwrap_or_else", "map"] => lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0]), ["map_or", ..] => lint_map_or_none(cx, expr, arg_lists[0]), + ["and_then", ..] => lint_option_and_then_some(cx, expr, arg_lists[0]), ["next", "filter"] => lint_filter_next(cx, expr, arg_lists[1]), ["map", "filter"] => lint_filter_map(cx, expr, arg_lists[1], arg_lists[0]), ["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]), @@ -2072,6 +2100,97 @@ fn lint_map_or_none<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, } } +/// Lint use of `_.and_then(|x| Some(y))` for `Option`s +fn lint_option_and_then_some(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) { + const LINT_MSG: &str = "using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`"; + const NO_OP_MSG: &str = "using `Option.and_then(Some)`, which is a no-op"; + + // Searches an return expressions in `y` in `_.and_then(|x| Some(y))`, which we don't lint + struct RetCallFinder { + found: bool, + } + + impl<'tcx> intravisit::Visitor<'tcx> for RetCallFinder { + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { + if self.found { + return; + } + if let hir::ExprKind::Ret(..) = &expr.node { + self.found = true; + } else { + intravisit::walk_expr(self, expr); + } + } + + fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> { + intravisit::NestedVisitorMap::None + } + } + + let ty = cx.tables.expr_ty(&args[0]); + if !match_type(cx, ty, &paths::OPTION) { + return; + } + + match args[1].node { + hir::ExprKind::Closure(_, _, body_id, closure_args_span, _) => { + let closure_body = cx.tcx.hir().body(body_id); + let closure_expr = remove_blocks(&closure_body.value); + if_chain! { + if let hir::ExprKind::Call(ref some_expr, ref some_args) = closure_expr.node; + if let hir::ExprKind::Path(ref qpath) = some_expr.node; + if match_qpath(qpath, &paths::OPTION_SOME); + if some_args.len() == 1; + then { + let inner_expr = &some_args[0]; + + let mut finder = RetCallFinder { found: false }; + finder.visit_expr(inner_expr); + if finder.found { + return; + } + + let some_inner_snip = if in_macro_or_desugar(inner_expr.span) { + snippet_with_macro_callsite(cx, inner_expr.span, "_") + } else { + snippet(cx, inner_expr.span, "_") + }; + + let closure_args_snip = snippet(cx, closure_args_span, ".."); + let option_snip = snippet(cx, args[0].span, ".."); + let note = format!("{}.map({} {})", option_snip, closure_args_snip, some_inner_snip); + span_lint_and_sugg( + cx, + OPTION_AND_THEN_SOME, + expr.span, + LINT_MSG, + "try this", + note, + Applicability::MachineApplicable, + ); + } + } + }, + // `_.and_then(Some)` case, which is no-op. + hir::ExprKind::Path(ref qpath) => { + if match_qpath(qpath, &paths::OPTION_SOME) { + let option_snip = snippet(cx, args[0].span, ".."); + let note = format!("{}", option_snip); + span_lint_and_sugg( + cx, + OPTION_AND_THEN_SOME, + expr.span, + NO_OP_MSG, + "use the expression directly", + note, + Applicability::MachineApplicable, + ); + } + }, + _ => {}, + } +} + /// lint use of `filter().next()` for `Iterators` fn lint_filter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, filter_args: &'tcx [hir::Expr]) { // lint if caller of `.filter().next()` is an Iterator diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 485352f5cc4a..9abe4558bb91 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -6,7 +6,7 @@ pub use lint::Lint; pub use lint::LINT_LEVELS; // begin lint list, do not remove this comment, it’s used in `update_lints` -pub const ALL_LINTS: [Lint; 310] = [ +pub const ALL_LINTS: [Lint; 311] = [ Lint { name: "absurd_extreme_comparisons", group: "correctness", @@ -1316,6 +1316,13 @@ pub const ALL_LINTS: [Lint; 310] = [ deprecation: None, module: "eq_op", }, + Lint { + name: "option_and_then_some", + group: "complexity", + desc: "using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`", + deprecation: None, + module: "methods", + }, Lint { name: "option_map_or_none", group: "style", diff --git a/tests/ui/option_and_then_some.fixed b/tests/ui/option_and_then_some.fixed new file mode 100644 index 000000000000..852f48879a35 --- /dev/null +++ b/tests/ui/option_and_then_some.fixed @@ -0,0 +1,21 @@ +// run-rustfix +#![deny(clippy::option_and_then_some)] + +// need a main anyway, use it get rid of unused warnings too +pub fn main() { + let x = Some(5); + // the easiest cases + let _ = x; + let _ = x.map(|o| o + 1); + // and an easy counter-example + let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); + + // Different type + let x: Result = Ok(1); + let _ = x.and_then(Ok); +} + +pub fn foo() -> Option { + let x = Some(String::from("hello")); + Some("hello".to_owned()).and_then(|s| Some(format!("{}{}", s, x?))) +} diff --git a/tests/ui/option_and_then_some.rs b/tests/ui/option_and_then_some.rs new file mode 100644 index 000000000000..aebc66374a51 --- /dev/null +++ b/tests/ui/option_and_then_some.rs @@ -0,0 +1,21 @@ +// run-rustfix +#![deny(clippy::option_and_then_some)] + +// need a main anyway, use it get rid of unused warnings too +pub fn main() { + let x = Some(5); + // the easiest cases + let _ = x.and_then(Some); + let _ = x.and_then(|o| Some(o + 1)); + // and an easy counter-example + let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); + + // Different type + let x: Result = Ok(1); + let _ = x.and_then(Ok); +} + +pub fn foo() -> Option { + let x = Some(String::from("hello")); + Some("hello".to_owned()).and_then(|s| Some(format!("{}{}", s, x?))) +} diff --git a/tests/ui/option_and_then_some.stderr b/tests/ui/option_and_then_some.stderr new file mode 100644 index 000000000000..a3b0a26149e1 --- /dev/null +++ b/tests/ui/option_and_then_some.stderr @@ -0,0 +1,20 @@ +error: using `Option.and_then(Some)`, which is a no-op + --> $DIR/option_and_then_some.rs:8:13 + | +LL | let _ = x.and_then(Some); + | ^^^^^^^^^^^^^^^^ help: use the expression directly: `x` + | +note: lint level defined here + --> $DIR/option_and_then_some.rs:2:9 + | +LL | #![deny(clippy::option_and_then_some)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)` + --> $DIR/option_and_then_some.rs:9:13 + | +LL | let _ = x.and_then(|o| Some(o + 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.map(|o| o + 1)` + +error: aborting due to 2 previous errors + From 50ecd595a6d8ec66299c4ce2f1804a381458d74f Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 16 Aug 2019 09:42:07 +0700 Subject: [PATCH 14/30] Allow option_and_then_some in option_map_or_none test --- tests/ui/option_map_or_none.fixed | 2 ++ tests/ui/option_map_or_none.rs | 2 ++ tests/ui/option_map_or_none.stderr | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/ui/option_map_or_none.fixed b/tests/ui/option_map_or_none.fixed index e637f973c2ea..decbae4e5af9 100644 --- a/tests/ui/option_map_or_none.fixed +++ b/tests/ui/option_map_or_none.fixed @@ -1,5 +1,7 @@ // run-rustfix +#![allow(clippy::option_and_then_some)] + fn main() { let opt = Some(1); diff --git a/tests/ui/option_map_or_none.rs b/tests/ui/option_map_or_none.rs index 4b9b247880a0..0f1d2218d5d3 100644 --- a/tests/ui/option_map_or_none.rs +++ b/tests/ui/option_map_or_none.rs @@ -1,5 +1,7 @@ // run-rustfix +#![allow(clippy::option_and_then_some)] + fn main() { let opt = Some(1); diff --git a/tests/ui/option_map_or_none.stderr b/tests/ui/option_map_or_none.stderr index 66ed1e9f0451..eb5c68ed79f3 100644 --- a/tests/ui/option_map_or_none.stderr +++ b/tests/ui/option_map_or_none.stderr @@ -1,5 +1,5 @@ error: called `map_or(None, f)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/option_map_or_none.rs:8:13 + --> $DIR/option_map_or_none.rs:10:13 | LL | let _ = opt.map_or(None, |x| Some(x + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using and_then instead: `opt.and_then(|x| Some(x + 1))` @@ -7,7 +7,7 @@ LL | let _ = opt.map_or(None, |x| Some(x + 1)); = note: `-D clippy::option-map-or-none` implied by `-D warnings` error: called `map_or(None, f)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/option_map_or_none.rs:11:13 + --> $DIR/option_map_or_none.rs:13:13 | LL | let _ = opt.map_or(None, |x| { | _____________^ From 88f417e446282d7c32c648e30815aebcb4d2c8b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 19 Aug 2019 06:10:00 +0200 Subject: [PATCH 15/30] try to fix build in rustc repo --- clippy_lints/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 956bc858a179..48133cc5b02b 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -28,7 +28,8 @@ serde = { version = "1.0", features = ["derive"] } toml = "0.5.3" unicode-normalization = "0.1" pulldown-cmark = "0.5.3" -url = "2.1.0" +url = { version = "2.1.0", features = ["serde"] } # cargo requires serde feat in its url dep +# see https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864 if_chain = "1.0.0" smallvec = { version = "0.6.5", features = ["union"] } From 41eba2f26aa0bb45148d37e9696b73322f8d6ca0 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Mon, 19 Aug 2019 05:41:47 +0000 Subject: [PATCH 16/30] Add test --- tests/ui/option_and_then_some.fixed | 4 ++++ tests/ui/option_and_then_some.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/ui/option_and_then_some.fixed b/tests/ui/option_and_then_some.fixed index 852f48879a35..035bc1e54656 100644 --- a/tests/ui/option_and_then_some.fixed +++ b/tests/ui/option_and_then_some.fixed @@ -19,3 +19,7 @@ pub fn foo() -> Option { let x = Some(String::from("hello")); Some("hello".to_owned()).and_then(|s| Some(format!("{}{}", s, x?))) } + +pub fn example2(x: bool) -> Option<&'static str> { + Some("a").and_then(|s| Some(if x { s } else { return None })) +} diff --git a/tests/ui/option_and_then_some.rs b/tests/ui/option_and_then_some.rs index aebc66374a51..d49da7813c6e 100644 --- a/tests/ui/option_and_then_some.rs +++ b/tests/ui/option_and_then_some.rs @@ -19,3 +19,7 @@ pub fn foo() -> Option { let x = Some(String::from("hello")); Some("hello".to_owned()).and_then(|s| Some(format!("{}{}", s, x?))) } + +pub fn example2(x: bool) -> Option<&'static str> { + Some("a").and_then(|s| Some(if x { s } else { return None })) +} From 68a1af540cc65c7ebc8804f615ade76359b7d2dc Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Mon, 19 Aug 2019 08:17:53 +0200 Subject: [PATCH 17/30] Fix `clone_on_copy` false positives Closes #4384 --- clippy_lints/src/methods/mod.rs | 40 +++++++++++++++---------------- tests/ui/unnecessary_clone.rs | 5 ++++ tests/ui/unnecessary_clone.stderr | 24 +++++++++---------- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c8e3ca14ab11..92ee50310f2b 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1521,30 +1521,30 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp 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.node { + // &*x is a nop, &x.clone() is not + hir::ExprKind::AddrOf(..) | + // (*x).func() is useless, x.clone().func() can work in case func borrows mutably + hir::ExprKind::MethodCall(..) => return, + _ => {}, + }, + hir::Node::Stmt(stmt) => { + if let hir::StmtKind::Local(ref loc) = stmt.node { + if let hir::PatKind::Ref(..) = loc.pat.node { + // 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.tables.expr_ty(arg) == ty { snip = Some(("try removing the `clone` call", format!("{}", snippet))); } else { - let parent = cx.tcx.hir().get_parent_node(expr.hir_id); - match cx.tcx.hir().get(parent) { - hir::Node::Expr(parent) => match parent.node { - // &*x is a nop, &x.clone() is not - hir::ExprKind::AddrOf(..) | - // (*x).func() is useless, x.clone().func() can work in case func borrows mutably - hir::ExprKind::MethodCall(..) => return, - _ => {}, - }, - hir::Node::Stmt(stmt) => { - if let hir::StmtKind::Local(ref loc) = stmt.node { - if let hir::PatKind::Ref(..) = loc.pat.node { - // let ref y = *x borrows x, let ref y = x.clone() does not - return; - } - } - }, - _ => {}, - } - let deref_count = cx .tables .expr_adjustments(arg) diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index 2e0fc1227781..4ff835115909 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -22,6 +22,11 @@ fn clone_on_copy() { let rc = RefCell::new(0); rc.borrow().clone(); + + // Issue #4348 + let mut x = 43; + let _ = &x.clone(); // ok, getting a ref + 'a'.clone().make_ascii_uppercase(); // ok, clone and then mutate } fn clone_on_ref_ptr() { diff --git a/tests/ui/unnecessary_clone.stderr b/tests/ui/unnecessary_clone.stderr index 79b99ff1d1d2..b1388044c42c 100644 --- a/tests/ui/unnecessary_clone.stderr +++ b/tests/ui/unnecessary_clone.stderr @@ -19,7 +19,7 @@ LL | rc.borrow().clone(); | ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()` error: using '.clone()' on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:34:5 + --> $DIR/unnecessary_clone.rs:39:5 | LL | rc.clone(); | ^^^^^^^^^^ help: try this: `Rc::::clone(&rc)` @@ -27,43 +27,43 @@ LL | rc.clone(); = note: `-D clippy::clone-on-ref-ptr` implied by `-D warnings` error: using '.clone()' on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:37:5 + --> $DIR/unnecessary_clone.rs:42:5 | LL | arc.clone(); | ^^^^^^^^^^^ help: try this: `Arc::::clone(&arc)` error: using '.clone()' on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:40:5 + --> $DIR/unnecessary_clone.rs:45:5 | LL | rcweak.clone(); | ^^^^^^^^^^^^^^ help: try this: `Weak::::clone(&rcweak)` error: using '.clone()' on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:43:5 + --> $DIR/unnecessary_clone.rs:48:5 | LL | arc_weak.clone(); | ^^^^^^^^^^^^^^^^ help: try this: `Weak::::clone(&arc_weak)` error: using '.clone()' on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:47:33 + --> $DIR/unnecessary_clone.rs:52:33 | LL | let _: Arc = x.clone(); | ^^^^^^^^^ help: try this: `Arc::::clone(&x)` error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:51:5 + --> $DIR/unnecessary_clone.rs:56:5 | LL | t.clone(); | ^^^^^^^^^ help: try removing the `clone` call: `t` error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:53:5 + --> $DIR/unnecessary_clone.rs:58:5 | LL | Some(t).clone(); | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)` error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:59:22 + --> $DIR/unnecessary_clone.rs:64:22 | LL | let z: &Vec<_> = y.clone(); | ^^^^^^^^^ @@ -79,7 +79,7 @@ LL | let z: &Vec<_> = &std::vec::Vec::clone(y); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> $DIR/unnecessary_clone.rs:66:27 + --> $DIR/unnecessary_clone.rs:71:27 | LL | let v2: Vec = v.iter().cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()` @@ -87,13 +87,13 @@ LL | let v2: Vec = v.iter().cloned().collect(); = note: `-D clippy::iter-cloned-collect` implied by `-D warnings` error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> $DIR/unnecessary_clone.rs:71:38 + --> $DIR/unnecessary_clone.rs:76:38 | LL | let _: Vec = vec![1, 2, 3].iter().cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()` error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> $DIR/unnecessary_clone.rs:76:24 + --> $DIR/unnecessary_clone.rs:81:24 | LL | .to_bytes() | ________________________^ @@ -103,7 +103,7 @@ LL | | .collect(); | |______________________^ help: try: `.to_vec()` error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:114:20 + --> $DIR/unnecessary_clone.rs:119:20 | LL | let _: E = a.clone(); | ^^^^^^^^^ help: try dereferencing it: `*****a` From 370433f6339856a2863ae85b98b6c2b09813a17a Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Mon, 19 Aug 2019 20:22:42 +1200 Subject: [PATCH 18/30] Requested test cleanup --- tests/ui/literals.rs | 11 +-------- tests/ui/literals.stderr | 50 +++++----------------------------------- 2 files changed, 7 insertions(+), 54 deletions(-) diff --git a/tests/ui/literals.rs b/tests/ui/literals.rs index 5f3f95bab980..be1d2ed2f4d6 100644 --- a/tests/ui/literals.rs +++ b/tests/ui/literals.rs @@ -1,7 +1,7 @@ #![warn(clippy::large_digit_groups)] #![warn(clippy::mixed_case_hex_literals)] -#![warn(clippy::unseparated_literal_suffix)] #![warn(clippy::zero_prefixed_literal)] +#![allow(clippy::unseparated_literal_suffix)] #![allow(dead_code)] fn main() { @@ -15,15 +15,6 @@ fn main() { let fail2 = 0xabCD_isize; let fail_multi_zero = 000_123usize; - let ok6 = 1234_i32; - let ok7 = 1234_f32; - let ok8 = 1234_isize; - let fail3 = 1234i32; - let fail4 = 1234u32; - let fail5 = 1234isize; - let fail6 = 1234usize; - let fail7 = 1.5f32; - let ok9 = 0; let ok10 = 0_i64; let fail8 = 0123; diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr index c140bd88e815..4f3d430c4d99 100644 --- a/tests/ui/literals.stderr +++ b/tests/ui/literals.stderr @@ -18,14 +18,6 @@ error: inconsistent casing in hexadecimal literal LL | let fail2 = 0xabCD_isize; | ^^^^^^^^^^^^ -error: integer type suffix should be separated by an underscore - --> $DIR/literals.rs:16:27 - | -LL | let fail_multi_zero = 000_123usize; - | ^^^^^^^^^^^^ help: add an underscore: `000_123_usize` - | - = note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings` - error: this is a decimal constant --> $DIR/literals.rs:16:27 | @@ -42,38 +34,8 @@ help: if you mean to use an octal constant, use `0o` LL | let fail_multi_zero = 0o123usize; | ^^^^^^^^^^ -error: integer type suffix should be separated by an underscore - --> $DIR/literals.rs:21:17 - | -LL | let fail3 = 1234i32; - | ^^^^^^^ help: add an underscore: `1234_i32` - -error: integer type suffix should be separated by an underscore - --> $DIR/literals.rs:22:17 - | -LL | let fail4 = 1234u32; - | ^^^^^^^ help: add an underscore: `1234_u32` - -error: integer type suffix should be separated by an underscore - --> $DIR/literals.rs:23:17 - | -LL | let fail5 = 1234isize; - | ^^^^^^^^^ help: add an underscore: `1234_isize` - -error: integer type suffix should be separated by an underscore - --> $DIR/literals.rs:24:17 - | -LL | let fail6 = 1234usize; - | ^^^^^^^^^ help: add an underscore: `1234_usize` - -error: float type suffix should be separated by an underscore - --> $DIR/literals.rs:25:17 - | -LL | let fail7 = 1.5f32; - | ^^^^^^ help: add an underscore: `1.5_f32` - error: this is a decimal constant - --> $DIR/literals.rs:29:17 + --> $DIR/literals.rs:20:17 | LL | let fail8 = 0123; | ^^^^ @@ -87,7 +49,7 @@ LL | let fail8 = 0o123; | ^^^^^ error: digit groups should be smaller - --> $DIR/literals.rs:40:18 + --> $DIR/literals.rs:31:18 | LL | let fail13 = 0x1_23456_78901_usize; | ^^^^^^^^^^^^^^^^^^^^^ help: consider: `0x0123_4567_8901_usize` @@ -95,7 +57,7 @@ LL | let fail13 = 0x1_23456_78901_usize; = note: `-D clippy::large-digit-groups` implied by `-D warnings` error: digits grouped inconsistently by underscores - --> $DIR/literals.rs:42:18 + --> $DIR/literals.rs:33:18 | LL | let fail19 = 12_3456_21; | ^^^^^^^^^^ help: consider: `12_345_621` @@ -103,16 +65,16 @@ LL | let fail19 = 12_3456_21; = note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings` error: digits grouped inconsistently by underscores - --> $DIR/literals.rs:43:18 + --> $DIR/literals.rs:34:18 | LL | let fail22 = 3__4___23; | ^^^^^^^^^ help: consider: `3_423` error: digits grouped inconsistently by underscores - --> $DIR/literals.rs:44:18 + --> $DIR/literals.rs:35:18 | LL | let fail23 = 3__16___23; | ^^^^^^^^^^ help: consider: `31_623` -error: aborting due to 15 previous errors +error: aborting due to 9 previous errors From 4a70ad43e1638f1338cca2565b83b55f2d5abf00 Mon Sep 17 00:00:00 2001 From: chansuke Date: Mon, 19 Aug 2019 18:27:47 +0900 Subject: [PATCH 19/30] Fix the name of a channel of discord in CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3eff20cead74..8786413c3a1b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Hello fellow Rustacean! Great to see your interest in compiler internals and lin Clippy welcomes contributions from everyone. There are many ways to contribute to Clippy and the following document explains how you can contribute and how to get started. If you have any questions about contributing or need help with anything, feel free to ask questions on issues or -visit the `#clippy` IRC channel on `irc.mozilla.org` or meet us in `#wg-clippy` on [Discord](https://discord.gg/rust-lang). +visit the `#clippy` IRC channel on `irc.mozilla.org` or meet us in `#clippy` on [Discord](https://discord.gg/rust-lang). All contributors are expected to follow the [Rust Code of Conduct](http://www.rust-lang.org/conduct.html). From 08d8ffc6a970a4e0886b36b332cdc4f6622e81f1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 19 Aug 2019 17:51:39 +0200 Subject: [PATCH 20/30] Import rustc_plugin from its new location Depends on https://github.com/rust-lang/rust/pull/62727 --- CONTRIBUTING.md | 10 +++++----- clippy_lints/src/lib.rs | 8 ++++---- src/driver.rs | 6 ++---- src/lib.rs | 4 +--- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8786413c3a1b..2a85197068f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -90,7 +90,7 @@ Clippy is a [rustc compiler plugin][compiler_plugin]. The main entry point is at pub mod else_if_without_else; // ... -pub fn register_plugins(reg: &mut rustc_plugin::Registry) { +pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry) { // ... reg.register_early_lint_pass(box else_if_without_else::ElseIfWithoutElse); // ... @@ -103,7 +103,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { } ``` -The [`rustc_plugin::PluginRegistry`][plugin_registry] provides two methods to register lints: [register_early_lint_pass][reg_early_lint_pass] and [register_late_lint_pass][reg_late_lint_pass]. +The [`plugin::PluginRegistry`][plugin_registry] provides two methods to register lints: [register_early_lint_pass][reg_early_lint_pass] and [register_late_lint_pass][reg_late_lint_pass]. Both take an object that implements an [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass] respectively. This is done in every single lint. It's worth noting that the majority of `clippy_lints/src/lib.rs` is autogenerated by `util/dev update_lints` and you don't have to add anything by hand. When you are writing your own lint, you can use that script to save you some time. @@ -193,9 +193,9 @@ or the [MIT](http://opensource.org/licenses/MIT) license. [lint_crate_entry]: https://github.com/rust-lang/rust-clippy/blob/c5b39a5917ffc0f1349b6e414fa3b874fdcf8429/clippy_lints/src/lib.rs [else_if_without_else]: https://github.com/rust-lang/rust-clippy/blob/c5b39a5917ffc0f1349b6e414fa3b874fdcf8429/clippy_lints/src/else_if_without_else.rs [compiler_plugin]: https://doc.rust-lang.org/unstable-book/language-features/plugin.html#lint-plugins -[plugin_registry]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_plugin/registry/struct.Registry.html -[reg_early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_plugin/registry/struct.Registry.html#method.register_early_lint_pass -[reg_late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_plugin/registry/struct.Registry.html#method.register_late_lint_pass +[plugin_registry]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_plugin_impl/registry/struct.Registry.html +[reg_early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_plugin_impl/registry/struct.Registry.html#method.register_early_lint_pass +[reg_late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_plugin_impl/registry/struct.Registry.html#method.register_late_lint_pass [early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.EarlyLintPass.html [late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.LateLintPass.html [toolstate_commit_history]: https://github.com/rust-lang-nursery/rust-toolstate/commits/master diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4d568a8a8b09..0ae93c6147ab 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -23,12 +23,12 @@ extern crate rustc; #[allow(unused_extern_crates)] extern crate rustc_data_structures; #[allow(unused_extern_crates)] +extern crate rustc_driver; +#[allow(unused_extern_crates)] extern crate rustc_errors; #[allow(unused_extern_crates)] extern crate rustc_mir; #[allow(unused_extern_crates)] -extern crate rustc_plugin; -#[allow(unused_extern_crates)] extern crate rustc_target; #[allow(unused_extern_crates)] extern crate rustc_typeck; @@ -320,7 +320,7 @@ pub fn register_pre_expansion_lints( } #[doc(hidden)] -pub fn read_conf(reg: &rustc_plugin::Registry<'_>) -> Conf { +pub fn read_conf(reg: &rustc_driver::plugin::Registry<'_>) -> Conf { match utils::conf::file_from_args(reg.args()) { Ok(file_name) => { // if the user specified a file, it must exist, otherwise default to `clippy.toml` but @@ -382,7 +382,7 @@ pub fn read_conf(reg: &rustc_plugin::Registry<'_>) -> Conf { /// Used in `./src/driver.rs`. #[allow(clippy::too_many_lines)] #[rustfmt::skip] -pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { +pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Conf) { let mut store = reg.sess.lint_store.borrow_mut(); register_removed_non_tool_lints(&mut store); diff --git a/src/driver.rs b/src/driver.rs index cec88be7eb1b..92f83f1a29e3 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -7,8 +7,6 @@ extern crate rustc_driver; #[allow(unused_extern_crates)] extern crate rustc_interface; -#[allow(unused_extern_crates)] -extern crate rustc_plugin; use rustc_interface::interface; use rustc_tools_util::*; @@ -65,7 +63,7 @@ struct ClippyCallbacks; impl rustc_driver::Callbacks for ClippyCallbacks { fn after_parsing(&mut self, compiler: &interface::Compiler) -> rustc_driver::Compilation { let sess = compiler.session(); - let mut registry = rustc_plugin::registry::Registry::new( + let mut registry = rustc_driver::plugin::registry::Registry::new( sess, compiler .parse() @@ -81,7 +79,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { let conf = clippy_lints::read_conf(®istry); clippy_lints::register_plugins(&mut registry, &conf); - let rustc_plugin::registry::Registry { + let rustc_driver::plugin::registry::Registry { early_lint_passes, late_lint_passes, lint_groups, diff --git a/src/lib.rs b/src/lib.rs index 86174a6b316f..76e1c711656b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,9 +7,7 @@ // (Currently there is no way to opt into sysroot crates without `extern crate`.) #[allow(unused_extern_crates)] extern crate rustc_driver; -#[allow(unused_extern_crates)] -extern crate rustc_plugin; -use self::rustc_plugin::Registry; +use self::rustc_driver::plugin::Registry; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry<'_>) { From 204b2f365864c304bcf510adeba77741653a7edf Mon Sep 17 00:00:00 2001 From: "KRAAI, MATTHEW [VISUS]" Date: Mon, 19 Aug 2019 09:30:32 -0700 Subject: [PATCH 21/30] Remove in_macro_or_desugar --- clippy_lints/src/assertions_on_constants.rs | 6 +++--- clippy_lints/src/attrs.rs | 6 +++--- clippy_lints/src/block_in_if_condition.rs | 6 +++--- clippy_lints/src/booleans.rs | 5 ++--- clippy_lints/src/cognitive_complexity.rs | 4 ++-- clippy_lints/src/collapsible_if.rs | 8 +++----- clippy_lints/src/copies.rs | 6 ++---- clippy_lints/src/double_parens.rs | 4 ++-- clippy_lints/src/enum_variants.rs | 4 ++-- clippy_lints/src/eq_op.rs | 6 ++---- clippy_lints/src/erasing_op.rs | 4 ++-- clippy_lints/src/format.rs | 5 ++--- clippy_lints/src/formatting.rs | 8 ++++---- clippy_lints/src/identity_conversion.rs | 5 ++--- clippy_lints/src/identity_op.rs | 4 ++-- clippy_lints/src/implicit_return.rs | 4 ++-- clippy_lints/src/inherent_to_string.rs | 6 +++--- clippy_lints/src/items_after_statements.rs | 6 +++--- clippy_lints/src/len_zero.rs | 8 +++----- clippy_lints/src/loops.rs | 6 +++--- clippy_lints/src/map_clone.rs | 5 ++--- clippy_lints/src/map_unit_fn.rs | 4 ++-- clippy_lints/src/matches.rs | 6 +++--- clippy_lints/src/methods/mod.rs | 12 +++++------ clippy_lints/src/misc.rs | 10 +++++----- clippy_lints/src/missing_doc.rs | 4 ++-- clippy_lints/src/needless_bool.rs | 4 ++-- clippy_lints/src/needless_borrow.rs | 6 +++--- clippy_lints/src/needless_borrowed_ref.rs | 4 ++-- clippy_lints/src/needless_continue.rs | 4 ++-- clippy_lints/src/needless_pass_by_value.rs | 6 +++--- clippy_lints/src/no_effect.rs | 8 ++++---- clippy_lints/src/non_copy_const.rs | 4 ++-- clippy_lints/src/precedence.rs | 4 ++-- clippy_lints/src/redundant_clone.rs | 6 +++--- .../src/redundant_static_lifetimes.rs | 4 ++-- clippy_lints/src/returns.rs | 10 +++++----- clippy_lints/src/strings.rs | 4 ++-- .../src/trivially_copy_pass_by_ref.rs | 6 +++--- clippy_lints/src/try_err.rs | 4 ++-- clippy_lints/src/types.rs | 20 +++++++++---------- clippy_lints/src/unused_label.rs | 4 ++-- clippy_lints/src/unwrap.rs | 6 ++---- clippy_lints/src/utils/mod.rs | 13 ++++-------- clippy_lints/src/utils/sugg.rs | 4 ++-- doc/adding_lints.md | 4 ++-- 46 files changed, 129 insertions(+), 148 deletions(-) diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index 32ca1cc1bb99..347c6478b47c 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -3,7 +3,7 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; use crate::consts::{constant, Constant}; -use crate::utils::{in_macro_or_desugar, is_direct_expn_of, is_expn_of, span_help_and_lint}; +use crate::utils::{is_direct_expn_of, is_expn_of, span_help_and_lint}; declare_clippy_lint! { /// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls. @@ -55,12 +55,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants { } }; if let Some(debug_assert_span) = is_expn_of(e.span, "debug_assert") { - if in_macro_or_desugar(debug_assert_span) { + if debug_assert_span.from_expansion() { return; } lint_assert_cb(true); } else if let Some(assert_span) = is_direct_expn_of(e.span, "assert") { - if in_macro_or_desugar(assert_span) { + if assert_span.from_expansion() { return; } lint_assert_cb(false); diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 64c8a715d5ef..1159df5475ac 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -2,8 +2,8 @@ use crate::reexport::*; use crate::utils::{ - in_macro_or_desugar, is_present_in_source, last_line_of_span, match_def_path, paths, snippet_opt, span_lint, - span_lint_and_sugg, span_lint_and_then, without_block_comments, + is_present_in_source, last_line_of_span, match_def_path, paths, snippet_opt, span_lint, span_lint_and_sugg, + span_lint_and_then, without_block_comments, }; use if_chain::if_chain; use rustc::hir::*; @@ -412,7 +412,7 @@ fn is_relevant_expr(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, exp } fn check_attrs(cx: &LateContext<'_, '_>, span: Span, name: Name, attrs: &[Attribute]) { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; } diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs index 4fd9e271af08..c2ff8c83373b 100644 --- a/clippy_lints/src/block_in_if_condition.rs +++ b/clippy_lints/src/block_in_if_condition.rs @@ -54,7 +54,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> { if let ExprKind::Closure(_, _, eid, _, _) = expr.node { let body = self.cx.tcx.hir().body(eid); let ex = &body.value; - if matches!(ex.node, ExprKind::Block(_, _)) && !in_macro_or_desugar(body.value.span) { + if matches!(ex.node, ExprKind::Block(_, _)) && !body.value.span.from_expansion() { self.found_block = Some(ex); return; } @@ -79,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition { if let Some(ex) = &block.expr { // don't dig into the expression here, just suggest that they remove // the block - if in_macro_or_desugar(expr.span) || differing_macro_contexts(expr.span, ex.span) { + if expr.span.from_expansion() || differing_macro_contexts(expr.span, ex.span) { return; } span_help_and_lint( @@ -96,7 +96,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition { } } else { let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span); - if in_macro_or_desugar(span) || differing_macro_contexts(expr.span, span) { + if span.from_expansion() || differing_macro_contexts(expr.span, span) { return; } // move block higher diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index caf418c9b5b4..b520a3e25769 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -1,6 +1,5 @@ use crate::utils::{ - get_trait_def_id, implements_trait, in_macro, in_macro_or_desugar, match_type, paths, snippet_opt, - span_lint_and_then, SpanlessEq, + get_trait_def_id, implements_trait, in_macro, match_type, paths, snippet_opt, span_lint_and_then, SpanlessEq, }; use if_chain::if_chain; use rustc::hir::intravisit::*; @@ -106,7 +105,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { } // prevent folding of `cfg!` macros and the like - if !in_macro_or_desugar(e.span) { + if !e.span.from_expansion() { match &e.node { ExprKind::Unary(UnNot, inner) => return Ok(Bool::Not(box self.run(inner)?)), ExprKind::Binary(binop, lhs, rhs) => match &binop.node { diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index 54947a6a6713..88b8d8688b66 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -9,7 +9,7 @@ use rustc::{declare_tool_lint, impl_lint_pass}; use syntax::ast::Attribute; use syntax::source_map::Span; -use crate::utils::{in_macro_or_desugar, is_allowed, match_type, paths, span_help_and_lint, LimitStack}; +use crate::utils::{is_allowed, match_type, paths, span_help_and_lint, LimitStack}; declare_clippy_lint! { /// **What it does:** Checks for methods with high cognitive complexity. @@ -42,7 +42,7 @@ impl_lint_pass!(CognitiveComplexity => [COGNITIVE_COMPLEXITY]); impl CognitiveComplexity { fn check<'a, 'tcx>(&mut self, cx: &'a LateContext<'a, 'tcx>, body: &'tcx Body, span: Span) { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; } diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 12c83873641c..6c33f362633c 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -18,9 +18,7 @@ use rustc::{declare_lint_pass, declare_tool_lint}; use syntax::ast; use crate::utils::sugg::Sugg; -use crate::utils::{ - in_macro_or_desugar, snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then, -}; +use crate::utils::{snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then}; use rustc_errors::Applicability; declare_clippy_lint! { @@ -77,7 +75,7 @@ declare_lint_pass!(CollapsibleIf => [COLLAPSIBLE_IF]); impl EarlyLintPass for CollapsibleIf { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { - if !in_macro_or_desugar(expr.span) { + if !expr.span.from_expansion() { check_if(cx, expr) } } @@ -108,7 +106,7 @@ fn check_collapsible_maybe_if_let(cx: &EarlyContext<'_>, else_: &ast::Expr) { if let ast::ExprKind::Block(ref block, _) = else_.node; if !block_starts_with_comment(cx, block); if let Some(else_) = expr_block(block); - if !in_macro_or_desugar(else_.span); + if !else_.span.from_expansion(); if let ast::ExprKind::If(..) = else_.node; then { let mut applicability = Applicability::MachineApplicable; diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 01989625b45a..df354073df80 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -1,6 +1,4 @@ -use crate::utils::{ - get_parent_expr, higher, in_macro_or_desugar, same_tys, snippet, span_lint_and_then, span_note_and_lint, -}; +use crate::utils::{get_parent_expr, higher, same_tys, snippet, span_lint_and_then, span_note_and_lint}; use crate::utils::{SpanlessEq, SpanlessHash}; use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -109,7 +107,7 @@ declare_lint_pass!(CopyAndPaste => [IFS_SAME_COND, IF_SAME_THEN_ELSE, MATCH_SAME impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if !in_macro_or_desugar(expr.span) { + if !expr.span.from_expansion() { // skip ifs directly in else, it will be checked in the parent if if let Some(expr) = get_parent_expr(cx, expr) { if let Some((_, _, Some(ref else_expr))) = higher::if_block(&expr) { diff --git a/clippy_lints/src/double_parens.rs b/clippy_lints/src/double_parens.rs index e55490325eca..5e1a860ae80f 100644 --- a/clippy_lints/src/double_parens.rs +++ b/clippy_lints/src/double_parens.rs @@ -1,4 +1,4 @@ -use crate::utils::{in_macro_or_desugar, span_lint}; +use crate::utils::span_lint; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; use syntax::ast::*; @@ -27,7 +27,7 @@ declare_lint_pass!(DoubleParens => [DOUBLE_PARENS]); impl EarlyLintPass for DoubleParens { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index cf61683cb719..277844983658 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -1,6 +1,6 @@ //! lint on enum variants that are prefixed or suffixed by the same characters -use crate::utils::{camel_case, in_macro_or_desugar, is_present_in_source}; +use crate::utils::{camel_case, is_present_in_source}; use crate::utils::{span_help_and_lint, span_lint}; use rustc::lint::{EarlyContext, EarlyLintPass, Lint, LintArray, LintPass}; use rustc::{declare_tool_lint, impl_lint_pass}; @@ -248,7 +248,7 @@ impl EarlyLintPass for EnumVariantNames { let item_name = item.ident.as_str(); let item_name_chars = item_name.chars().count(); let item_camel = to_camel_case(&item_name); - if !in_macro_or_desugar(item.span) && is_present_in_source(cx, item.span) { + if !item.span.from_expansion() && is_present_in_source(cx, item.span) { if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() { // constants don't have surrounding modules if !mod_camel.is_empty() { diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index 08c0b36855e2..9c8380ab7de7 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -1,6 +1,4 @@ -use crate::utils::{ - implements_trait, in_macro_or_desugar, is_copy, multispan_sugg, snippet, span_lint, span_lint_and_then, SpanlessEq, -}; +use crate::utils::{implements_trait, is_copy, multispan_sugg, snippet, span_lint, span_lint_and_then, SpanlessEq}; use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; @@ -52,7 +50,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { #[allow(clippy::similar_names, clippy::too_many_lines)] fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { if let ExprKind::Binary(op, ref left, ref right) = e.node { - if in_macro_or_desugar(e.span) { + if e.span.from_expansion() { return; } if is_valid_operator(op) && SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) { diff --git a/clippy_lints/src/erasing_op.rs b/clippy_lints/src/erasing_op.rs index 3ac2f90ce01b..190f4e7b56e8 100644 --- a/clippy_lints/src/erasing_op.rs +++ b/clippy_lints/src/erasing_op.rs @@ -4,7 +4,7 @@ use rustc::{declare_lint_pass, declare_tool_lint}; use syntax::source_map::Span; use crate::consts::{constant_simple, Constant}; -use crate::utils::{in_macro_or_desugar, span_lint}; +use crate::utils::span_lint; declare_clippy_lint! { /// **What it does:** Checks for erasing operations, e.g., `x * 0`. @@ -31,7 +31,7 @@ declare_lint_pass!(ErasingOp => [ERASING_OP]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - if in_macro_or_desugar(e.span) { + if e.span.from_expansion() { return; } if let ExprKind::Binary(ref cmp, ref left, ref right) = e.node { diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 751d8fd00830..6e8d4585161e 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -1,7 +1,6 @@ use crate::utils::paths; use crate::utils::{ - in_macro_or_desugar, is_expn_of, last_path_segment, match_def_path, match_type, resolve_node, snippet, - span_lint_and_then, walk_ptrs_ty, + is_expn_of, last_path_segment, match_def_path, match_type, resolve_node, snippet, span_lint_and_then, walk_ptrs_ty, }; use if_chain::if_chain; use rustc::hir::*; @@ -40,7 +39,7 @@ declare_lint_pass!(UselessFormat => [USELESS_FORMAT]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessFormat { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { if let Some(span) = is_expn_of(expr.span, "format") { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; } match expr.node { diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index f20c95d7684c..463530211157 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -1,4 +1,4 @@ -use crate::utils::{differing_macro_contexts, in_macro_or_desugar, snippet_opt, span_note_and_lint}; +use crate::utils::{differing_macro_contexts, snippet_opt, span_note_and_lint}; use if_chain::if_chain; use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; @@ -107,7 +107,7 @@ impl EarlyLintPass for Formatting { /// Implementation of the `SUSPICIOUS_ASSIGNMENT_FORMATTING` lint. fn check_assign(cx: &EarlyContext<'_>, expr: &Expr) { if let ExprKind::Assign(ref lhs, ref rhs) = expr.node { - if !differing_macro_contexts(lhs.span, rhs.span) && !in_macro_or_desugar(lhs.span) { + if !differing_macro_contexts(lhs.span, rhs.span) && !lhs.span.from_expansion() { let eq_span = lhs.span.between(rhs.span); if let ExprKind::Unary(op, ref sub_rhs) = rhs.node { if let Some(eq_snippet) = snippet_opt(cx, eq_span) { @@ -139,7 +139,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) { if let ExprKind::If(_, then, Some(else_)) = &expr.node; if is_block(else_) || is_if(else_); if !differing_macro_contexts(then.span, else_.span); - if !in_macro_or_desugar(then.span) && !in_external_macro(cx.sess, expr.span); + if !then.span.from_expansion() && !in_external_macro(cx.sess, expr.span); // workaround for rust-lang/rust#43081 if expr.span.lo().0 != 0 && expr.span.hi().0 != 0; @@ -205,7 +205,7 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) { fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) { if !differing_macro_contexts(first.span, second.span) - && !in_macro_or_desugar(first.span) + && !first.span.from_expansion() && is_if(first) && (is_block(second) || is_if(second)) { diff --git a/clippy_lints/src/identity_conversion.rs b/clippy_lints/src/identity_conversion.rs index baf7791b7921..2441dd914aff 100644 --- a/clippy_lints/src/identity_conversion.rs +++ b/clippy_lints/src/identity_conversion.rs @@ -1,6 +1,5 @@ use crate::utils::{ - in_macro_or_desugar, match_def_path, match_trait_method, same_tys, snippet, snippet_with_macro_callsite, - span_lint_and_then, + match_def_path, match_trait_method, same_tys, snippet, snippet_with_macro_callsite, span_lint_and_then, }; use crate::utils::{paths, resolve_node}; use rustc::hir::*; @@ -34,7 +33,7 @@ impl_lint_pass!(IdentityConversion => [IDENTITY_CONVERSION]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - if in_macro_or_desugar(e.span) { + if e.span.from_expansion() { return; } diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index 1cd58a370945..55f8701ab18b 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -5,7 +5,7 @@ use rustc::{declare_lint_pass, declare_tool_lint}; use syntax::source_map::Span; use crate::consts::{constant_simple, Constant}; -use crate::utils::{clip, in_macro_or_desugar, snippet, span_lint, unsext}; +use crate::utils::{clip, snippet, span_lint, unsext}; declare_clippy_lint! { /// **What it does:** Checks for identity operations, e.g., `x + 0`. @@ -29,7 +29,7 @@ declare_lint_pass!(IdentityOp => [IDENTITY_OP]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - if in_macro_or_desugar(e.span) { + if e.span.from_expansion() { return; } if let ExprKind::Binary(ref cmp, ref left, ref right) = e.node { diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index ceda6578182f..b1b05bdc17fd 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -1,5 +1,5 @@ use crate::utils::{ - in_macro_or_desugar, match_def_path, + match_def_path, paths::{BEGIN_PANIC, BEGIN_PANIC_FMT}, resolve_node, snippet_opt, span_lint_and_then, }; @@ -138,7 +138,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitReturn { // 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() && !in_macro_or_desugar(span) { + if !mir.return_ty().is_unit() && !span.from_expansion() { expr_match(cx, &body.value); } } diff --git a/clippy_lints/src/inherent_to_string.rs b/clippy_lints/src/inherent_to_string.rs index ef0a75438379..eb29a6d436ab 100644 --- a/clippy_lints/src/inherent_to_string.rs +++ b/clippy_lints/src/inherent_to_string.rs @@ -4,8 +4,8 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; use crate::utils::{ - get_trait_def_id, implements_trait, in_macro_or_desugar, match_type, paths, return_ty, span_help_and_lint, - trait_ref_of_method, walk_ptrs_ty, + get_trait_def_id, implements_trait, match_type, paths, return_ty, span_help_and_lint, trait_ref_of_method, + walk_ptrs_ty, }; declare_clippy_lint! { @@ -94,7 +94,7 @@ declare_lint_pass!(InherentToString => [INHERENT_TO_STRING, INHERENT_TO_STRING_S impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InherentToString { fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplItem) { - if in_macro_or_desugar(impl_item.span) { + if impl_item.span.from_expansion() { return; } diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index 226809a2e28b..5a1713467601 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -1,6 +1,6 @@ //! lint when items are used after statements -use crate::utils::{in_macro_or_desugar, span_lint}; +use crate::utils::span_lint; use matches::matches; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; @@ -38,7 +38,7 @@ declare_lint_pass!(ItemsAfterStatements => [ITEMS_AFTER_STATEMENTS]); impl EarlyLintPass for ItemsAfterStatements { fn check_block(&mut self, cx: &EarlyContext<'_>, item: &Block) { - if in_macro_or_desugar(item.span) { + if item.span.from_expansion() { return; } @@ -52,7 +52,7 @@ impl EarlyLintPass for ItemsAfterStatements { // lint on all further items for stmt in stmts { if let StmtKind::Item(ref it) = *stmt { - if in_macro_or_desugar(it.span) { + if it.span.from_expansion() { return; } if let ItemKind::MacroDef(..) = it.node { diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index ea302ed9fc9a..a1c61edbba58 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,6 +1,4 @@ -use crate::utils::{ - get_item_name, in_macro_or_desugar, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty, -}; +use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty}; use rustc::hir::def_id::DefId; use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -75,7 +73,7 @@ declare_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { - if in_macro_or_desugar(item.span) { + if item.span.from_expansion() { return; } @@ -87,7 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero { } fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 62c9e904f7a1..b1da7483a600 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -11,7 +11,7 @@ use rustc::{declare_lint_pass, declare_tool_lint}; // use rustc::middle::region::CodeExtent; use crate::consts::{constant, Constant}; use crate::utils::usage::mutated_variables; -use crate::utils::{in_macro_or_desugar, sext, sugg}; +use crate::utils::{sext, sugg}; use rustc::middle::expr_use_visitor::*; use rustc::middle::mem_categorization::cmt_; use rustc::middle::mem_categorization::Categorization; @@ -470,7 +470,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops { #[allow(clippy::too_many_lines)] fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { // we don't want to check expanded macros - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } @@ -1034,7 +1034,7 @@ fn check_for_loop_range<'a, 'tcx>( body: &'tcx Expr, expr: &'tcx Expr, ) { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index df10336d6d97..09c1f4b3c979 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -1,7 +1,6 @@ use crate::utils::paths; use crate::utils::{ - in_macro_or_desugar, is_copy, match_trait_method, match_type, remove_blocks, snippet_with_applicability, - span_lint_and_sugg, + is_copy, match_trait_method, match_type, remove_blocks, snippet_with_applicability, span_lint_and_sugg, }; use if_chain::if_chain; use rustc::hir; @@ -44,7 +43,7 @@ declare_lint_pass!(MapClone => [MAP_CLONE]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone { fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) { - if in_macro_or_desugar(e.span) { + if e.span.from_expansion() { return; } diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index 22093bfbee84..7d46478a6fd3 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -1,5 +1,5 @@ use crate::utils::paths; -use crate::utils::{in_macro_or_desugar, iter_input_pats, match_type, method_chain_args, snippet, span_lint_and_then}; +use crate::utils::{iter_input_pats, match_type, method_chain_args, snippet, span_lint_and_then}; use if_chain::if_chain; use rustc::hir; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -257,7 +257,7 @@ fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt, expr: &hir::Expr impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapUnit { fn check_stmt(&mut self, cx: &LateContext<'_, '_>, stmt: &hir::Stmt) { - if in_macro_or_desugar(stmt.span) { + if stmt.span.from_expansion() { return; } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 52265ae55bf1..6b6fd2bb2087 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -2,8 +2,8 @@ use crate::consts::{constant, Constant}; use crate::utils::paths; use crate::utils::sugg::Sugg; use crate::utils::{ - expr_block, in_macro_or_desugar, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg, remove_blocks, - snippet, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, + expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg, remove_blocks, snippet, + snippet_with_applicability, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, }; use if_chain::if_chain; use rustc::hir::def::CtorKind; @@ -597,7 +597,7 @@ fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: })); span_lint_and_then(cx, MATCH_REF_PATS, expr.span, title, |db| { - if !in_macro_or_desugar(expr.span) { + if !expr.span.from_expansion() { multispan_sugg(db, msg.to_owned(), suggs); } }); diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 8c0fb2a6c2f2..21cfeadba2be 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -21,11 +21,11 @@ use syntax::symbol::LocalInternedString; use crate::utils::sugg; use crate::utils::usage::mutated_variables; use crate::utils::{ - get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, in_macro_or_desugar, - is_copy, is_ctor_function, is_expn_of, iter_input_pats, last_path_segment, match_def_path, match_qpath, - match_trait_method, match_type, match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, - single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, - span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq, + get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, is_copy, + is_ctor_function, is_expn_of, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method, + match_type, match_var, method_calls, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, + snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_sugg, + span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq, }; use crate::utils::{paths, span_help_and_lint}; @@ -2150,7 +2150,7 @@ fn lint_option_and_then_some(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: & return; } - let some_inner_snip = if in_macro_or_desugar(inner_expr.span) { + let some_inner_snip = if inner_expr.span.from_expansion() { snippet_with_macro_callsite(cx, inner_expr.span, "_") } else { snippet(cx, inner_expr.span, "_") diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index a127431e2d53..8cae91f434cd 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -12,8 +12,8 @@ use syntax::source_map::{ExpnKind, Span}; use crate::consts::{constant, Constant}; use crate::utils::sugg::Sugg; use crate::utils::{ - get_item_name, get_parent_expr, implements_trait, in_constant, in_macro_or_desugar, is_integer_literal, - iter_input_pats, last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint, span_lint_and_then, + get_item_name, get_parent_expr, implements_trait, in_constant, is_integer_literal, iter_input_pats, + last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint, span_lint_and_then, span_lint_hir_and_then, walk_ptrs_ty, SpanlessEq, }; @@ -48,8 +48,8 @@ declare_clippy_lint! { declare_clippy_lint! { /// **What it does:** Checks for comparisons to NaN. /// - /// **Why is this bad?** NaN does not compare meaningfully to anything – not - /// even itself – so those comparisons are simply wrong. + /// **Why is this bad?** NaN does not compare meaningfully to anything not + /// even itself so those comparisons are simply wrong. /// /// **Known problems:** None. /// @@ -641,7 +641,7 @@ fn in_attributes_expansion(expr: &Expr) -> bool { /// Tests whether `res` is a variable defined outside a macro. fn non_macro_local(cx: &LateContext<'_, '_>, res: def::Res) -> bool { if let def::Res::Local(id) = res { - !in_macro_or_desugar(cx.tcx.hir().span(id)) + !cx.tcx.hir().span(id).from_expansion() } else { false } diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 15cbdf7180d7..6c575fd94a87 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -5,7 +5,7 @@ // [`missing_doc`]: https://github.com/rust-lang/rust/blob/d6d05904697d89099b55da3331155392f1db9c00/src/librustc_lint/builtin.rs#L246 // -use crate::utils::{in_macro_or_desugar, span_lint}; +use crate::utils::span_lint; use if_chain::if_chain; use rustc::hir; use rustc::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass}; @@ -85,7 +85,7 @@ impl MissingDoc { return; } - if in_macro_or_desugar(sp) { + if sp.from_expansion() { return; } diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 285ec0d081f3..7d28b32c3299 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -3,7 +3,7 @@ //! This lint is **warn** by default use crate::utils::sugg::Sugg; -use crate::utils::{higher, in_macro_or_desugar, span_lint, span_lint_and_sugg}; +use crate::utils::{higher, span_lint, span_lint_and_sugg}; use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; @@ -129,7 +129,7 @@ declare_lint_pass!(BoolComparison => [BOOL_COMPARISON]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - if in_macro_or_desugar(e.span) { + if e.span.from_expansion() { return; } diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index b15f836bb1ee..3a0b6d0fbdf0 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -2,7 +2,7 @@ //! //! This lint is **warn** by default -use crate::utils::{in_macro_or_desugar, snippet_opt, span_lint_and_then}; +use crate::utils::{snippet_opt, span_lint_and_then}; use if_chain::if_chain; use rustc::hir::{BindingAnnotation, Expr, ExprKind, HirId, Item, MutImmutable, Pat, PatKind}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -38,7 +38,7 @@ impl_lint_pass!(NeedlessBorrow => [NEEDLESS_BORROW]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - if in_macro_or_desugar(e.span) || self.derived_item.is_some() { + if e.span.from_expansion() || self.derived_item.is_some() { return; } if let ExprKind::AddrOf(MutImmutable, ref inner) = e.node { @@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } } fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) { - if in_macro_or_desugar(pat.span) || self.derived_item.is_some() { + if pat.span.from_expansion() || self.derived_item.is_some() { return; } if_chain! { diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index b6598ac55b38..714c746f68d6 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -2,7 +2,7 @@ //! //! This lint is **warn** by default -use crate::utils::{in_macro_or_desugar, snippet, span_lint_and_then}; +use crate::utils::{snippet, span_lint_and_then}; use if_chain::if_chain; use rustc::hir::{BindingAnnotation, MutImmutable, Pat, PatKind}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -54,7 +54,7 @@ declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrowedRef { fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) { - if in_macro_or_desugar(pat.span) { + if pat.span.from_expansion() { // OK, simple enough, lints doesn't check in macro. return; } diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index a5c0652b265b..79da82ae3e20 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -39,7 +39,7 @@ use std::borrow::Cow; use syntax::ast; use syntax::source_map::{original_sp, DUMMY_SP}; -use crate::utils::{in_macro_or_desugar, snippet, snippet_block, span_help_and_lint, trim_multiline}; +use crate::utils::{snippet, snippet_block, span_help_and_lint, trim_multiline}; declare_clippy_lint! { /// **What it does:** The lint checks for `if`-statements appearing in loops @@ -120,7 +120,7 @@ declare_lint_pass!(NeedlessContinue => [NEEDLESS_CONTINUE]); impl EarlyLintPass for NeedlessContinue { fn check_expr(&mut self, ctx: &EarlyContext<'_>, expr: &ast::Expr) { - if !in_macro_or_desugar(expr.span) { + if !expr.span.from_expansion() { check_and_warn(ctx, expr); } } diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index eaca9c42afb9..f09fb22f82ad 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -1,7 +1,7 @@ use crate::utils::ptr::get_spans; use crate::utils::{ - get_trait_def_id, implements_trait, in_macro_or_desugar, is_copy, is_self, match_type, multispan_sugg, paths, - snippet, snippet_opt, span_lint_and_then, + get_trait_def_id, implements_trait, is_copy, is_self, match_type, multispan_sugg, paths, snippet, snippet_opt, + span_lint_and_then, }; use if_chain::if_chain; use matches::matches; @@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { span: Span, hir_id: HirId, ) { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; } diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 2fe866a1d95b..078aa6923f2d 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -1,4 +1,4 @@ -use crate::utils::{has_drop, in_macro_or_desugar, snippet_opt, span_lint, span_lint_and_sugg}; +use crate::utils::{has_drop, snippet_opt, span_lint, span_lint_and_sugg}; use rustc::hir::def::{DefKind, Res}; use rustc::hir::{BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -43,7 +43,7 @@ declare_clippy_lint! { } fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return false; } match expr.node { @@ -103,7 +103,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoEffect { } else if let Some(reduced) = reduce_expression(cx, expr) { let mut snippet = String::new(); for e in reduced { - if in_macro_or_desugar(e.span) { + if e.span.from_expansion() { return; } if let Some(snip) = snippet_opt(cx, e.span) { @@ -128,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoEffect { } fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option> { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return None; } match expr.node { diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 644660100b8b..56922c73110b 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -14,7 +14,7 @@ use rustc_errors::Applicability; use rustc_typeck::hir_ty_to_ty; use syntax_pos::{InnerSpan, Span, DUMMY_SP}; -use crate::utils::{in_constant, in_macro_or_desugar, is_copy, span_lint_and_then}; +use crate::utils::{in_constant, is_copy, span_lint_and_then}; declare_clippy_lint! { /// **What it does:** Checks for declaration of `const` items which is interior @@ -119,7 +119,7 @@ fn verify_ty_bound<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, source: S let (lint, msg, span) = source.lint(); span_lint_and_then(cx, lint, span, msg, |db| { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; // Don't give suggestions into macros. } match source { diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index c52b59653706..8e57b8ed7785 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -1,4 +1,4 @@ -use crate::utils::{in_macro_or_desugar, snippet_with_applicability, span_lint_and_sugg}; +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; use rustc_errors::Applicability; @@ -32,7 +32,7 @@ declare_lint_pass!(Precedence => [PRECEDENCE]); impl EarlyLintPass for Precedence { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index 76f3f8fd88fe..68bf1febc6d6 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -1,6 +1,6 @@ use crate::utils::{ - has_drop, in_macro_or_desugar, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir, - span_lint_hir_and_then, walk_ptrs_ty_depth, + has_drop, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir, span_lint_hir_and_then, + walk_ptrs_ty_depth, }; use if_chain::if_chain; use matches::matches; @@ -91,7 +91,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone { for (bb, bbdata) in mir.basic_blocks().iter_enumerated() { let terminator = bbdata.terminator(); - if in_macro_or_desugar(terminator.source_info.span) { + if terminator.source_info.span.from_expansion() { continue; } diff --git a/clippy_lints/src/redundant_static_lifetimes.rs b/clippy_lints/src/redundant_static_lifetimes.rs index 4d9fbbca83ed..6a1ef19dd6cd 100644 --- a/clippy_lints/src/redundant_static_lifetimes.rs +++ b/clippy_lints/src/redundant_static_lifetimes.rs @@ -1,4 +1,4 @@ -use crate::utils::{in_macro_or_desugar, snippet, span_lint_and_then}; +use crate::utils::{snippet, span_lint_and_then}; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; use rustc_errors::Applicability; @@ -78,7 +78,7 @@ impl RedundantStaticLifetimes { impl EarlyLintPass for RedundantStaticLifetimes { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { - if !in_macro_or_desugar(item.span) { + if !item.span.from_expansion() { if let ItemKind::Const(ref var_type, _) = item.node { self.visit_type(var_type, cx, "Constants have by default a `'static` lifetime"); // Don't check associated consts because `'static` cannot be elided on those (issue diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 8a8133bfa1ea..3cc053a0ebf6 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -7,7 +7,7 @@ use syntax::source_map::Span; use syntax::visit::FnKind; use syntax_pos::BytePos; -use crate::utils::{in_macro_or_desugar, match_path_ast, snippet_opt, span_lint_and_then}; +use crate::utils::{match_path_ast, snippet_opt, span_lint_and_then}; declare_clippy_lint! { /// **What it does:** Checks for return statements at the end of a block. @@ -155,7 +155,7 @@ impl Return { ) { match inner_span { Some(inner_span) => { - if in_external_macro(cx.sess(), inner_span) || in_macro_or_desugar(inner_span) { + if in_external_macro(cx.sess(), inner_span) || inner_span.from_expansion() { return; } @@ -245,7 +245,7 @@ impl EarlyLintPass for Return { if_chain! { if let ast::FunctionRetTy::Ty(ref ty) = decl.output; if let ast::TyKind::Tup(ref vals) = ty.node; - if vals.is_empty() && !in_macro_or_desugar(ty.span) && get_def(span) == get_def(ty.span); + if vals.is_empty() && !ty.span.from_expansion() && get_def(span) == get_def(ty.span); then { let (rspan, appl) = if let Ok(fn_source) = cx.sess().source_map() @@ -277,7 +277,7 @@ impl EarlyLintPass for Return { if_chain! { if let Some(ref stmt) = block.stmts.last(); if let ast::StmtKind::Expr(ref expr) = stmt.node; - if is_unit_expr(expr) && !in_macro_or_desugar(expr.span); + if is_unit_expr(expr) && !expr.span.from_expansion(); then { let sp = expr.span; span_lint_and_then(cx, UNUSED_UNIT, sp, "unneeded unit expression", |db| { @@ -295,7 +295,7 @@ impl EarlyLintPass for Return { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { match e.node { ast::ExprKind::Ret(Some(ref expr)) | ast::ExprKind::Break(_, Some(ref expr)) => { - if is_unit_expr(expr) && !in_macro_or_desugar(expr.span) { + if is_unit_expr(expr) && !expr.span.from_expansion() { span_lint_and_then(cx, UNUSED_UNIT, expr.span, "unneeded `()`", |db| { db.span_suggestion( expr.span, diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 0de63b5ff3e5..4135fc87fcd1 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -145,7 +145,7 @@ declare_lint_pass!(StringLitAsBytes => [STRING_LIT_AS_BYTES]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - use crate::utils::{in_macro_or_desugar, snippet, snippet_with_applicability}; + use crate::utils::{snippet, snippet_with_applicability}; use syntax::ast::{LitKind, StrStyle}; if let ExprKind::MethodCall(ref path, _, ref args) = e.node { @@ -177,7 +177,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { } else if callsite == expanded && lit_content.as_str().chars().all(|c| c.is_ascii()) && lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT - && !in_macro_or_desugar(args[0].span) + && !args[0].span.from_expansion() { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index be79fc2fb81f..eb6e46c3014e 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -1,6 +1,6 @@ use std::cmp; -use crate::utils::{in_macro_or_desugar, is_copy, is_self_ty, snippet, span_lint_and_sugg}; +use crate::utils::{is_copy, is_self_ty, snippet, span_lint_and_sugg}; use if_chain::if_chain; use matches::matches; use rustc::hir; @@ -127,7 +127,7 @@ impl_lint_pass!(TriviallyCopyPassByRef => [TRIVIALLY_COPY_PASS_BY_REF]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef { fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) { - if in_macro_or_desugar(item.span) { + if item.span.from_expansion() { return; } @@ -145,7 +145,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef { span: Span, hir_id: HirId, ) { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; } diff --git a/clippy_lints/src/try_err.rs b/clippy_lints/src/try_err.rs index 7eba331ae0f3..4d9934cee30a 100644 --- a/clippy_lints/src/try_err.rs +++ b/clippy_lints/src/try_err.rs @@ -1,4 +1,4 @@ -use crate::utils::{in_macro_or_desugar, match_qpath, paths, snippet, snippet_with_macro_callsite, span_lint_and_sugg}; +use crate::utils::{match_qpath, paths, snippet, snippet_with_macro_callsite, span_lint_and_sugg}; use if_chain::if_chain; use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -67,7 +67,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TryErr { then { let err_type = cx.tables.expr_ty(err_arg); - let origin_snippet = if in_macro_or_desugar(err_arg.span) { + let origin_snippet = if err_arg.span.from_expansion() { snippet_with_macro_callsite(cx, err_arg.span, "_") } else { snippet(cx, err_arg.span, "_") diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 6c184246c10a..24eba166c7b1 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -23,8 +23,8 @@ use syntax::symbol::sym; use crate::consts::{constant, Constant}; use crate::utils::paths; use crate::utils::{ - clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro_or_desugar, int_bits, last_path_segment, - match_def_path, match_path, multispan_sugg, same_tys, sext, snippet, snippet_opt, snippet_with_applicability, + clip, comparisons, differing_macro_contexts, higher, in_constant, int_bits, last_path_segment, match_def_path, + match_path, multispan_sugg, same_tys, sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext, }; @@ -234,7 +234,7 @@ fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath, path: &[&str]) /// local bindings should only be checked for the `BORROWED_BOX` lint. #[allow(clippy::too_many_lines)] fn check_ty(cx: &LateContext<'_, '_>, hir_ty: &hir::Ty, is_local: bool) { - if in_macro_or_desugar(hir_ty.span) { + if hir_ty.span.from_expansion() { return; } match hir_ty.node { @@ -462,7 +462,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnitValue { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { if let StmtKind::Local(ref local) = stmt.node { if is_unit(cx.tables.pat_ty(&local.pat)) { - if in_external_macro(cx.sess(), stmt.span) || in_macro_or_desugar(local.pat.span) { + if in_external_macro(cx.sess(), stmt.span) || local.pat.span.from_expansion() { return; } if higher::is_from_for_desugar(local) { @@ -526,7 +526,7 @@ declare_lint_pass!(UnitCmp => [UNIT_CMP]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } if let ExprKind::Binary(ref cmp, ref left, _) = expr.node { @@ -575,7 +575,7 @@ declare_lint_pass!(UnitArg => [UNIT_ARG]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } @@ -1115,7 +1115,7 @@ fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Casts { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { return; } if let ExprKind::Cast(ref ex, _) = expr.node { @@ -1381,7 +1381,7 @@ impl<'a, 'tcx> TypeComplexity { } fn check_type(&self, cx: &LateContext<'_, '_>, ty: &hir::Ty) { - if in_macro_or_desugar(ty.span) { + if ty.span.from_expansion() { return; } let score = { @@ -1485,7 +1485,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 { if let ExprKind::Cast(ref e, _) = expr.node { if let ExprKind::Lit(ref l) = e.node { if let LitKind::Char(_) = l.node { - if ty::Uint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !in_macro_or_desugar(expr.span) { + if ty::Uint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !expr.span.from_expansion() { let msg = "casting character literal to u8. `char`s \ are 4 bytes wide in rust, so casting to u8 \ truncates them"; @@ -1646,7 +1646,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons { if let ExprKind::Binary(ref cmp, ref lhs, ref rhs) = expr.node { if let Some((culprit, result)) = detect_absurd_comparison(cx, cmp.node, lhs, rhs) { - if !in_macro_or_desugar(expr.span) { + if !expr.span.from_expansion() { let msg = "this comparison involving the minimum or maximum element for this \ type contains a case that is always true or always false"; diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs index 9c02c1c31042..197b9a8146ed 100644 --- a/clippy_lints/src/unused_label.rs +++ b/clippy_lints/src/unused_label.rs @@ -1,4 +1,4 @@ -use crate::utils::{in_macro_or_desugar, span_lint}; +use crate::utils::span_lint; use rustc::hir; use rustc::hir::intravisit::{walk_expr, walk_fn, FnKind, NestedVisitorMap, Visitor}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; @@ -44,7 +44,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedLabel { span: Span, fn_id: hir::HirId, ) { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; } diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index d39c341d06e5..061d4aa7460c 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -2,9 +2,7 @@ use if_chain::if_chain; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_lint_pass, declare_tool_lint}; -use crate::utils::{ - higher::if_block, in_macro_or_desugar, match_type, paths, span_lint_and_then, usage::is_potentially_mutated, -}; +use crate::utils::{higher::if_block, match_type, paths, span_lint_and_then, usage::is_potentially_mutated}; use rustc::hir::intravisit::*; use rustc::hir::*; use syntax::source_map::Span; @@ -197,7 +195,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Unwrap { span: Span, fn_id: HirId, ) { - if in_macro_or_desugar(span) { + if span.from_expansion() { return; } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 020068d4633a..2d772d77ed10 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -92,11 +92,6 @@ pub fn in_constant(cx: &LateContext<'_, '_>, id: HirId) -> bool { } } -/// Returns `true` if this `span` was expanded by any macro or desugaring -pub fn in_macro_or_desugar(span: Span) -> bool { - span.from_expansion() -} - /// Returns `true` if this `span` was expanded by any macro. pub fn in_macro(span: Span) -> bool { if span.from_expansion() { @@ -349,7 +344,7 @@ pub fn method_calls(expr: &Expr, max_depth: usize) -> (Vec, Vec<&[Expr]> let mut current = expr; for _ in 0..max_depth { if let ExprKind::MethodCall(path, _, args) = ¤t.node { - if args.iter().any(|e| in_macro_or_desugar(e.span)) { + if args.iter().any(|e| e.span.from_expansion()) { break; } method_names.push(path.ident.name); @@ -376,7 +371,7 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option first if let ExprKind::MethodCall(ref path, _, ref args) = current.node { if path.ident.name.as_str() == *method_name { - if args.iter().any(|e| in_macro_or_desugar(e.span)) { + if args.iter().any(|e| e.span.from_expansion()) { return None; } matched.push(&**args); // build up `matched` backwards @@ -471,7 +466,7 @@ pub fn snippet_with_applicability<'a, T: LintContext>( default: &'a str, applicability: &mut Applicability, ) -> Cow<'a, str> { - if *applicability != Applicability::Unspecified && in_macro_or_desugar(span) { + if *applicability != Applicability::Unspecified && span.from_expansion() { *applicability = Applicability::MaybeIncorrect; } snippet_opt(cx, span).map_or_else( @@ -536,7 +531,7 @@ pub fn last_line_of_span(cx: &T, span: Span) -> Span { pub fn expr_block<'a, T: LintContext>(cx: &T, expr: &Expr, option: Option, default: &'a str) -> Cow<'a, str> { let code = snippet_block(cx, expr.span, default); let string = option.unwrap_or_default(); - if in_macro_or_desugar(expr.span) { + if expr.span.from_expansion() { Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default))) } else if let ExprKind::Block(_, _) = expr.node { Cow::Owned(format!("{}{}", code, string)) diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 0e45750e94df..b1b5791b15d8 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -1,7 +1,7 @@ //! Contains utility functions to generate suggestions. #![deny(clippy::missing_docs_in_private_items)] -use crate::utils::{higher, in_macro_or_desugar, snippet, snippet_opt, snippet_with_macro_callsite}; +use crate::utils::{higher, snippet, snippet_opt, snippet_with_macro_callsite}; use matches::matches; use rustc::hir; use rustc::lint::{EarlyContext, LateContext, LintContext}; @@ -69,7 +69,7 @@ impl<'a> Sugg<'a> { default: &'a str, applicability: &mut Applicability, ) -> Self { - if *applicability != Applicability::Unspecified && in_macro_or_desugar(expr.span) { + if *applicability != Applicability::Unspecified && expr.span.from_expansion() { *applicability = Applicability::MaybeIncorrect; } Self::hir_opt(cx, expr).unwrap_or_else(|| { diff --git a/doc/adding_lints.md b/doc/adding_lints.md index d87580191fb9..452852f1060b 100644 --- a/doc/adding_lints.md +++ b/doc/adding_lints.md @@ -392,7 +392,7 @@ Here are some pointers to things you are likely going to need for every lint: is already in here (`implements_trait`, `match_path`, `snippet`, etc) * [Clippy diagnostics][diagnostics] * [The `if_chain` macro][if_chain] -* [`in_macro_or_desugar`][in_macro_or_desugar] and [`in_external_macro`][in_external_macro] +* [`from_expansion`][from_expansion] and [`in_external_macro`][in_external_macro] * [`Span`][span] * [`Applicability`][applicability] * [The rustc guide][rustc_guide] explains a lot of internal compiler concepts @@ -432,7 +432,7 @@ don't hesitate to ask on Discord, IRC or in the issue/PR. [if_chain]: https://docs.rs/if_chain/0.1.2/if_chain/ [ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/sty/index.html [ast]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/index.html -[in_macro_or_desugar]: https://github.com/rust-lang/rust-clippy/blob/d0717d1f9531a03d154aaeb0cad94c243915a146/clippy_lints/src/utils/mod.rs#L94 +[from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax_pos/struct.Span.html#method.from_expansion [in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/fn.in_external_macro.html [play]: https://play.rust-lang.org [author_example]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f093b986e80ad62f3b67a1f24f5e66e2 From eaf8f0839090fd144a2ca05a91bef5c50ccc590a Mon Sep 17 00:00:00 2001 From: "KRAAI, MATTHEW [VISUS]" Date: Mon, 19 Aug 2019 12:38:33 -0700 Subject: [PATCH 22/30] Restore en dashes --- clippy_lints/src/misc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 8cae91f434cd..362eaea3c1f8 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -48,8 +48,8 @@ declare_clippy_lint! { declare_clippy_lint! { /// **What it does:** Checks for comparisons to NaN. /// - /// **Why is this bad?** NaN does not compare meaningfully to anything not - /// even itself so those comparisons are simply wrong. + /// **Why is this bad?** NaN does not compare meaningfully to anything – not + /// even itself – so those comparisons are simply wrong. /// /// **Known problems:** None. /// From 93c77b7d01a21e717d15ef8d11d0c1a7d55568b9 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Tue, 20 Aug 2019 09:59:13 +0700 Subject: [PATCH 23/30] Update if_chain doc link --- doc/adding_lints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/adding_lints.md b/doc/adding_lints.md index 452852f1060b..c9816911a828 100644 --- a/doc/adding_lints.md +++ b/doc/adding_lints.md @@ -429,7 +429,7 @@ don't hesitate to ask on Discord, IRC or in the issue/PR. [ident]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax/source_map/symbol/struct.Ident.html [span]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax_pos/struct.Span.html [applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html -[if_chain]: https://docs.rs/if_chain/0.1.2/if_chain/ +[if_chain]: https://docs.rs/if_chain/*/if_chain/ [ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/sty/index.html [ast]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/index.html [from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax_pos/struct.Span.html#method.from_expansion From 18592826da472ef52149fd5fd999e4bdf962a8dc Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Tue, 20 Aug 2019 07:27:14 +0200 Subject: [PATCH 24/30] Disable RLS integration test until RLS has been updated to the latest Clippy commit. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fb3d2ef6784e..9c1d004d6943 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,8 +56,8 @@ matrix: if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try) - env: INTEGRATION=rust-lang-nursery/chalk if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try) - - env: INTEGRATION=rust-lang/rls - if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try) + # - env: INTEGRATION=rust-lang/rls + # if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try) - env: INTEGRATION=Geal/nom if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try) - env: INTEGRATION=rust-lang/rustfmt From 2a66196013ca9794127190e0c84fa47eba245418 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Tue, 20 Aug 2019 23:21:39 +0000 Subject: [PATCH 25/30] Remove feature gate for async_await --- tests/ui/issue_4266.rs | 1 - tests/ui/issue_4266.stderr | 4 ++-- tests/ui/methods.rs | 1 - tests/ui/methods.stderr | 42 +++++++++++++++++++------------------- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/tests/ui/issue_4266.rs b/tests/ui/issue_4266.rs index 953879f7bed0..1538abb1d776 100644 --- a/tests/ui/issue_4266.rs +++ b/tests/ui/issue_4266.rs @@ -1,5 +1,4 @@ // compile-flags: --edition 2018 -#![feature(async_await)] #![allow(dead_code)] async fn sink1<'a>(_: &'a str) {} // lint diff --git a/tests/ui/issue_4266.stderr b/tests/ui/issue_4266.stderr index 8b4e70eb9c22..2ebe85bd6b0e 100644 --- a/tests/ui/issue_4266.stderr +++ b/tests/ui/issue_4266.stderr @@ -1,5 +1,5 @@ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/issue_4266.rs:5:1 + --> $DIR/issue_4266.rs:4:1 | LL | async fn sink1<'a>(_: &'a str) {} // lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | async fn sink1<'a>(_: &'a str) {} // lint = note: `-D clippy::needless-lifetimes` implied by `-D warnings` error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/issue_4266.rs:9:1 + --> $DIR/issue_4266.rs:8:1 | LL | / async fn one_to_one<'a>(s: &'a str) -> &'a str { LL | | s diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index 5ae2b32c1bb0..53f9f82485d1 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -1,7 +1,6 @@ // aux-build:option_helpers.rs // compile-flags: --edition 2018 -#![feature(async_await)] #![warn(clippy::all, clippy::pedantic, clippy::option_unwrap_used)] #![allow( clippy::blacklisted_name, diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index 8d09c49f005b..504bb5e8253f 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -1,5 +1,5 @@ error: defining a method called `add` on this type; consider implementing the `std::ops::Add` trait or choosing a less ambiguous name - --> $DIR/methods.rs:37:5 + --> $DIR/methods.rs:36:5 | LL | / pub fn add(self, other: T) -> T { LL | | self @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::should-implement-trait` implied by `-D warnings` error: methods called `new` usually return `Self` - --> $DIR/methods.rs:153:5 + --> $DIR/methods.rs:152:5 | LL | / fn new() -> i32 { LL | | 0 @@ -19,7 +19,7 @@ LL | | } = note: `-D clippy::new-ret-no-self` implied by `-D warnings` error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead - --> $DIR/methods.rs:175:13 + --> $DIR/methods.rs:174:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ @@ -31,7 +31,7 @@ LL | | .unwrap_or(0); = note: replace `map(|x| x + 1).unwrap_or(0)` with `map_or(0, |x| x + 1)` error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead - --> $DIR/methods.rs:179:13 + --> $DIR/methods.rs:178:13 | LL | let _ = opt.map(|x| { | _____________^ @@ -41,7 +41,7 @@ LL | | ).unwrap_or(0); | |____________________________^ error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead - --> $DIR/methods.rs:183:13 + --> $DIR/methods.rs:182:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ @@ -51,7 +51,7 @@ LL | | }); | |__________________^ error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:188:13 + --> $DIR/methods.rs:187:13 | LL | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); = note: replace `map(|x| Some(x + 1)).unwrap_or(None)` with `and_then(|x| Some(x + 1))` error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:190:13 + --> $DIR/methods.rs:189:13 | LL | let _ = opt.map(|x| { | _____________^ @@ -69,7 +69,7 @@ LL | | ).unwrap_or(None); | |_____________________^ error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:194:13 + --> $DIR/methods.rs:193:13 | LL | let _ = opt | _____________^ @@ -80,7 +80,7 @@ LL | | .unwrap_or(None); = note: replace `map(|x| Some(x + 1)).unwrap_or(None)` with `and_then(|x| Some(x + 1))` error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead - --> $DIR/methods.rs:205:13 + --> $DIR/methods.rs:204:13 | LL | let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id); = note: replace `map(|p| format!("{}.", p)).unwrap_or(id)` with `map_or(id, |p| format!("{}.", p))` error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead - --> $DIR/methods.rs:209:13 + --> $DIR/methods.rs:208:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ @@ -100,7 +100,7 @@ LL | | .unwrap_or_else(|| 0); = note: replace `map(|x| x + 1).unwrap_or_else(|| 0)` with `map_or_else(|| 0, |x| x + 1)` error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead - --> $DIR/methods.rs:213:13 + --> $DIR/methods.rs:212:13 | LL | let _ = opt.map(|x| { | _____________^ @@ -110,7 +110,7 @@ LL | | ).unwrap_or_else(|| 0); | |____________________________________^ error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead - --> $DIR/methods.rs:217:13 + --> $DIR/methods.rs:216:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ @@ -120,7 +120,7 @@ LL | | ); | |_________________^ error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead. - --> $DIR/methods.rs:247:13 + --> $DIR/methods.rs:246:13 | LL | let _ = v.iter().filter(|&x| *x < 0).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | let _ = v.iter().filter(|&x| *x < 0).next(); = note: replace `filter(|&x| *x < 0).next()` with `find(|&x| *x < 0)` error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead. - --> $DIR/methods.rs:250:13 + --> $DIR/methods.rs:249:13 | LL | let _ = v.iter().filter(|&x| { | _____________^ @@ -139,7 +139,7 @@ LL | | ).next(); | |___________________________^ error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:266:13 + --> $DIR/methods.rs:265:13 | LL | let _ = v.iter().find(|&x| *x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | let _ = v.iter().find(|&x| *x < 0).is_some(); = note: replace `find(|&x| *x < 0).is_some()` with `any(|x| *x < 0)` error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:269:13 + --> $DIR/methods.rs:268:13 | LL | let _ = v.iter().find(|&x| { | _____________^ @@ -158,7 +158,7 @@ LL | | ).is_some(); | |______________________________^ error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:275:13 + --> $DIR/methods.rs:274:13 | LL | let _ = v.iter().position(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | let _ = v.iter().position(|&x| x < 0).is_some(); = note: replace `position(|&x| x < 0).is_some()` with `any(|&x| x < 0)` error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:278:13 + --> $DIR/methods.rs:277:13 | LL | let _ = v.iter().position(|&x| { | _____________^ @@ -176,7 +176,7 @@ LL | | ).is_some(); | |______________________________^ error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:284:13 + --> $DIR/methods.rs:283:13 | LL | let _ = v.iter().rposition(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -184,7 +184,7 @@ LL | let _ = v.iter().rposition(|&x| x < 0).is_some(); = note: replace `rposition(|&x| x < 0).is_some()` with `any(|&x| x < 0)` error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:287:13 + --> $DIR/methods.rs:286:13 | LL | let _ = v.iter().rposition(|&x| { | _____________^ @@ -194,7 +194,7 @@ LL | | ).is_some(); | |______________________________^ error: used unwrap() on an Option value. If you don't want to handle the None case gracefully, consider using expect() to provide a better panic message - --> $DIR/methods.rs:302:13 + --> $DIR/methods.rs:301:13 | LL | let _ = opt.unwrap(); | ^^^^^^^^^^^^ From a0f9af2132e6dec27be80bd94abc0f2cfe22218e Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Wed, 21 Aug 2019 07:23:48 +0200 Subject: [PATCH 26/30] Add note on how to find the latest beta commit --- doc/changelog_update.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/changelog_update.md b/doc/changelog_update.md index 4eb97b48b9cb..cabf25135dac 100644 --- a/doc/changelog_update.md +++ b/doc/changelog_update.md @@ -26,6 +26,9 @@ release tag from the dropdown and then check the commit of the Clippy directory: ![Explanation of how to find the commit hash](https://user-images.githubusercontent.com/2042399/62846160-1f8b0480-bcce-11e9-9da8-7964ca034e7a.png) +When writing the release notes for the upcoming stable release you want to check +out the commit of the current Rust `beta` tag. + ### 2. Fetching the PRs between those commits You'll want to run `util/fetch_prs_between.sh commit1 commit2 > changes.txt` From 0d85d7e60f393563d717d86fbef05f7309923a08 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Wed, 7 Aug 2019 20:34:23 +0200 Subject: [PATCH 27/30] Fix suggestions for redundant_pattern_matching Fixes the problem displayed in https://github.com/rust-lang/rust-clippy/issues/4344#issuecomment-519206388. We now append `{}` to the suggestion so that the conditional has the correct syntax again. (If we were to _remove_ the `if` instead, it would trigger the `unused_must_use` warning for `#[must_use]` types. --- clippy_lints/src/redundant_pattern_matching.rs | 6 +++--- tests/ui/redundant_pattern_matching.stderr | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/redundant_pattern_matching.rs b/clippy_lints/src/redundant_pattern_matching.rs index ce33ebf87ba6..68862f838cb0 100644 --- a/clippy_lints/src/redundant_pattern_matching.rs +++ b/clippy_lints/src/redundant_pattern_matching.rs @@ -90,8 +90,8 @@ fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, db.span_suggestion( span, "try this", - format!("if {}.{}", snippet(cx, op.span, "_"), good_method), - Applicability::MachineApplicable, // snippet + format!("{}.{}", snippet(cx, op.span, "_"), good_method), + Applicability::MaybeIncorrect, // snippet ); }, ); @@ -154,7 +154,7 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, o span, "try this", format!("{}.{}", snippet(cx, op.span, "_"), good_method), - Applicability::MachineApplicable, // snippet + Applicability::MaybeIncorrect, // snippet ); }, ); diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr index baed95d6f2e7..a904c5ceb9d5 100644 --- a/tests/ui/redundant_pattern_matching.stderr +++ b/tests/ui/redundant_pattern_matching.stderr @@ -2,7 +2,7 @@ error: redundant pattern matching, consider using `is_ok()` --> $DIR/redundant_pattern_matching.rs:5:12 | LL | if let Ok(_) = Ok::(42) {} - | -------^^^^^------------------------ help: try this: `if Ok::(42).is_ok()` + | -------^^^^^------------------------ help: try this: `Ok::(42).is_ok()` | = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` @@ -10,19 +10,19 @@ error: redundant pattern matching, consider using `is_err()` --> $DIR/redundant_pattern_matching.rs:7:12 | LL | if let Err(_) = Err::(42) {} - | -------^^^^^^------------------------- help: try this: `if Err::(42).is_err()` + | -------^^^^^^------------------------- help: try this: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_none()` --> $DIR/redundant_pattern_matching.rs:9:12 | LL | if let None = None::<()> {} - | -------^^^^---------------- help: try this: `if None::<()>.is_none()` + | -------^^^^---------------- help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` --> $DIR/redundant_pattern_matching.rs:11:12 | LL | if let Some(_) = Some(42) {} - | -------^^^^^^^-------------- help: try this: `if Some(42).is_some()` + | -------^^^^^^^-------------- help: try this: `Some(42).is_some()` error: redundant pattern matching, consider using `is_ok()` --> $DIR/redundant_pattern_matching.rs:25:5 From 84716e49f0a93c0ddbab8701a44835a0041e6ffc Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Thu, 8 Aug 2019 21:27:50 +0200 Subject: [PATCH 28/30] Add more testcases for redundant_pattern_matching These should make sure that, when the suggestions are fixed, they are fixed for all these cases. --- tests/ui/redundant_pattern_matching.rs | 26 +++++++++ tests/ui/redundant_pattern_matching.stderr | 68 ++++++++++++++++++---- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/tests/ui/redundant_pattern_matching.rs b/tests/ui/redundant_pattern_matching.rs index 8e8d4b59ba4e..74dd12edfb6c 100644 --- a/tests/ui/redundant_pattern_matching.rs +++ b/tests/ui/redundant_pattern_matching.rs @@ -51,4 +51,30 @@ fn main() { Some(_) => false, None => true, }; + + let _ = match None::<()> { + Some(_) => false, + None => true, + }; + + let _ = if let Ok(_) = Ok::(4) { true } else { false }; + + let _ = does_something(); + let _ = returns_unit(); +} + +fn does_something() -> bool { + if let Ok(_) = Ok::(4) { + true + } else { + false + } +} + +fn returns_unit() { + if let Ok(_) = Ok::(4) { + true + } else { + false + }; } diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr index a904c5ceb9d5..e3ba152d58a9 100644 --- a/tests/ui/redundant_pattern_matching.stderr +++ b/tests/ui/redundant_pattern_matching.stderr @@ -1,5 +1,5 @@ error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:5:12 + --> $DIR/redundant_pattern_matching.rs:6:12 | LL | if let Ok(_) = Ok::(42) {} | -------^^^^^------------------------ help: try this: `Ok::(42).is_ok()` @@ -7,25 +7,25 @@ LL | if let Ok(_) = Ok::(42) {} = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:7:12 + --> $DIR/redundant_pattern_matching.rs:8:12 | LL | if let Err(_) = Err::(42) {} | -------^^^^^^------------------------- help: try this: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:9:12 + --> $DIR/redundant_pattern_matching.rs:10:12 | LL | if let None = None::<()> {} | -------^^^^---------------- help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:11:12 + --> $DIR/redundant_pattern_matching.rs:12:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^-------------- help: try this: `Some(42).is_some()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:25:5 + --> $DIR/redundant_pattern_matching.rs:26:5 | LL | / match Ok::(42) { LL | | Ok(_) => true, @@ -34,7 +34,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:30:5 + --> $DIR/redundant_pattern_matching.rs:31:5 | LL | / match Ok::(42) { LL | | Ok(_) => false, @@ -43,7 +43,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_err()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:35:5 + --> $DIR/redundant_pattern_matching.rs:36:5 | LL | / match Err::(42) { LL | | Ok(_) => false, @@ -52,7 +52,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:40:5 + --> $DIR/redundant_pattern_matching.rs:41:5 | LL | / match Err::(42) { LL | | Ok(_) => true, @@ -61,7 +61,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_ok()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:45:5 + --> $DIR/redundant_pattern_matching.rs:46:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -70,7 +70,7 @@ LL | | }; | |_____^ help: try this: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:50:5 + --> $DIR/redundant_pattern_matching.rs:51:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -78,5 +78,51 @@ LL | | None => true, LL | | }; | |_____^ help: try this: `None::<()>.is_none()` -error: aborting due to 10 previous errors +error: redundant pattern matching, consider using `is_none()` + --> $DIR/redundant_pattern_matching.rs:56:15 + | +LL | let foo = match None::<()> { + | _______________^ +LL | | Some(_) => false, +LL | | None => true, +LL | | }; + | |_____^ help: try this: `None::<()>.is_none()` + +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching.rs:61:20 + | +LL | let _ = if let Ok(_) = Ok::(4) { true } else { false }; + | -------^^^^^--------------------------------------------- help: try this: `Ok::(4).is_ok()` + +error: this let-binding has unit value + --> $DIR/redundant_pattern_matching.rs:64:5 + | +LL | let _ = returns_unit(); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `returns_unit();` + | + = note: `-D clippy::let-unit-value` implied by `-D warnings` + +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching.rs:68:12 + | +LL | if let Ok(_) = Ok::(4) { + | _____- ^^^^^ +LL | | true +LL | | } else { +LL | | false +LL | | } + | |_____- help: try this: `Ok::(4).is_ok()` + +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching.rs:76:12 + | +LL | if let Ok(_) = Ok::(4) { + | _____- ^^^^^ +LL | | true +LL | | } else { +LL | | false +LL | | }; + | |_____- help: try this: `Ok::(4).is_ok()` + +error: aborting due to 15 previous errors From 59893bcab0684abf0483fd7da474e34910d9c507 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Wed, 21 Aug 2019 07:35:04 +0200 Subject: [PATCH 29/30] Fix `temporary_cstring_as_ptr` false negative Fixes #4375. Changes the check to test when `.unwrap().as_ptr()` is called on any `Result` as suggested by @flip1995 (https://github.com/rust-lang/rust-clippy/issues/4375#issuecomment-520724123). --- clippy_lints/src/methods/mod.rs | 12 +++++------- clippy_lints/src/utils/paths.rs | 2 +- tests/ui/cstring.rs | 17 ++++++++++++++++- tests/ui/cstring.stderr | 29 +++++++++++++++++++++++------ 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 21cfeadba2be..43388a891532 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -8,7 +8,6 @@ use std::iter; use if_chain::if_chain; use matches::matches; use rustc::hir; -use rustc::hir::def::{DefKind, Res}; use rustc::hir::intravisit::{self, Visitor}; use rustc::lint::{in_external_macro, LateContext, LateLintPass, Lint, LintArray, LintContext, LintPass}; use rustc::ty::{self, Predicate, Ty}; @@ -1668,13 +1667,12 @@ fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) { } } -fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, new: &hir::Expr, unwrap: &hir::Expr) { +fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, source: &hir::Expr, unwrap: &hir::Expr) { if_chain! { - if let hir::ExprKind::Call(ref fun, ref args) = new.node; - if args.len() == 1; - if let hir::ExprKind::Path(ref path) = fun.node; - if let Res::Def(DefKind::Method, did) = cx.tables.qpath_res(path, fun.hir_id); - if match_def_path(cx, did, &paths::CSTRING_NEW); + let source_type = cx.tables.expr_ty(source); + if let ty::Adt(def, substs) = source_type.sty; + if match_def_path(cx, def.did, &paths::RESULT); + if match_type(cx, substs.type_at(0), &paths::CSTRING); then { span_lint_and_then( cx, diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index be811da02179..5c688a601cd8 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -17,7 +17,7 @@ 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"]; pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"]; -pub const CSTRING_NEW: [&str; 5] = ["std", "ffi", "c_str", "CString", "new"]; +pub const CSTRING: [&str; 4] = ["std", "ffi", "c_str", "CString"]; pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"]; pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"]; pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"]; diff --git a/tests/ui/cstring.rs b/tests/ui/cstring.rs index 0d775d4067a3..6cdd6b4ff6e7 100644 --- a/tests/ui/cstring.rs +++ b/tests/ui/cstring.rs @@ -1,9 +1,24 @@ +#![deny(clippy::temporary_cstring_as_ptr)] + fn main() {} -#[allow(clippy::result_unwrap_used)] fn temporary_cstring() { use std::ffi::CString; CString::new("foo").unwrap().as_ptr(); CString::new("foo").expect("dummy").as_ptr(); } + +mod issue4375 { + use std::ffi::CString; + use std::os::raw::c_char; + + extern "C" { + fn foo(data: *const c_char); + } + + pub fn bar(v: &[u8]) { + let cstr = CString::new(v); + unsafe { foo(cstr.unwrap().as_ptr()) } + } +} diff --git a/tests/ui/cstring.stderr b/tests/ui/cstring.stderr index 83f64ff3b026..21838237413c 100644 --- a/tests/ui/cstring.stderr +++ b/tests/ui/cstring.stderr @@ -1,29 +1,46 @@ error: you are getting the inner pointer of a temporary `CString` - --> $DIR/cstring.rs:7:5 + --> $DIR/cstring.rs:8:5 | LL | CString::new("foo").unwrap().as_ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(clippy::temporary_cstring_as_ptr)]` on by default +note: lint level defined here + --> $DIR/cstring.rs:1:9 + | +LL | #![deny(clippy::temporary_cstring_as_ptr)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: that pointer will be invalid outside this expression help: assign the `CString` to a variable to extend its lifetime - --> $DIR/cstring.rs:7:5 + --> $DIR/cstring.rs:8:5 | LL | CString::new("foo").unwrap().as_ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: you are getting the inner pointer of a temporary `CString` - --> $DIR/cstring.rs:8:5 + --> $DIR/cstring.rs:9:5 | LL | CString::new("foo").expect("dummy").as_ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: that pointer will be invalid outside this expression help: assign the `CString` to a variable to extend its lifetime - --> $DIR/cstring.rs:8:5 + --> $DIR/cstring.rs:9:5 | LL | CString::new("foo").expect("dummy").as_ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: you are getting the inner pointer of a temporary `CString` + --> $DIR/cstring.rs:22:22 + | +LL | unsafe { foo(cstr.unwrap().as_ptr()) } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: that pointer will be invalid outside this expression +help: assign the `CString` to a variable to extend its lifetime + --> $DIR/cstring.rs:22:22 + | +LL | unsafe { foo(cstr.unwrap().as_ptr()) } + | ^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors From 436d429d27ba3ce1a9a5ca3ae4074ac75ab11c2c Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Wed, 21 Aug 2019 07:43:42 +0200 Subject: [PATCH 30/30] Add two more tests, allow 2 other lints. --- tests/ui/redundant_pattern_matching.rs | 10 +++++++++ tests/ui/redundant_pattern_matching.stderr | 26 +++++++++++++--------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/ui/redundant_pattern_matching.rs b/tests/ui/redundant_pattern_matching.rs index 74dd12edfb6c..2bea7d8d9618 100644 --- a/tests/ui/redundant_pattern_matching.rs +++ b/tests/ui/redundant_pattern_matching.rs @@ -1,5 +1,6 @@ #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] +#![allow(clippy::unit_arg, clippy::let_unit_value)] fn main() { if let Ok(_) = Ok::(42) {} @@ -61,8 +62,17 @@ fn main() { let _ = does_something(); let _ = returns_unit(); + + let opt = Some(false); + let x = if let Some(_) = opt { true } else { false }; + takes_bool(x); + let y = if let Some(_) = opt {}; + takes_unit(y); } +fn takes_bool(x: bool) {} +fn takes_unit(x: ()) {} + fn does_something() -> bool { if let Ok(_) = Ok::(4) { true diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr index e3ba152d58a9..df12b7e169a1 100644 --- a/tests/ui/redundant_pattern_matching.stderr +++ b/tests/ui/redundant_pattern_matching.stderr @@ -79,10 +79,10 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:56:15 + --> $DIR/redundant_pattern_matching.rs:56:13 | -LL | let foo = match None::<()> { - | _______________^ +LL | let _ = match None::<()> { + | _____________^ LL | | Some(_) => false, LL | | None => true, LL | | }; @@ -94,16 +94,20 @@ error: redundant pattern matching, consider using `is_ok()` LL | let _ = if let Ok(_) = Ok::(4) { true } else { false }; | -------^^^^^--------------------------------------------- help: try this: `Ok::(4).is_ok()` -error: this let-binding has unit value - --> $DIR/redundant_pattern_matching.rs:64:5 +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching.rs:67:20 | -LL | let _ = returns_unit(); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `returns_unit();` +LL | let x = if let Some(_) = opt { true } else { false }; + | -------^^^^^^^------------------------------ help: try this: `opt.is_some()` + +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching.rs:69:20 | - = note: `-D clippy::let-unit-value` implied by `-D warnings` +LL | let y = if let Some(_) = opt {}; + | -------^^^^^^^--------- help: try this: `opt.is_some()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:68:12 + --> $DIR/redundant_pattern_matching.rs:77:12 | LL | if let Ok(_) = Ok::(4) { | _____- ^^^^^ @@ -114,7 +118,7 @@ LL | | } | |_____- help: try this: `Ok::(4).is_ok()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:76:12 + --> $DIR/redundant_pattern_matching.rs:85:12 | LL | if let Ok(_) = Ok::(4) { | _____- ^^^^^ @@ -124,5 +128,5 @@ LL | | false LL | | }; | |_____- help: try this: `Ok::(4).is_ok()` -error: aborting due to 15 previous errors +error: aborting due to 16 previous errors